changeset 48437:1f38b6c89f8a

Merge
author prr
date Wed, 13 Dec 2017 10:56:50 -0800
parents 4966e9237b88 191ae61bd1e9
children 4f9683bf0923
files src/java.base/share/classes/java/lang/StringDecoderUTF8.java test/java/util/Calendar/Bug8185841.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/TestMemberInheritence.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/diamond/A.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/diamond/B.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/diamond/C.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/diamond/X.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/diamond/Z.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/inheritDist/A.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/inheritDist/B.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/inheritDist/C.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/pkg/BaseClass.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/pkg/BaseInterface.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/pkg/SubClass.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/pkg1/Implementer.java test/langtools/jdk/javadoc/doclet/testMemberInheritence/pkg1/Interface.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestBadOverride.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestMultiInheritence.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverrideMethods.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverridenMethodDocCopy.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverridenPrivateMethods.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverridenPrivateMethodsWithPackageFlag.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg1/BaseClass.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg1/SubClass.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg2/SubClass.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg3/I0.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg3/I1.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg3/I2.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg3/I3.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg3/I4.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg4/Foo.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/Classes.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/Interfaces.java test/langtools/jdk/javadoc/doclet/testOverridenMethods/pkg5/TestEnum.java
diffstat 247 files changed, 13229 insertions(+), 4510 deletions(-) [+]
line wrap: on
line diff
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -37,6 +37,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import org.xml.sax.SAXNotRecognizedException;
@@ -52,21 +53,32 @@
 
     static final String LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldml.dtd";
     static final String SPPL_LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldmlSupplemental.dtd";
+    static final String BCP47_LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldmlBCP47.dtd";
+
 
     private static String CLDR_BASE = "../CLDR/21.0.1/";
     static String LOCAL_LDML_DTD;
     static String LOCAL_SPPL_LDML_DTD;
+    static String LOCAL_BCP47_LDML_DTD;
     private static String SOURCE_FILE_DIR;
     private static String SPPL_SOURCE_FILE;
     private static String NUMBERING_SOURCE_FILE;
     private static String METAZONES_SOURCE_FILE;
     private static String LIKELYSUBTAGS_SOURCE_FILE;
+    private static String TIMEZONE_SOURCE_FILE;
     static String DESTINATION_DIR = "build/gensrc";
 
     static final String LOCALE_NAME_PREFIX = "locale.displayname.";
+    static final String LOCALE_SEPARATOR = LOCALE_NAME_PREFIX + "separator";
+    static final String LOCALE_KEYTYPE = LOCALE_NAME_PREFIX + "keytype";
+    static final String LOCALE_KEY_PREFIX = LOCALE_NAME_PREFIX + "key.";
+    static final String LOCALE_TYPE_PREFIX = LOCALE_NAME_PREFIX + "type.";
+    static final String LOCALE_TYPE_PREFIX_CA = LOCALE_TYPE_PREFIX + "ca.";
     static final String CURRENCY_SYMBOL_PREFIX = "currency.symbol.";
     static final String CURRENCY_NAME_PREFIX = "currency.displayname.";
     static final String CALENDAR_NAME_PREFIX = "calendarname.";
+    static final String CALENDAR_FIRSTDAY_PREFIX = "firstDay.";
+    static final String CALENDAR_MINDAYS_PREFIX = "minDays.";
     static final String TIMEZONE_ID_PREFIX = "timezone.id.";
     static final String ZONE_NAME_PREFIX = "timezone.displayname.";
     static final String METAZONE_ID_PREFIX = "metazone.id.";
@@ -76,6 +88,7 @@
     private static LikelySubtagsParseHandler handlerLikelySubtags;
     static NumberingSystemsParseHandler handlerNumbering;
     static MetaZonesParseHandler handlerMetaZones;
+    static TimeZoneParseHandler handlerTimeZone;
     private static BundleGenerator bundleGenerator;
 
     // java.base module related
@@ -201,11 +214,13 @@
         // Set up path names
         LOCAL_LDML_DTD = CLDR_BASE + "/dtd/ldml.dtd";
         LOCAL_SPPL_LDML_DTD = CLDR_BASE + "/dtd/ldmlSupplemental.dtd";
+        LOCAL_BCP47_LDML_DTD = CLDR_BASE + "/dtd/ldmlBCP47.dtd";
         SOURCE_FILE_DIR = CLDR_BASE + "/main";
         SPPL_SOURCE_FILE = CLDR_BASE + "/supplemental/supplementalData.xml";
         LIKELYSUBTAGS_SOURCE_FILE = CLDR_BASE + "/supplemental/likelySubtags.xml";
         NUMBERING_SOURCE_FILE = CLDR_BASE + "/supplemental/numberingSystems.xml";
         METAZONES_SOURCE_FILE = CLDR_BASE + "/supplemental/metaZones.xml";
+        TIMEZONE_SOURCE_FILE = CLDR_BASE + "/bcp47/timezone.xml";
 
         if (BASE_LOCALES.isEmpty()) {
             setupBaseLocales("en-US");
@@ -215,10 +230,10 @@
 
         // Parse data independent of locales
         parseSupplemental();
+        parseBCP47();
 
         List<Bundle> bundles = readBundleList();
         convertBundles(bundles);
-        convertBundles(addedBundles);
     }
 
     private static void usage() {
@@ -314,34 +329,19 @@
     }
 
     private static final Map<String, Map<String, Object>> cldrBundles = new HashMap<>();
-    // this list will contain additional bundles to be generated for Region dependent Data.
-    private static List<Bundle> addedBundles = new ArrayList<>();
 
     private static Map<String, SortedSet<String>> metaInfo = new HashMap<>();
 
     static {
         // For generating information on supported locales.
-        metaInfo.put("LocaleNames", new TreeSet<>());
-        metaInfo.put("CurrencyNames", new TreeSet<>());
-        metaInfo.put("TimeZoneNames", new TreeSet<>());
-        metaInfo.put("CalendarData", new TreeSet<>());
-        metaInfo.put("FormatData", new TreeSet<>());
         metaInfo.put("AvailableLocales", new TreeSet<>());
     }
 
-
-    private static Set<String> calendarDataFields = Set.of("firstDayOfWeek", "minimalDaysInFirstWeek");
-
     static Map<String, Object> getCLDRBundle(String id) throws Exception {
         Map<String, Object> bundle = cldrBundles.get(id);
         if (bundle != null) {
             return bundle;
         }
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-        factory.setValidating(true);
-        SAXParser parser = factory.newSAXParser();
-        enableFileAccess(parser);
-        LDMLParseHandler handler = new LDMLParseHandler(id);
         File file = new File(SOURCE_FILE_DIR + File.separator + id + ".xml");
         if (!file.exists()) {
             // Skip if the file doesn't exist.
@@ -349,14 +349,15 @@
         }
 
         info("..... main directory .....");
-        info("Reading file " + file);
-        parser.parse(file, handler);
+        LDMLParseHandler handler = new LDMLParseHandler(id);
+        parseLDMLFile(file, handler);
 
         bundle = handler.getData();
         cldrBundles.put(id, bundle);
-        String country = getCountryCode(id);
-        if (country != null) {
-            bundle = handlerSuppl.getData(country);
+
+        if (id.equals("root")) {
+            // Calendar data (firstDayOfWeek & minDaysInFirstWeek)
+            bundle = handlerSuppl.getData("root");
             if (bundle != null) {
                 //merge two maps into one map
                 Map<String, Object> temp = cldrBundles.remove(id);
@@ -379,98 +380,44 @@
         // SupplementalData file also provides the "parent" locales which
         // are othrwise not to be fallen back. Process them here as well.
         //
-        info("..... Parsing supplementalData.xml .....");
-        SAXParserFactory factorySuppl = SAXParserFactory.newInstance();
-        factorySuppl.setValidating(true);
-        SAXParser parserSuppl = factorySuppl.newSAXParser();
-        enableFileAccess(parserSuppl);
         handlerSuppl = new SupplementDataParseHandler();
-        File fileSupply = new File(SPPL_SOURCE_FILE);
-        parserSuppl.parse(fileSupply, handlerSuppl);
+        parseLDMLFile(new File(SPPL_SOURCE_FILE), handlerSuppl);
         Map<String, Object> parentData = handlerSuppl.getData("root");
-        parentData.keySet().forEach(key -> {
+        parentData.keySet().stream()
+                .filter(key -> key.startsWith(PARENT_LOCALE_PREFIX))
+                .forEach(key -> {
                 parentLocalesMap.put(key, new TreeSet(
                     Arrays.asList(((String)parentData.get(key)).split(" "))));
             });
 
         // Parse numberingSystems to get digit zero character information.
-        SAXParserFactory numberingParser = SAXParserFactory.newInstance();
-        numberingParser.setValidating(true);
-        SAXParser parserNumbering = numberingParser.newSAXParser();
-        enableFileAccess(parserNumbering);
         handlerNumbering = new NumberingSystemsParseHandler();
-        File fileNumbering = new File(NUMBERING_SOURCE_FILE);
-        parserNumbering.parse(fileNumbering, handlerNumbering);
+        parseLDMLFile(new File(NUMBERING_SOURCE_FILE), handlerNumbering);
 
         // Parse metaZones to create mappings between Olson tzids and CLDR meta zone names
-        info("..... Parsing metaZones.xml .....");
-        SAXParserFactory metazonesParser = SAXParserFactory.newInstance();
-        metazonesParser.setValidating(true);
-        SAXParser parserMetaZones = metazonesParser.newSAXParser();
-        enableFileAccess(parserMetaZones);
         handlerMetaZones = new MetaZonesParseHandler();
-        File fileMetaZones = new File(METAZONES_SOURCE_FILE);
-        parserMetaZones.parse(fileMetaZones, handlerMetaZones);
+        parseLDMLFile(new File(METAZONES_SOURCE_FILE), handlerMetaZones);
 
         // Parse likelySubtags
-        info("..... Parsing likelySubtags.xml .....");
-        SAXParserFactory likelySubtagsParser = SAXParserFactory.newInstance();
-        likelySubtagsParser.setValidating(true);
-        SAXParser parserLikelySubtags = likelySubtagsParser.newSAXParser();
-        enableFileAccess(parserLikelySubtags);
         handlerLikelySubtags = new LikelySubtagsParseHandler();
-        File fileLikelySubtags = new File(LIKELYSUBTAGS_SOURCE_FILE);
-        parserLikelySubtags.parse(fileLikelySubtags, handlerLikelySubtags);
+        parseLDMLFile(new File(LIKELYSUBTAGS_SOURCE_FILE), handlerLikelySubtags);
     }
 
-    /**
-     * This method will check if a new region dependent Bundle needs to be
-     * generated for this Locale id and targetMap. New Bundle will be generated
-     * when Locale id has non empty script and country code and targetMap
-     * contains region dependent data. This method will also remove region
-     * dependent data from this targetMap after candidate locales check. E.g. It
-     * will call genRegionDependentBundle() in case of az_Latn_AZ locale and
-     * remove region dependent data from this targetMap so that az_Latn_AZ
-     * bundle will not be created. For az_Cyrl_AZ, new Bundle will be generated
-     * but region dependent data will not be removed from targetMap as its candidate
-     * locales are [az_Cyrl_AZ, az_Cyrl, root], which does not include az_AZ for
-     * fallback.
-     *
-     */
+    // Parsers for data in "bcp47" directory
+    //
+    private static void parseBCP47() throws Exception {
+        // Parse timezone
+        handlerTimeZone = new TimeZoneParseHandler();
+        parseLDMLFile(new File(TIMEZONE_SOURCE_FILE), handlerTimeZone);
+    }
 
-    private static void checkRegionDependentBundle(Map<String, Object> targetMap, String id) {
-        if ((CLDRConverter.getScript(id) != "")
-                && (CLDRConverter.getCountryCode(id) != "")) {
-            Map<String, Object> regionDepDataMap = targetMap
-                    .keySet()
-                    .stream()
-                    .filter(calendarDataFields::contains)
-                    .collect(Collectors.toMap(k -> k, targetMap::get));
-            if (!regionDepDataMap.isEmpty()) {
-                Locale cldrLoc = new Locale(CLDRConverter.getLanguageCode(id),
-                                            CLDRConverter.getCountryCode(id));
-                genRegionDependentBundle(regionDepDataMap, cldrLoc);
-                if (checkCandidateLocales(id, cldrLoc)) {
-                    // Remove matchedKeys from this targetMap only if checkCandidateLocales() returns true.
-                    regionDepDataMap.keySet().forEach(targetMap::remove);
-                }
-            }
-        }
-    }
-    /**
-     * This method will generate a new Bundle for region dependent data,
-     * minimalDaysInFirstWeek and firstDayOfWeek. Newly generated Bundle will be added
-     * to addedBundles list.
-     */
-    private static void genRegionDependentBundle(Map<String, Object> targetMap, Locale cldrLoc) {
-        String localeId = cldrLoc.toString();
-        StringBuilder sb = getCandLocales(cldrLoc);
-        if (sb.indexOf(localeId) == -1) {
-            sb.append(localeId);
-        }
-        Bundle bundle = new Bundle(localeId, sb.toString(), null, null);
-        cldrBundles.put(localeId, targetMap);
-        addedBundles.add(bundle);
+    private static void parseLDMLFile(File srcfile, AbstractLDMLHandler handler) throws Exception {
+        info("..... Parsing " + srcfile.getName() + " .....");
+        SAXParserFactory pf = SAXParserFactory.newInstance();
+        pf.setValidating(true);
+        SAXParser parser = pf.newSAXParser();
+        enableFileAccess(parser);
+        parser.parse(srcfile, handler);
     }
 
     private static StringBuilder getCandLocales(Locale cldrLoc) {
@@ -491,16 +438,6 @@
         return candList;
     }
 
-    /**
-     * This method will return true, if for a given locale, its language and
-     * country specific locale will exist in runtime lookup path. E.g. it will
-     * return true for bs_Latn_BA.
-     */
-    private static boolean checkCandidateLocales(String id, Locale cldrLoc) {
-        return(getCandidateLocales(Locale.forLanguageTag(id.replaceAll("_", "-")))
-                .contains(cldrLoc));
-    }
-
     private static void convertBundles(List<Bundle> bundles) throws Exception {
         // parent locales map. The mappings are put in base metaInfo file
         // for now.
@@ -514,8 +451,6 @@
 
             Map<String, Object> targetMap = bundle.getTargetMap();
 
-            // check if new region DependentBundle needs to be generated for this Locale.
-            checkRegionDependentBundle(targetMap, bundle.getID());
             EnumSet<Bundle.Type> bundleTypes = bundle.getBundleTypes();
 
             if (bundle.isRoot()) {
@@ -528,40 +463,30 @@
             if (bundleTypes.contains(Bundle.Type.LOCALENAMES)) {
                 Map<String, Object> localeNamesMap = extractLocaleNames(targetMap, bundle.getID());
                 if (!localeNamesMap.isEmpty() || bundle.isRoot()) {
-                    metaInfo.get("LocaleNames").add(toLanguageTag(bundle.getID()));
-                    addLikelySubtags(metaInfo, "LocaleNames", bundle.getID());
                     bundleGenerator.generateBundle("util", "LocaleNames", bundle.getJavaID(), true, localeNamesMap, BundleType.OPEN);
                 }
             }
             if (bundleTypes.contains(Bundle.Type.CURRENCYNAMES)) {
                 Map<String, Object> currencyNamesMap = extractCurrencyNames(targetMap, bundle.getID(), bundle.getCurrencies());
                 if (!currencyNamesMap.isEmpty() || bundle.isRoot()) {
-                    metaInfo.get("CurrencyNames").add(toLanguageTag(bundle.getID()));
-                    addLikelySubtags(metaInfo, "CurrencyNames", bundle.getID());
                     bundleGenerator.generateBundle("util", "CurrencyNames", bundle.getJavaID(), true, currencyNamesMap, BundleType.OPEN);
                 }
             }
             if (bundleTypes.contains(Bundle.Type.TIMEZONENAMES)) {
                 Map<String, Object> zoneNamesMap = extractZoneNames(targetMap, bundle.getID());
                 if (!zoneNamesMap.isEmpty() || bundle.isRoot()) {
-                    metaInfo.get("TimeZoneNames").add(toLanguageTag(bundle.getID()));
-                    addLikelySubtags(metaInfo, "TimeZoneNames", bundle.getID());
                     bundleGenerator.generateBundle("util", "TimeZoneNames", bundle.getJavaID(), true, zoneNamesMap, BundleType.TIMEZONE);
                 }
             }
             if (bundleTypes.contains(Bundle.Type.CALENDARDATA)) {
                 Map<String, Object> calendarDataMap = extractCalendarData(targetMap, bundle.getID());
                 if (!calendarDataMap.isEmpty() || bundle.isRoot()) {
-                    metaInfo.get("CalendarData").add(toLanguageTag(bundle.getID()));
-                    addLikelySubtags(metaInfo, "CalendarData", bundle.getID());
                     bundleGenerator.generateBundle("util", "CalendarData", bundle.getJavaID(), true, calendarDataMap, BundleType.PLAIN);
                 }
             }
             if (bundleTypes.contains(Bundle.Type.FORMATDATA)) {
                 Map<String, Object> formatDataMap = extractFormatData(targetMap, bundle.getID());
                 if (!formatDataMap.isEmpty() || bundle.isRoot()) {
-                    metaInfo.get("FormatData").add(toLanguageTag(bundle.getID()));
-                    addLikelySubtags(metaInfo, "FormatData", bundle.getID());
                     bundleGenerator.generateBundle("text", "FormatData", bundle.getJavaID(), true, formatDataMap, BundleType.PLAIN);
                 }
             }
@@ -570,43 +495,9 @@
             metaInfo.get("AvailableLocales").add(toLanguageTag(bundle.getID()));
             addLikelySubtags(metaInfo, "AvailableLocales", bundle.getID());
         }
-        addCldrImplicitLocales(metaInfo);
         bundleGenerator.generateMetaInfo(metaInfo);
     }
 
-    /**
-     * These are the Locales that are implicitly supported by CLDR.
-     * Adding them explicitly as likelySubtags here, will ensure that
-     * COMPAT locales do not precede them during ResourceBundle search path.
-     */
-    private static void addCldrImplicitLocales(Map<String, SortedSet<String>> metaInfo) {
-        metaInfo.get("LocaleNames").add("zh-Hans-CN");
-        metaInfo.get("LocaleNames").add("zh-Hans-SG");
-        metaInfo.get("LocaleNames").add("zh-Hant-HK");
-        metaInfo.get("LocaleNames").add("zh-Hant-MO");
-        metaInfo.get("LocaleNames").add("zh-Hant-TW");
-        metaInfo.get("CurrencyNames").add("zh-Hans-CN");
-        metaInfo.get("CurrencyNames").add("zh-Hans-SG");
-        metaInfo.get("CurrencyNames").add("zh-Hant-HK");
-        metaInfo.get("CurrencyNames").add("zh-Hant-MO");
-        metaInfo.get("CurrencyNames").add("zh-Hant-TW");
-        metaInfo.get("TimeZoneNames").add("zh-Hans-CN");
-        metaInfo.get("TimeZoneNames").add("zh-Hans-SG");
-        metaInfo.get("TimeZoneNames").add("zh-Hant-HK");
-        metaInfo.get("TimeZoneNames").add("zh-Hant-MO");
-        metaInfo.get("TimeZoneNames").add("zh-Hant-TW");
-        metaInfo.get("TimeZoneNames").add("zh-HK");
-        metaInfo.get("CalendarData").add("zh-Hans-CN");
-        metaInfo.get("CalendarData").add("zh-Hans-SG");
-        metaInfo.get("CalendarData").add("zh-Hant-HK");
-        metaInfo.get("CalendarData").add("zh-Hant-MO");
-        metaInfo.get("CalendarData").add("zh-Hant-TW");
-        metaInfo.get("FormatData").add("zh-Hans-CN");
-        metaInfo.get("FormatData").add("zh-Hans-SG");
-        metaInfo.get("FormatData").add("zh-Hant-HK");
-        metaInfo.get("FormatData").add("zh-Hant-MO");
-        metaInfo.get("FormatData").add("zh-Hant-TW");
-    }
     static final Map<String, String> aliases = new HashMap<>();
 
     /**
@@ -656,14 +547,6 @@
         return Locale.forLanguageTag(id.replaceAll("_", "-")).getCountry();
     }
 
-    /*
-     * Returns the script portion of the given id.
-     * If id is "root", "" is returned.
-     */
-    static String getScript(String id) {
-        return "root".equals(id) ? "" : Locale.forLanguageTag(id.replaceAll("_", "-")).getScript();
-    }
-
     private static class KeyComparator implements Comparator<String> {
         static KeyComparator INSTANCE = new KeyComparator();
 
@@ -695,9 +578,25 @@
         Map<String, Object> localeNames = new TreeMap<>(KeyComparator.INSTANCE);
         for (String key : map.keySet()) {
             if (key.startsWith(LOCALE_NAME_PREFIX)) {
-                localeNames.put(key.substring(LOCALE_NAME_PREFIX.length()), map.get(key));
+                switch (key) {
+                    case LOCALE_SEPARATOR:
+                        localeNames.put("ListCompositionPattern", map.get(key));
+                        break;
+                    case LOCALE_KEYTYPE:
+                        localeNames.put("ListKeyTypePattern", map.get(key));
+                        break;
+                    default:
+                        localeNames.put(key.substring(LOCALE_NAME_PREFIX.length()), map.get(key));
+                        break;
+                }
             }
         }
+
+        if (id.equals("root")) {
+            // Add display name pattern, which is not in CLDR
+            localeNames.put("DisplayNamePattern", "{0,choice,0#|1#{1}|2#{1} ({2})}");
+        }
+
         return localeNames;
     }
 
@@ -778,10 +677,30 @@
         return names;
     }
 
+    /**
+     * Extracts the language independent calendar data. Each of the two keys,
+     * "firstDayOfWeek" and "minimalDaysInFirstWeek" has a string value consists of
+     * one or multiple occurrences of:
+     *  i: rg1 rg2 ... rgn;
+     * where "i" is the data for the following regions (delimited by a space) after
+     * ":", and ends with a ";".
+     */
     private static Map<String, Object> extractCalendarData(Map<String, Object> map, String id) {
         Map<String, Object> calendarData = new LinkedHashMap<>();
-        copyIfPresent(map, "firstDayOfWeek", calendarData);
-        copyIfPresent(map, "minimalDaysInFirstWeek", calendarData);
+        if (id.equals("root")) {
+            calendarData.put("firstDayOfWeek",
+                IntStream.range(1, 8)
+                    .mapToObj(String::valueOf)
+                    .filter(d -> map.keySet().contains(CALENDAR_FIRSTDAY_PREFIX + d))
+                    .map(d -> d + ": " + map.get(CALENDAR_FIRSTDAY_PREFIX + d))
+                    .collect(Collectors.joining(";")));
+            calendarData.put("minimalDaysInFirstWeek",
+                IntStream.range(0, 7)
+                    .mapToObj(String::valueOf)
+                    .filter(d -> map.keySet().contains(CALENDAR_MINDAYS_PREFIX + d))
+                    .map(d -> d + ": " + map.get(CALENDAR_MINDAYS_PREFIX + d))
+                    .collect(Collectors.joining(";")));
+        }
         return calendarData;
     }
 
@@ -844,17 +763,19 @@
 
         for (String key : map.keySet()) {
         // Copy available calendar names
-            if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) {
-                String type = key.substring(CLDRConverter.CALENDAR_NAME_PREFIX.length());
+            if (key.startsWith(CLDRConverter.LOCALE_TYPE_PREFIX_CA)) {
+                String type = key.substring(CLDRConverter.LOCALE_TYPE_PREFIX_CA.length());
                 for (CalendarType calendarType : CalendarType.values()) {
                     if (calendarType == CalendarType.GENERIC) {
                         continue;
                     }
                     if (type.equals(calendarType.lname())) {
                         Object value = map.get(key);
-                        formatData.put(key, value);
-                        String ukey = CLDRConverter.CALENDAR_NAME_PREFIX + calendarType.uname();
-                        if (!key.equals(ukey)) {
+                        String dataKey = key.replace(LOCALE_TYPE_PREFIX_CA,
+                                CALENDAR_NAME_PREFIX);
+                        formatData.put(dataKey, value);
+                        String ukey = CALENDAR_NAME_PREFIX + calendarType.uname();
+                        if (!dataKey.equals(ukey)) {
                             formatData.put(ukey, value);
                         }
                     }
@@ -874,6 +795,18 @@
             copyIfPresent(map, "NumberElements", formatData);
         }
         copyIfPresent(map, "NumberPatterns", formatData);
+
+        // put extra number elements for available scripts into formatData, if it is "root"
+        if (id.equals("root")) {
+            handlerNumbering.keySet().stream()
+                .filter(k -> !numberingScripts.contains(k))
+                .forEach(k -> {
+                    String[] ne = (String[])map.get("latn.NumberElements");
+                    String[] neNew = Arrays.copyOf(ne, ne.length);
+                    neNew[4] = handlerNumbering.get(k).substring(0, 1);
+                    formatData.put(k + ".NumberElements", neNew);
+                });
+        }
         return formatData;
     }
 
--- a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -76,12 +76,16 @@
             // ignore this element - it has language and territory elements that aren't locale data
             pushIgnoredContainer(qName);
             break;
-        case "type":
-            if ("calendar".equals(attributes.getValue("key"))) {
-                pushStringEntry(qName, attributes, CLDRConverter.CALENDAR_NAME_PREFIX + attributes.getValue("type"));
-            } else {
-                pushIgnoredContainer(qName);
-            }
+
+        // for LocaleNames
+        // copy string
+        case "localeSeparator":
+            pushStringEntry(qName, attributes,
+                CLDRConverter.LOCALE_SEPARATOR);
+            break;
+        case "localeKeyTypePattern":
+            pushStringEntry(qName, attributes,
+                CLDRConverter.LOCALE_KEYTYPE);
             break;
 
         case "language":
@@ -96,6 +100,24 @@
                 attributes.getValue("type"));
             break;
 
+        case "key":
+            // for LocaleNames
+            // copy string
+            pushStringEntry(qName, attributes,
+                CLDRConverter.LOCALE_KEY_PREFIX +
+                convertOldKeyName(attributes.getValue("type")));
+            break;
+
+        case "type":
+            // for LocaleNames/CalendarNames
+            // copy string
+            pushStringEntry(qName, attributes,
+                CLDRConverter.LOCALE_TYPE_PREFIX +
+                convertOldKeyName(attributes.getValue("key")) + "." +
+                attributes.getValue("type"));
+
+            break;
+
         //
         // Currency information
         //
@@ -515,26 +537,10 @@
                 currentNumberingSystem = script + ".";
                 String digits = CLDRConverter.handlerNumbering.get(script);
                 if (digits == null) {
-                    throw new InternalError("null digits for " + script);
-                }
-                if (Character.isSurrogate(digits.charAt(0))) {
-                    // DecimalFormatSymbols doesn't support supplementary characters as digit zero.
                     pushIgnoredContainer(qName);
                     break;
                 }
-                // in case digits are in the reversed order, reverse back the order.
-                if (digits.charAt(0) > digits.charAt(digits.length() - 1)) {
-                    StringBuilder sb = new StringBuilder(digits);
-                    digits = sb.reverse().toString();
-                }
-                // Check if the order is sequential.
-                char c0 = digits.charAt(0);
-                for (int i = 1; i < digits.length(); i++) {
-                    if (digits.charAt(i) != c0 + i) {
-                        pushIgnoredContainer(qName);
-                        break symbols;
-                    }
-                }
+
                 @SuppressWarnings("unchecked")
                 List<String> numberingScripts = (List<String>) get("numberingScripts");
                 if (numberingScripts == null) {
@@ -924,17 +930,35 @@
                 }
             }
         } else if (currentContainer instanceof Entry) {
-                Entry<?> entry = (Entry<?>) currentContainer;
-                Object value = entry.getValue();
-                if (value != null) {
-                    String key = entry.getKey();
-                    // Tweak for MonthNames for the root locale, Needed for
-                    // SimpleDateFormat.format()/parse() roundtrip.
-                    if (id.equals("root") && key.startsWith("MonthNames")) {
-                        value = new DateFormatSymbols(Locale.US).getShortMonths();
-                    }
-                    put(entry.getKey(), value);
+            Entry<?> entry = (Entry<?>) currentContainer;
+            Object value = entry.getValue();
+            if (value != null) {
+                String key = entry.getKey();
+                // Tweak for MonthNames for the root locale, Needed for
+                // SimpleDateFormat.format()/parse() roundtrip.
+                if (id.equals("root") && key.startsWith("MonthNames")) {
+                    value = new DateFormatSymbols(Locale.US).getShortMonths();
                 }
+                put(entry.getKey(), value);
             }
         }
     }
+
+    public String convertOldKeyName(String key) {
+        // Explicitly obtained from "alias" attribute in each "key" element.
+        switch (key) {
+            case "calendar":
+                return "ca";
+            case "currency":
+                return "cu";
+            case "collation":
+                return "co";
+            case "numbers":
+                return "nu";
+            case "timezone":
+                return "tz";
+            default:
+                return key;
+        }
+    }
+}
--- a/make/jdk/src/classes/build/tools/cldrconverter/NumberingSystemsParseHandler.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/NumberingSystemsParseHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,9 +54,32 @@
     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
         switch (qName) {
         case "numberingSystem":
-            if ("numeric".equals(attributes.getValue("type"))) {
-                // eg, <numberingSystem id="latn" type="numeric" digits="0123456789"/>
-                put(attributes.getValue("id"), attributes.getValue("digits"));
+            numberingSystem: {
+                if ("numeric".equals(attributes.getValue("type"))) {
+                    // eg, <numberingSystem id="latn" type="numeric" digits="0123456789"/>
+                    String script = attributes.getValue("id");
+                    String digits = attributes.getValue("digits");
+
+                    if (Character.isSurrogate(digits.charAt(0))) {
+                        // DecimalFormatSymbols doesn't support supplementary characters as digit zero.
+                        break numberingSystem;
+                    }
+                    // in case digits are in the reversed order, reverse back the order.
+                    if (digits.charAt(0) > digits.charAt(digits.length() - 1)) {
+                        StringBuilder sb = new StringBuilder(digits);
+                        digits = sb.reverse().toString();
+                    }
+                    // Check if the order is sequential.
+                    char c0 = digits.charAt(0);
+                    for (int i = 1; i < digits.length(); i++) {
+                        if (digits.charAt(i) != c0 + i) {
+                            break numberingSystem;
+                        }
+                    }
+
+                    // script/digits are acceptable.
+                    put(script, digits);
+                }
             }
             pushIgnoredContainer(qName);
             break;
--- a/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -256,20 +256,21 @@
         CLDRConverter.info("Generating file " + file);
 
         try (PrintWriter out = new PrintWriter(file, "us-ascii")) {
-            out.println(CopyrightHeaders.getOpenJDKCopyright());
+            out.printf(CopyrightHeaders.getOpenJDKCopyright());
 
-            out.println((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" :
+            out.printf((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" :
                                   "package sun.util.resources.cldr.provider;\n\n")
                       + "import java.util.HashMap;\n"
                       + "import java.util.Locale;\n"
                       + "import java.util.Map;\n"
-                      + "import sun.util.locale.provider.LocaleProviderAdapter;\n"
-                      + "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
+                      + "import sun.util.locale.provider.LocaleDataMetaInfo;\n"
+                      + "import sun.util.locale.provider.LocaleProviderAdapter;\n\n");
             out.printf("public class %s implements LocaleDataMetaInfo {\n", className);
-            out.println("    private static final Map<String, String> resourceNameToLocales = new HashMap<>();\n" +
-                        (CLDRConverter.isBaseModule ?
-                        "    private static final Map<Locale, String[]> parentLocalesMap = new HashMap<>();\n\n" : "\n") +
-                        "    static {\n");
+            out.printf("    private static final Map<String, String> resourceNameToLocales = new HashMap<>();\n" +
+                       (CLDRConverter.isBaseModule ?
+                       "    private static final Map<Locale, String[]> parentLocalesMap = new HashMap<>();\n\n" :
+                       "\n") +
+                       "    static {\n");
 
             for (String key : metaInfo.keySet()) {
                 if (key.startsWith(CLDRConverter.PARENT_LOCALE_PREFIX)) {
@@ -296,30 +297,50 @@
                     }
                     out.printf("\n             });\n");
                 } else {
-                    out.printf("        resourceNameToLocales.put(\"%s\",\n", key);
-                    out.printf("              \"%s\");\n",
-                    toLocaleList(key.equals("FormatData") ? metaInfo.get("AvailableLocales") :
-                                            metaInfo.get(key), false));
+                    if ("AvailableLocales".equals(key)) {
+                        out.printf("        resourceNameToLocales.put(\"%s\",\n", key);
+                        out.printf("              \"%s\");\n", toLocaleList(metaInfo.get(key), false));
+                    }
                 }
             }
-            out.println("    }\n\n");
 
-            out.println("    @Override\n" +
+            out.printf("    }\n\n");
+
+            // end of static initializer block.
+
+            // Short TZ names for delayed initialization
+            if (CLDRConverter.isBaseModule) {
+                out.printf("    private static class TZShortIDMapHolder {\n");
+                out.printf("        static final Map<String, String> tzShortIDMap = new HashMap<>();\n");
+                out.printf("        static {\n");
+                CLDRConverter.handlerTimeZone.getData().entrySet().stream()
+                    .forEach(e -> {
+                        out.printf("            tzShortIDMap.put(\"%s\", \"%s\");\n", e.getKey(),
+                                ((String)e.getValue()));
+                    });
+                out.printf("        }\n    }\n\n");
+            }
+
+            out.printf("    @Override\n" +
                         "    public LocaleProviderAdapter.Type getType() {\n" +
                         "        return LocaleProviderAdapter.Type.CLDR;\n" +
                         "    }\n\n");
 
-            out.println("    @Override\n" +
+            out.printf("    @Override\n" +
                         "    public String availableLanguageTags(String category) {\n" +
                         "        return resourceNameToLocales.getOrDefault(category, \"\");\n" +
                         "    }\n\n");
 
             if (CLDRConverter.isBaseModule) {
+                out.printf("    @Override\n" +
+                           "    public Map<String, String> tzShortIDs() {\n" +
+                           "        return TZShortIDMapHolder.tzShortIDMap;\n" +
+                           "    }\n\n");
                 out.printf("    public Map<Locale, String[]> parentLocales() {\n" +
                            "        return parentLocalesMap;\n" +
                            "    }\n}");
             } else {
-                out.println("}");
+                out.printf("}");
             }
         }
     }
--- a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,53 +84,18 @@
             values.put(CLDRConverter.PARENT_LOCALE_PREFIX+key,
                 parentLocalesMap.get(key));
             });
-        } else {
-            String countryData = getWeekData(id, JAVA_FIRSTDAY, firstDayMap);
-        if (countryData != null) {
-            values.put(JAVA_FIRSTDAY, countryData);
-        }
-            String minDaysData = getWeekData(id, JAVA_MINDAY, minDaysMap);
-        if (minDaysData != null) {
-            values.put(JAVA_MINDAY, minDaysData);
-        }
+            firstDayMap.keySet().forEach(key -> {
+            values.put(CLDRConverter.CALENDAR_FIRSTDAY_PREFIX+firstDayMap.get(key),
+                key);
+            });
+            minDaysMap.keySet().forEach(key -> {
+            values.put(CLDRConverter.CALENDAR_MINDAYS_PREFIX+minDaysMap.get(key),
+                key);
+            });
         }
         return values.isEmpty() ? null : values;
     }
 
-    /**
-     * It returns either firstDay or minDays in the JRE format for the country.
-     *
-     * @param country       territory code of the requested data
-     * @param jreDataName   JAVA_FIRSTDAY or JAVA_MINDAY
-     * @param dataMap       firstDayMap or minDaysMap
-     * @return the value for the given jreDataName, or null if requested value
-     *         (firstDay/minDays) is not available although that is highly unlikely
-     *         because of the default value for the world (001).
-     */
-    String getWeekData(String country, final String jreDataName, final Map<String, Object> dataMap) {
-        String countryValue = null;
-        String defaultWorldValue = null;
-        for (String key : dataMap.keySet()) {
-            if (key.contains(country)) {
-                if (jreDataName.equals(JAVA_FIRSTDAY)) {
-                    countryValue = DAY_OF_WEEK_MAP.get((String) dataMap.get(key));
-                } else if (jreDataName.equals(JAVA_MINDAY)) {
-                    countryValue = (String) dataMap.get(key);
-                }
-                if (countryValue != null) {
-                    return countryValue;
-                }
-            } else if (key.contains(WORLD)) {
-                if (jreDataName.equals(JAVA_FIRSTDAY)) {
-                    defaultWorldValue = DAY_OF_WEEK_MAP.get((String) dataMap.get(key));
-                } else if (jreDataName.equals(JAVA_MINDAY)) {
-                    defaultWorldValue = (String) dataMap.get(key);
-                }
-            }
-        }
-        return defaultWorldValue;
-    }
-
     @Override
     public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException {
         // avoid HTTP traffic to unicode.org
@@ -152,7 +117,33 @@
         switch (qName) {
         case "firstDay":
             if (!isIgnored(attributes)) {
-                firstDayMap.put(attributes.getValue("territories"), attributes.getValue("day"));
+                String fd;
+
+                switch (attributes.getValue("day")) {
+                    case "sun":
+                        fd = "1";
+                        break;
+                    default:
+                    case "mon":
+                        fd = "2";
+                        break;
+                    case "tue":
+                        fd = "3";
+                        break;
+                    case "wed":
+                        fd = "4";
+                        break;
+                    case "thu":
+                        fd = "5";
+                        break;
+                    case "fri":
+                        fd = "6";
+                        break;
+                    case "sat":
+                        fd = "7";
+                        break;
+                }
+                firstDayMap.put(attributes.getValue("territories"), fd);
             }
             break;
         case "minDays":
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/jdk/src/classes/build/tools/cldrconverter/TimeZoneParseHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.cldrconverter;
+
+import java.io.File;
+import java.io.IOException;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Handles parsing of timezone.xml and produces a map from short timezone IDs to
+ * tz database IDs.
+ */
+
+class TimeZoneParseHandler extends AbstractLDMLHandler<Object> {
+
+    @Override
+    public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException {
+        // avoid HTTP traffic to unicode.org
+        if (systemID.startsWith(CLDRConverter.BCP47_LDML_DTD_SYSTEM_ID)) {
+            return new InputSource((new File(CLDRConverter.LOCAL_BCP47_LDML_DTD)).toURI().toString());
+        }
+        return null;
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        switch (qName) {
+        case "type":
+            if (!isIgnored(attributes) && !attributes.getValue("deprecated").equals("true")) {
+                put(attributes.getValue("name"), attributes.getValue("alias"));
+            }
+            break;
+        default:
+            // treat anything else as a container
+            pushContainer(qName, attributes);
+            break;
+        }
+    }
+}
--- a/make/nashorn/build.xml	Wed Dec 13 14:41:27 2017 +0000
+++ b/make/nashorn/build.xml	Wed Dec 13 10:56:50 2017 -0800
@@ -265,7 +265,7 @@
   </target>
 
   <!-- generate javadoc for Nashorn classes -->
-  <target name="javadoc" depends="jar">
+  <target name="javadoc" depends="jar" unless="test.class">
     <javadoc destdir="${dist.javadoc.dir}" use="yes"
         windowtitle="${nashorn.product.name} ${nashorn.version}"
         additionalparam="-quiet" failonerror="true" useexternalfile="true"> 
--- a/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package java.io;
 
+import java.nio.charset.Charset;
 import java.util.Arrays;
 
 /**
@@ -223,14 +224,27 @@
 
     /**
      * Converts the buffer's contents into a string by decoding the bytes using
-     * the named {@link java.nio.charset.Charset charset}. The length of the new
-     * {@code String} is a function of the charset, and hence may not be equal
-     * to the length of the byte array.
+     * the named {@link java.nio.charset.Charset charset}.
      *
-     * <p> This method always replaces malformed-input and unmappable-character
-     * sequences with this charset's default replacement string. The {@link
-     * java.nio.charset.CharsetDecoder} class should be used when more control
-     * over the decoding process is required.
+     * <p> This method is equivalent to {@code #toString(charset)} that takes a
+     * {@link java.nio.charset.Charset charset}.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <pre> {@code
+     *      ByteArrayOutputStream b = ...
+     *      b.toString("UTF-8")
+     *      }
+     * </pre>
+     *
+     * behaves in exactly the same way as the expression
+     *
+     * <pre> {@code
+     *      ByteArrayOutputStream b = ...
+     *      b.toString(StandardCharsets.UTF_8)
+     *      }
+     * </pre>
+     *
      *
      * @param      charsetName  the name of a supported
      *             {@link java.nio.charset.Charset charset}
@@ -246,6 +260,26 @@
     }
 
     /**
+     * Converts the buffer's contents into a string by decoding the bytes using
+     * the specified {@link java.nio.charset.Charset charset}. The length of the new
+     * {@code String} is a function of the charset, and hence may not be equal
+     * to the length of the byte array.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with the charset's default replacement string. The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param      charset  the {@linkplain java.nio.charset.Charset charset}
+     *             to be used to decode the {@code bytes}
+     * @return     String decoded from the buffer's contents.
+     * @since      10
+     */
+    public synchronized String toString(Charset charset) {
+        return new String(buf, 0, count, charset);
+    }
+
+    /**
      * Creates a newly allocated string. Its size is the current size of
      * the output stream and the valid contents of the buffer have been
      * copied into it. Each character <i>c</i> in the resulting string is
@@ -257,9 +291,10 @@
      *
      * @deprecated This method does not properly convert bytes into characters.
      * As of JDK&nbsp;1.1, the preferred way to do this is via the
-     * {@code toString(String enc)} method, which takes an encoding-name
-     * argument, or the {@code toString()} method, which uses the
-     * platform's default character encoding.
+     * {@link #toString(String charsetName)} or {@link #toString(Charset charset)}
+     * method, which takes an encoding-name or charset argument,
+     * or the {@code toString()} method, which uses the platform's default
+     * character encoding.
      *
      * @param      hibyte    the high byte of each resulting Unicode character.
      * @return     the current contents of the output stream, as a string.
--- a/src/java.base/share/classes/java/io/PrintStream.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/io/PrintStream.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,10 +45,16 @@
  * ({@code '\n'}) is written.
  *
  * <p> All characters printed by a {@code PrintStream} are converted into
- * bytes using the platform's default character encoding.
+ * bytes using the given encoding or charset, or platform's default character
+ * encoding if not specified.
  * The {@link PrintWriter} class should be used in situations that require
  *  writing characters rather than bytes.
  *
+ * <p> This class always replaces malformed and unmappable character sequences with
+ * the charset's default replacement string.
+ * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
+ * control over the encoding process is required.
+ *
  * @author     Frank Yellin
  * @author     Mark Reinhold
  * @since      1.0
@@ -105,22 +111,13 @@
         this.textOut = new BufferedWriter(charOut);
     }
 
-    private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
-        super(out);
-        this.autoFlush = autoFlush;
-        this.charOut = new OutputStreamWriter(this, charset);
-        this.textOut = new BufferedWriter(charOut);
-    }
-
     /* Variant of the private constructor so that the given charset name
      * can be verified before evaluating the OutputStream argument. Used
      * by constructors creating a FileOutputStream that also take a
      * charset name.
      */
-    private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
-        throws UnsupportedEncodingException
-    {
-        this(autoFlush, out, charset);
+    private PrintStream(boolean autoFlush, Charset charset, OutputStream out) {
+        this(out, autoFlush, charset);
     }
 
     /**
@@ -172,9 +169,30 @@
     public PrintStream(OutputStream out, boolean autoFlush, String encoding)
         throws UnsupportedEncodingException
     {
-        this(autoFlush,
-             requireNonNull(out, "Null output stream"),
-             toCharset(encoding));
+        this(requireNonNull(out, "Null output stream"), autoFlush, toCharset(encoding));
+    }
+
+    /**
+     * Creates a new print stream, with the specified OutputStream, automatic line
+     * flushing and charset.  This convenience constructor creates the necessary
+     * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
+     * which will encode characters using the provided charset.
+     *
+     * @param  out        The output stream to which values and objects will be
+     *                    printed
+     * @param  autoFlush  A boolean; if true, the output buffer will be flushed
+     *                    whenever a byte array is written, one of the
+     *                    {@code println} methods is invoked, or a newline
+     *                    character or byte ({@code '\n'}) is written
+     * @param  charset    A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @since  10
+     */
+    public PrintStream(OutputStream out, boolean autoFlush, Charset charset) {
+        super(out);
+        this.autoFlush = autoFlush;
+        this.charOut = new OutputStreamWriter(this, charset);
+        this.textOut = new BufferedWriter(charOut);
     }
 
     /**
@@ -250,6 +268,36 @@
 
     /**
      * Creates a new print stream, without automatic line flushing, with the
+     * specified file name and charset.  This convenience constructor creates
+     * the necessary intermediate {@link java.io.OutputStreamWriter
+     * OutputStreamWriter}, which will encode characters using the provided
+     * charset.
+     *
+     * @param  fileName
+     *         The name of the file to use as the destination of this print
+     *         stream.  If the file exists, then it will be truncated to
+     *         zero size; otherwise, a new file will be created.  The output
+     *         will be written to the file and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs while opening or creating the file
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and {@link
+     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
+     *          access to the file
+     *
+     * @since  10
+     */
+    public PrintStream(String fileName, Charset charset) throws IOException {
+        this(false, requireNonNull(charset, "charset"), new FileOutputStream(fileName));
+    }
+
+    /**
+     * Creates a new print stream, without automatic line flushing, with the
      * specified file.  This convenience constructor creates the necessary
      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
      * which will encode characters using the {@linkplain
@@ -319,6 +367,37 @@
         this(false, toCharset(csn), new FileOutputStream(file));
     }
 
+
+    /**
+     * Creates a new print stream, without automatic line flushing, with the
+     * specified file and charset.  This convenience constructor creates
+     * the necessary intermediate {@link java.io.OutputStreamWriter
+     * OutputStreamWriter}, which will encode characters using the provided
+     * charset.
+     *
+     * @param  file
+     *         The file to use as the destination of this print stream.  If the
+     *         file exists, then it will be truncated to zero size; otherwise,
+     *         a new file will be created.  The output will be written to the
+     *         file and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs while opening or creating the file
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and {@link
+     *          SecurityManager#checkWrite checkWrite(file.getPath())}
+     *          denies write access to the file
+     *
+     * @since  10
+     */
+    public PrintStream(File file, Charset charset) throws IOException {
+        this(false, requireNonNull(charset, "charset"), new FileOutputStream(file));
+    }
+
     /** Check to make sure that the stream has not been closed */
     private void ensureOpen() throws IOException {
         if (out == null)
--- a/src/java.base/share/classes/java/io/PrintWriter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/io/PrintWriter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,11 @@
  * constructors may.  The client may inquire as to whether any errors have
  * occurred by invoking {@link #checkError checkError()}.
  *
+ * <p> This class always replaces malformed and unmappable character sequences with
+ * the charset's default replacement string.
+ * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
+ * control over the encoding process is required.
+ *
  * @author      Frank Yellin
  * @author      Mark Reinhold
  * @since       1.1
@@ -137,7 +142,26 @@
      * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
      */
     public PrintWriter(OutputStream out, boolean autoFlush) {
-        this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
+        this(out, autoFlush, Charset.defaultCharset());
+    }
+
+    /**
+     * Creates a new PrintWriter from an existing OutputStream.  This
+     * convenience constructor creates the necessary intermediate
+     * OutputStreamWriter, which will convert characters into bytes using the
+     * specified charset.
+     *
+     * @param  out        An output stream
+     * @param  autoFlush  A boolean; if true, the {@code println},
+     *                    {@code printf}, or {@code format} methods will
+     *                    flush the output buffer
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @since 10
+     */
+    public PrintWriter(OutputStream out, boolean autoFlush, Charset charset) {
+        this(new BufferedWriter(new OutputStreamWriter(out, charset)), autoFlush);
 
         // save print stream for error propagation
         if (out instanceof java.io.PrintStream) {
@@ -226,6 +250,36 @@
 
     /**
      * Creates a new PrintWriter, without automatic line flushing, with the
+     * specified file name and charset.  This convenience constructor creates
+     * the necessary intermediate {@link java.io.OutputStreamWriter
+     * OutputStreamWriter}, which will encode characters using the provided
+     * charset.
+     *
+     * @param  fileName
+     *         The name of the file to use as the destination of this writer.
+     *         If the file exists then it will be truncated to zero size;
+     *         otherwise, a new file will be created.  The output will be
+     *         written to the file and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs while opening or creating the file
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and {@link
+     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
+     *          access to the file
+     *
+     * @since  10
+     */
+    public PrintWriter(String fileName, Charset charset) throws IOException {
+        this(Objects.requireNonNull(charset, "charset"), new File(fileName));
+    }
+
+    /**
+     * Creates a new PrintWriter, without automatic line flushing, with the
      * specified file.  This convenience constructor creates the necessary
      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
      * which will encode characters using the {@linkplain
@@ -295,6 +349,36 @@
         this(toCharset(csn), file);
     }
 
+    /**
+     * Creates a new PrintWriter, without automatic line flushing, with the
+     * specified file and charset.  This convenience constructor creates the
+     * necessary intermediate {@link java.io.OutputStreamWriter
+     * OutputStreamWriter}, which will encode characters using the provided
+     * charset.
+     *
+     * @param  file
+     *         The file to use as the destination of this writer.  If the file
+     *         exists then it will be truncated to zero size; otherwise, a new
+     *         file will be created.  The output will be written to the file
+     *         and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs while opening or creating the file
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and {@link
+     *          SecurityManager#checkWrite checkWrite(file.getPath())}
+     *          denies write access to the file
+     *
+     * @since  10
+     */
+    public PrintWriter(File file, Charset charset) throws IOException {
+        this(Objects.requireNonNull(charset, "charset"), file);
+    }
+
     /** Checks to make sure that the stream has not been closed */
     private void ensureOpen() throws IOException {
         if (out == null)
--- a/src/java.base/share/classes/java/lang/String.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/lang/String.java	Wed Dec 13 10:56:50 2017 -0800
@@ -3046,6 +3046,10 @@
         return COMPACT_STRINGS ? coder : UTF16;
     }
 
+    byte[] value() {
+        return value;
+    }
+
     private boolean isLatin1() {
         return COMPACT_STRINGS && coder == LATIN1;
     }
--- a/src/java.base/share/classes/java/lang/StringCoding.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/lang/StringCoding.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,11 @@
 import static java.lang.String.LATIN1;
 import static java.lang.String.UTF16;
 import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.Character.isSurrogate;
+import static java.lang.Character.highSurrogate;
+import static java.lang.Character.lowSurrogate;
+import static java.lang.Character.isSupplementaryCodePoint;
+import static java.lang.StringUTF16.putChar;
 
 /**
  * Utility class for string encoding and decoding.
@@ -66,8 +71,6 @@
     private static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
     private static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
 
-    private static boolean warnUnsupportedCharset = true;
-
     private static <T> T deref(ThreadLocal<SoftReference<T>> tl) {
         SoftReference<T> sr = tl.get();
         if (sr == null)
@@ -80,7 +83,6 @@
     }
 
     // Trim the given byte array to the given length
-    //
     private static byte[] safeTrim(byte[] ba, int len, boolean isTrusted) {
         if (len == ba.length && (isTrusted || System.getSecurityManager() == null))
             return ba;
@@ -105,17 +107,6 @@
         return null;
     }
 
-    private static void warnUnsupportedCharset(String csn) {
-        if (warnUnsupportedCharset) {
-            // Use err(String) rather than the Logging API or System.err
-            // since this method may be called during VM initialization
-            // before either is available.
-            err("WARNING: Default charset " + csn +
-                " not supported, using ISO-8859-1 instead\n");
-            warnUnsupportedCharset = false;
-        }
-    }
-
     static class Result {
         byte[] value;
         byte coder;
@@ -224,19 +215,6 @@
         }
     }
 
-    private static class StringDecoder8859_1 extends StringDecoder {
-        StringDecoder8859_1(Charset cs, String rcn) {
-            super(cs, rcn);
-        }
-        Result decode(byte[] ba, int off, int len) {
-            if (COMPACT_STRINGS) {
-                return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1);
-            } else {
-                return result.with(StringLatin1.inflate(ba, off, len), UTF16);
-            }
-        }
-    }
-
     static Result decode(String charsetName, byte[] ba, int off, int len)
         throws UnsupportedEncodingException
     {
@@ -249,12 +227,15 @@
                 Charset cs = lookupCharset(csn);
                 if (cs != null) {
                     if (cs == UTF_8) {
-                        sd = new StringDecoderUTF8(cs, csn);
-                    } else if (cs == ISO_8859_1) {
-                        sd = new StringDecoder8859_1(cs, csn);
-                    } else {
-                        sd = new StringDecoder(cs, csn);
+                        return decodeUTF8(ba, off, len, true);
                     }
+                    if (cs == ISO_8859_1) {
+                        return decodeLatin1(ba, off, len);
+                    }
+                    if (cs == US_ASCII) {
+                        return decodeASCII(ba, off, len);
+                    }
+                    sd = new StringDecoder(cs, csn);
                 }
             } catch (IllegalCharsetNameException x) {}
             if (sd == null)
@@ -265,6 +246,16 @@
     }
 
     static Result decode(Charset cs, byte[] ba, int off, int len) {
+        if (cs == UTF_8) {
+            return decodeUTF8(ba, off, len, true);
+        }
+        if (cs == ISO_8859_1) {
+            return decodeLatin1(ba, off, len);
+        }
+        if (cs == US_ASCII) {
+            return decodeASCII(ba, off, len);
+        }
+
         // (1)We never cache the "external" cs, the only benefit of creating
         // an additional StringDe/Encoder object to wrap it is to share the
         // de/encode() method. These SD/E objects are short-lived, the young-gen
@@ -280,39 +271,29 @@
         // check (... && (isTrusted || SM == null || getClassLoader0())) in trim
         // but it then can be argued that the SM is null when the operation
         // is started...
-        if (cs == UTF_8) {
-            return StringDecoderUTF8.decode(ba, off, len, new Result());
-        }
         CharsetDecoder cd = cs.newDecoder();
         // ascii fastpath
-        if (cs == ISO_8859_1 || ((cd instanceof ArrayDecoder) &&
-                                 ((ArrayDecoder)cd).isASCIICompatible() &&
-                                 !hasNegatives(ba, off, len))) {
-             if (COMPACT_STRINGS) {
-                 return new Result().with(Arrays.copyOfRange(ba, off, off + len),
-                                          LATIN1);
-             } else {
-                 return new Result().with(StringLatin1.inflate(ba, off, len), UTF16);
-             }
+        if ((cd instanceof ArrayDecoder) &&
+            ((ArrayDecoder)cd).isASCIICompatible() && !hasNegatives(ba, off, len)) {
+            return decodeLatin1(ba, off, len);
         }
         int en = scale(len, cd.maxCharsPerByte());
         if (len == 0) {
             return new Result().with();
         }
-        if (cs.getClass().getClassLoader0() != null &&
-            System.getSecurityManager() != null) {
-            ba =  Arrays.copyOfRange(ba, off, off + len);
-            off = 0;
-        }
         cd.onMalformedInput(CodingErrorAction.REPLACE)
           .onUnmappableCharacter(CodingErrorAction.REPLACE)
           .reset();
-
         char[] ca = new char[en];
         if (cd instanceof ArrayDecoder) {
             int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
             return new Result().with(ca, 0, clen);
         }
+        if (cs.getClass().getClassLoader0() != null &&
+            System.getSecurityManager() != null) {
+            ba = Arrays.copyOfRange(ba, off, off + len);
+            off = 0;
+        }
         ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
         CharBuffer cb = CharBuffer.wrap(ca);
         try {
@@ -331,24 +312,22 @@
     }
 
     static Result decode(byte[] ba, int off, int len) {
-        String csn = Charset.defaultCharset().name();
-        try {
-            // use charset name decode() variant which provides caching.
-            return decode(csn, ba, off, len);
-        } catch (UnsupportedEncodingException x) {
-            warnUnsupportedCharset(csn);
+        Charset cs = Charset.defaultCharset();
+        if (cs == UTF_8) {
+            return decodeUTF8(ba, off, len, true);
         }
-        try {
-            return decode("ISO-8859-1", ba, off, len);
-        } catch (UnsupportedEncodingException x) {
-            // If this code is hit during VM initialization, err(String) is
-            // the only way we will be able to get any kind of error message.
-            err("ISO-8859-1 charset not available: " + x.toString() + "\n");
-            // If we can not find ISO-8859-1 (a required encoding) then things
-            // are seriously wrong with the installation.
-            System.exit(1);
-            return null;
+        if (cs == ISO_8859_1) {
+            return decodeLatin1(ba, off, len);
         }
+        if (cs == US_ASCII) {
+            return decodeASCII(ba, off, len);
+        }
+        StringDecoder sd = deref(decoder);
+        if (sd == null || !cs.name().equals(sd.cs.name())) {
+            sd = new StringDecoder(cs, cs.name());
+            set(decoder, sd);
+        }
+        return sd.decode(ba, off, len);
     }
 
     // -- Encoding --
@@ -393,9 +372,6 @@
                 return ba;
             }
             if (ce instanceof ArrayEncoder) {
-                if (!isTrusted) {
-                    val = Arrays.copyOf(val, val.length);
-                }
                 int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
                                               : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
                 if (blen != -1) {
@@ -423,49 +399,140 @@
         }
     }
 
-    @HotSpotIntrinsicCandidate
-    private static int implEncodeISOArray(byte[] sa, int sp,
-                                          byte[] da, int dp, int len) {
-        int i = 0;
-        for (; i < len; i++) {
-            char c = StringUTF16.getChar(sa, sp++);
-            if (c > '\u00FF')
-                break;
-            da[dp++] = (byte)c;
+    static byte[] encode(String charsetName, byte coder, byte[] val)
+        throws UnsupportedEncodingException
+    {
+        StringEncoder se = deref(encoder);
+        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
+        if ((se == null) || !(csn.equals(se.requestedCharsetName())
+                              || csn.equals(se.charsetName()))) {
+            se = null;
+            try {
+                Charset cs = lookupCharset(csn);
+                if (cs != null) {
+                    if (cs == UTF_8) {
+                        return encodeUTF8(coder, val, true);
+                    }
+                    if (cs == ISO_8859_1) {
+                        return encode8859_1(coder, val);
+                    }
+                    if (cs == US_ASCII) {
+                        return encodeASCII(coder, val);
+                    }
+                    se = new StringEncoder(cs, csn);
+                }
+            } catch (IllegalCharsetNameException x) {}
+            if (se == null) {
+                throw new UnsupportedEncodingException (csn);
+            }
+            set(encoder, se);
         }
-        return i;
+        return se.encode(coder, val);
     }
 
-    static byte[] encode8859_1(byte coder, byte[] val) {
-        if (coder == LATIN1) {
+    static byte[] encode(Charset cs, byte coder, byte[] val) {
+        if (cs == UTF_8) {
+            return encodeUTF8(coder, val, true);
+        }
+        if (cs == ISO_8859_1) {
+            return encode8859_1(coder, val);
+        }
+        if (cs == US_ASCII) {
+            return encodeASCII(coder, val);
+        }
+        CharsetEncoder ce = cs.newEncoder();
+        // fastpath for ascii compatible
+        if (coder == LATIN1 && (((ce instanceof ArrayEncoder) &&
+                                 ((ArrayEncoder)ce).isASCIICompatible() &&
+                                 !hasNegatives(val, 0, val.length)))) {
             return Arrays.copyOf(val, val.length);
         }
-        int len = val.length >> 1;
-        byte[] dst = new byte[len];
-        int dp = 0;
-        int sp = 0;
-        int sl = len;
-        while (sp < sl) {
-            int ret = implEncodeISOArray(val, sp, dst, dp, len);
-            sp = sp + ret;
-            dp = dp + ret;
-            if (ret != len) {
-                char c = StringUTF16.getChar(val, sp++);
-                if (Character.isHighSurrogate(c) && sp < sl &&
-                    Character.isLowSurrogate(StringUTF16.getChar(val, sp))) {
-                    sp++;
-                }
-                dst[dp++] = '?';
-                len = sl - sp;
+        int len = val.length >> coder;  // assume LATIN1=0/UTF16=1;
+        int en = scale(len, ce.maxBytesPerChar());
+        byte[] ba = new byte[en];
+        if (len == 0) {
+            return ba;
+        }
+        ce.onMalformedInput(CodingErrorAction.REPLACE)
+          .onUnmappableCharacter(CodingErrorAction.REPLACE)
+          .reset();
+        if (ce instanceof ArrayEncoder) {
+            int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
+                                          : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
+            if (blen != -1) {
+                return safeTrim(ba, blen, true);
             }
         }
-        if (dp == dst.length) {
-            return dst;
+        boolean isTrusted = cs.getClass().getClassLoader0() == null ||
+                            System.getSecurityManager() == null;
+        char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
+                                       : StringUTF16.toChars(val);
+        ByteBuffer bb = ByteBuffer.wrap(ba);
+        CharBuffer cb = CharBuffer.wrap(ca, 0, len);
+        try {
+            CoderResult cr = ce.encode(cb, bb, true);
+            if (!cr.isUnderflow())
+                cr.throwException();
+            cr = ce.flush(bb);
+            if (!cr.isUnderflow())
+                cr.throwException();
+        } catch (CharacterCodingException x) {
+            throw new Error(x);
         }
-        return Arrays.copyOf(dst, dp);
+        return safeTrim(ba, bb.position(), isTrusted);
     }
 
-    static byte[] encodeASCII(byte coder, byte[] val) {
+    static byte[] encode(byte coder, byte[] val) {
+        Charset cs = Charset.defaultCharset();
+        if (cs == UTF_8) {
+            return encodeUTF8(coder, val, true);
+        }
+        if (cs == ISO_8859_1) {
+            return encode8859_1(coder, val);
+        }
+        if (cs == US_ASCII) {
+            return encodeASCII(coder, val);
+        }
+        StringEncoder se = deref(encoder);
+        if (se == null || !cs.name().equals(se.cs.name())) {
+            se = new StringEncoder(cs, cs.name());
+            set(encoder, se);
+        }
+        return se.encode(coder, val);
+    }
+
+    /**
+     *  Print a message directly to stderr, bypassing all character conversion
+     *  methods.
+     *  @param msg  message to print
+     */
+    private static native void err(String msg);
+
+     /* The cached Result for each thread */
+    private static final ThreadLocal<StringCoding.Result>
+        resultCached = new ThreadLocal<>() {
+            protected StringCoding.Result initialValue() {
+                return new StringCoding.Result();
+            }};
+
+    ////////////////////////// ascii //////////////////////////////
+
+    private static Result decodeASCII(byte[] ba, int off, int len) {
+        Result result = resultCached.get();
+        if (COMPACT_STRINGS && !hasNegatives(ba, off, len)) {
+            return result.with(Arrays.copyOfRange(ba, off, off + len),
+                               LATIN1);
+        }
+        byte[] dst = new byte[len<<1];
+        int dp = 0;
+        while (dp < len) {
+            int b = ba[off++];
+            putChar(dst, dp++, (b >= 0) ? (char)b : repl);
+        }
+        return result.with(dst, UTF16);
+    }
+
+    private static byte[] encodeASCII(byte coder, byte[] val) {
         if (coder == LATIN1) {
             byte[] dst = new byte[val.length];
             for (int i = 0; i < val.length; i++) {
@@ -498,59 +565,51 @@
         return Arrays.copyOf(dst, dp);
     }
 
-   static byte[] encodeUTF8(byte coder, byte[] val) {
+    ////////////////////////// latin1/8859_1 ///////////////////////////
+
+    private static Result decodeLatin1(byte[] ba, int off, int len) {
+       Result result = resultCached.get();
+       if (COMPACT_STRINGS) {
+           return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1);
+       } else {
+           return result.with(StringLatin1.inflate(ba, off, len), UTF16);
+       }
+    }
+
+    @HotSpotIntrinsicCandidate
+    private static int implEncodeISOArray(byte[] sa, int sp,
+                                          byte[] da, int dp, int len) {
+        int i = 0;
+        for (; i < len; i++) {
+            char c = StringUTF16.getChar(sa, sp++);
+            if (c > '\u00FF')
+                break;
+            da[dp++] = (byte)c;
+        }
+        return i;
+    }
+
+    private static byte[] encode8859_1(byte coder, byte[] val) {
+        if (coder == LATIN1) {
+            return Arrays.copyOf(val, val.length);
+        }
+        int len = val.length >> 1;
+        byte[] dst = new byte[len];
         int dp = 0;
-        byte[] dst;
-        if (coder == LATIN1) {
-            dst = new byte[val.length << 1];
-            for (int sp = 0; sp < val.length; sp++) {
-                byte c = val[sp];
-                if (c < 0) {
-                    dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6));
-                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
-                } else {
-                    dst[dp++] = c;
+        int sp = 0;
+        int sl = len;
+        while (sp < sl) {
+            int ret = implEncodeISOArray(val, sp, dst, dp, len);
+            sp = sp + ret;
+            dp = dp + ret;
+            if (ret != len) {
+                char c = StringUTF16.getChar(val, sp++);
+                if (Character.isHighSurrogate(c) && sp < sl &&
+                    Character.isLowSurrogate(StringUTF16.getChar(val, sp))) {
+                    sp++;
                 }
-            }
-        } else {
-            int sp = 0;
-            int sl = val.length >> 1;
-            dst = new byte[sl * 3];
-            char c;
-            while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') {
-                // ascii fast loop;
-                dst[dp++] = (byte)c;
-                sp++;
-            }
-            while (sp < sl) {
-                c = StringUTF16.getChar(val, sp++);
-                if (c < 0x80) {
-                    dst[dp++] = (byte)c;
-                } else if (c < 0x800) {
-                    dst[dp++] = (byte)(0xc0 | (c >> 6));
-                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
-                } else if (Character.isSurrogate(c)) {
-                    int uc = -1;
-                    char c2;
-                    if (Character.isHighSurrogate(c) && sp < sl &&
-                        Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) {
-                        uc = Character.toCodePoint(c, c2);
-                    }
-                    if (uc < 0) {
-                        dst[dp++] = '?';
-                    } else {
-                        dst[dp++] = (byte)(0xf0 | ((uc >> 18)));
-                        dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
-                        dst[dp++] = (byte)(0x80 | ((uc >>  6) & 0x3f));
-                        dst[dp++] = (byte)(0x80 | (uc & 0x3f));
-                        sp++;  // 2 chars
-                    }
-                } else {
-                    // 3 bytes, 16 bits
-                    dst[dp++] = (byte)(0xe0 | ((c >> 12)));
-                    dst[dp++] = (byte)(0x80 | ((c >>  6) & 0x3f));
-                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
-                }
+                dst[dp++] = '?';
+                len = sl - sp;
             }
         }
         if (dp == dst.length) {
@@ -559,113 +618,333 @@
         return Arrays.copyOf(dst, dp);
     }
 
-    static byte[] encode(String charsetName, byte coder, byte[] val)
-        throws UnsupportedEncodingException
-    {
-        StringEncoder se = deref(encoder);
-        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
-        if ((se == null) || !(csn.equals(se.requestedCharsetName())
-                              || csn.equals(se.charsetName()))) {
-            se = null;
-            try {
-                Charset cs = lookupCharset(csn);
-                if (cs != null) {
-                    if (cs == UTF_8) {
-                        return encodeUTF8(coder, val);
-                    } else if (cs == ISO_8859_1) {
-                        return encode8859_1(coder, val);
-                    } else if (cs == US_ASCII) {
-                        return encodeASCII(coder, val);
-                    }
-                    se = new StringEncoder(cs, csn);
-                }
-            } catch (IllegalCharsetNameException x) {}
-            if (se == null) {
-                throw new UnsupportedEncodingException (csn);
-            }
-            set(encoder, se);
-        }
-        return se.encode(coder, val);
+    //////////////////////////////// utf8 ////////////////////////////////////
+
+    private static boolean isNotContinuation(int b) {
+        return (b & 0xc0) != 0x80;
     }
 
-    static byte[] encode(Charset cs, byte coder, byte[] val) {
-        if (cs == UTF_8) {
-            return encodeUTF8(coder, val);
-        } else if (cs == ISO_8859_1) {
-            return encode8859_1(coder, val);
-        } else if (cs == US_ASCII) {
-            return encodeASCII(coder, val);
+    private static boolean isMalformed3(int b1, int b2, int b3) {
+        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+               (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed3_2(int b1, int b2) {
+        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+               (b2 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4(int b2, int b3, int b4) {
+        return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
+               (b4 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4_2(int b1, int b2) {
+        return (b1 == 0xf0 && (b2  < 0x90 || b2 > 0xbf)) ||
+               (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+               (b2 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4_3(int b3) {
+        return (b3 & 0xc0) != 0x80;
+    }
+
+    // for nb == 3/4
+    private static int malformedN(byte[] src, int sp, int nb) {
+        if (nb == 3) {
+            int b1 = src[sp++];
+            int b2 = src[sp++];    // no need to lookup b3
+            return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+                    isNotContinuation(b2)) ? 1 : 2;
+        } else if (nb == 4) { // we don't care the speed here
+            int b1 = src[sp++] & 0xff;
+            int b2 = src[sp++] & 0xff;
+            if (b1 > 0xf4 ||
+                (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
+                (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+                isNotContinuation(b2))
+                return 1;
+            if (isNotContinuation(src[sp++]))
+                return 2;
+            return 3;
         }
-        CharsetEncoder ce = cs.newEncoder();
-        // fastpath for ascii compatible
-        if (coder == LATIN1 && (((ce instanceof ArrayEncoder) &&
-                                 ((ArrayEncoder)ce).isASCIICompatible() &&
-                                 !hasNegatives(val, 0, val.length)))) {
-            return Arrays.copyOf(val, val.length);
-        }
-        int len = val.length >> coder;  // assume LATIN1=0/UTF16=1;
-        int en = scale(len, ce.maxBytesPerChar());
-        byte[] ba = new byte[en];
-        if (len == 0) {
-            return ba;
-        }
-        boolean isTrusted = cs.getClass().getClassLoader0() == null ||
-                            System.getSecurityManager() == null;
-        ce.onMalformedInput(CodingErrorAction.REPLACE)
-          .onUnmappableCharacter(CodingErrorAction.REPLACE)
-          .reset();
-        if (ce instanceof ArrayEncoder) {
-            if (!isTrusted) {
-                val = Arrays.copyOf(val, val.length);
+        assert false;
+        return -1;
+    }
+
+    private static void throwMalformed(int off, int nb) {
+        throw new IllegalArgumentException("malformed input off : " + off +
+                                           ", length : " + nb);
+    }
+
+    private static char repl = '\ufffd';
+
+    private static Result decodeUTF8(byte[] src, int sp, int len, boolean doReplace) {
+        // ascii-bais, which has a relative impact to the non-ascii-only bytes
+        if (COMPACT_STRINGS && !hasNegatives(src, sp, len))
+            return resultCached.get().with(Arrays.copyOfRange(src, sp, sp + len),
+                                           LATIN1);
+        return decodeUTF8_0(src, sp, len, doReplace);
+    }
+
+    private static Result decodeUTF8_0(byte[] src, int sp, int len, boolean doReplace) {
+        Result ret = resultCached.get();
+
+        int sl = sp + len;
+        int dp = 0;
+        byte[] dst = new byte[len];
+
+        if (COMPACT_STRINGS) {
+            while (sp < sl) {
+                int b1 = src[sp];
+                if (b1 >= 0) {
+                    dst[dp++] = (byte)b1;
+                    sp++;
+                    continue;
+                }
+                if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) &&
+                    sp + 1 < sl) {
+                    int b2 = src[sp + 1];
+                    if (!isNotContinuation(b2)) {
+                        dst[dp++] = (byte)(((b1 << 6) ^ b2)^
+                                           (((byte) 0xC0 << 6) ^
+                                           ((byte) 0x80 << 0)));
+                        sp += 2;
+                        continue;
+                    }
+                }
+                // anything not a latin1, including the repl
+                // we have to go with the utf16
+                break;
             }
-            int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
-                                          : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
-            if (blen != -1) {
-                return safeTrim(ba, blen, isTrusted);
+            if (sp == sl) {
+                if (dp != dst.length) {
+                    dst = Arrays.copyOf(dst, dp);
+                }
+                return ret.with(dst, LATIN1);
             }
         }
-        char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
-                                       : StringUTF16.toChars(val);
-        ByteBuffer bb = ByteBuffer.wrap(ba);
-        CharBuffer cb = CharBuffer.wrap(ca, 0, len);
-        try {
-            CoderResult cr = ce.encode(cb, bb, true);
-            if (!cr.isUnderflow())
-                cr.throwException();
-            cr = ce.flush(bb);
-            if (!cr.isUnderflow())
-                cr.throwException();
-        } catch (CharacterCodingException x) {
-            throw new Error(x);
+        if (dp == 0) {
+            dst = new byte[len << 1];
+        } else {
+            byte[] buf = new byte[len << 1];
+            StringLatin1.inflate(dst, 0, buf, 0, dp);
+            dst = buf;
         }
-        return safeTrim(ba, bb.position(), isTrusted);
+        while (sp < sl) {
+            int b1 = src[sp++];
+            if (b1 >= 0) {
+                putChar(dst, dp++, (char) b1);
+            } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
+                if (sp < sl) {
+                    int b2 = src[sp++];
+                    if (isNotContinuation(b2)) {
+                        if (!doReplace) {
+                            throwMalformed(sp - 1, 1);
+                        }
+                        putChar(dst, dp++, repl);
+                        sp--;
+                    } else {
+                        putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^
+                                                  (((byte) 0xC0 << 6) ^
+                                                  ((byte) 0x80 << 0))));
+                    }
+                    continue;
+                }
+                if (!doReplace) {
+                    throwMalformed(sp, 1);  // underflow()
+                }
+                putChar(dst, dp++, repl);
+                break;
+            } else if ((b1 >> 4) == -2) {
+                if (sp + 1 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    if (isMalformed3(b1, b2, b3)) {
+                        if (!doReplace) {
+                            throwMalformed(sp - 3, 3);
+                        }
+                        putChar(dst, dp++, repl);
+                        sp -= 3;
+                        sp += malformedN(src, sp, 3);
+                    } else {
+                        char c = (char)((b1 << 12) ^
+                                        (b2 <<  6) ^
+                                        (b3 ^
+                                         (((byte) 0xE0 << 12) ^
+                                         ((byte) 0x80 <<  6) ^
+                                         ((byte) 0x80 <<  0))));
+                        if (isSurrogate(c)) {
+                            if (!doReplace) {
+                                throwMalformed(sp - 3, 3);
+                            }
+                            putChar(dst, dp++, repl);
+                        } else {
+                            putChar(dst, dp++, c);
+                        }
+                    }
+                    continue;
+                }
+                if (sp  < sl && isMalformed3_2(b1, src[sp])) {
+                    if (!doReplace) {
+                        throwMalformed(sp - 1, 2);
+                    }
+                    putChar(dst, dp++, repl);
+                    continue;
+                }
+                if (!doReplace){
+                    throwMalformed(sp, 1);
+                }
+                putChar(dst, dp++, repl);
+                break;
+            } else if ((b1 >> 3) == -2) {
+                if (sp + 2 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    int b4 = src[sp++];
+                    int uc = ((b1 << 18) ^
+                              (b2 << 12) ^
+                              (b3 <<  6) ^
+                              (b4 ^
+                               (((byte) 0xF0 << 18) ^
+                               ((byte) 0x80 << 12) ^
+                               ((byte) 0x80 <<  6) ^
+                               ((byte) 0x80 <<  0))));
+                    if (isMalformed4(b2, b3, b4) ||
+                        !isSupplementaryCodePoint(uc)) { // shortest form check
+                        if (!doReplace) {
+                            throwMalformed(sp - 4, 4);
+                        }
+                        putChar(dst, dp++, repl);
+                        sp -= 4;
+                        sp += malformedN(src, sp, 4);
+                    } else {
+                        putChar(dst, dp++, highSurrogate(uc));
+                        putChar(dst, dp++, lowSurrogate(uc));
+                    }
+                    continue;
+                }
+                b1 &= 0xff;
+                if (b1 > 0xf4 ||
+                    sp  < sl && isMalformed4_2(b1, src[sp] & 0xff)) {
+                    if (!doReplace) {
+                        throwMalformed(sp - 1, 1);  // or 2
+                    }
+                    putChar(dst, dp++, repl);
+                    continue;
+                }
+                if (!doReplace) {
+                    throwMalformed(sp - 1, 1);
+                }
+                sp++;
+                putChar(dst, dp++, repl);
+                if (sp  < sl && isMalformed4_3(src[sp])) {
+                    continue;
+                }
+                break;
+            } else {
+                if (!doReplace) {
+                    throwMalformed(sp - 1, 1);
+                }
+                putChar(dst, dp++, repl);
+            }
+        }
+        if (dp != len) {
+            dst = Arrays.copyOf(dst, dp << 1);
+        }
+        return ret.with(dst, UTF16);
     }
 
-    static byte[] encode(byte coder, byte[] val) {
-        String csn = Charset.defaultCharset().name();
-        try {
-            // use charset name encode() variant which provides caching.
-            return encode(csn, coder, val);
-        } catch (UnsupportedEncodingException x) {
-            warnUnsupportedCharset(csn);
+    private static byte[] encodeUTF8(byte coder, byte[] val, boolean doReplace) {
+        if (coder == UTF16)
+            return encodeUTF8_UTF16(val, doReplace);
+
+        if (!hasNegatives(val, 0, val.length))
+            return Arrays.copyOf(val, val.length);
+
+        int dp = 0;
+        byte[] dst = new byte[val.length << 1];
+        for (int sp = 0; sp < val.length; sp++) {
+            byte c = val[sp];
+            if (c < 0) {
+                dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6));
+                dst[dp++] = (byte)(0x80 | (c & 0x3f));
+            } else {
+                dst[dp++] = c;
+            }
         }
-        try {
-            return encode("ISO-8859-1", coder, val);
-        } catch (UnsupportedEncodingException x) {
-            // If this code is hit during VM initialization, err(String) is
-            // the only way we will be able to get any kind of error message.
-            err("ISO-8859-1 charset not available: " + x.toString() + "\n");
-            // If we can not find ISO-8859-1 (a required encoding) then things
-            // are seriously wrong with the installation.
-            System.exit(1);
-            return null;
-        }
+        if (dp == dst.length)
+            return dst;
+        return Arrays.copyOf(dst, dp);
     }
 
-    /**
-     *  Print a message directly to stderr, bypassing all character conversion
-     *  methods.
-     *  @param msg  message to print
+    private static byte[] encodeUTF8_UTF16(byte[] val, boolean doReplace) {
+        int dp = 0;
+        int sp = 0;
+        int sl = val.length >> 1;
+        byte[] dst = new byte[sl * 3];
+        char c;
+        while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') {
+            // ascii fast loop;
+            dst[dp++] = (byte)c;
+            sp++;
+        }
+        while (sp < sl) {
+            c = StringUTF16.getChar(val, sp++);
+            if (c < 0x80) {
+                dst[dp++] = (byte)c;
+            } else if (c < 0x800) {
+                dst[dp++] = (byte)(0xc0 | (c >> 6));
+                dst[dp++] = (byte)(0x80 | (c & 0x3f));
+            } else if (Character.isSurrogate(c)) {
+                int uc = -1;
+                char c2;
+                if (Character.isHighSurrogate(c) && sp < sl &&
+                    Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) {
+                    uc = Character.toCodePoint(c, c2);
+                }
+                if (uc < 0) {
+                    if (doReplace) {
+                        dst[dp++] = '?';
+                    } else {
+                        throwMalformed(sp - 1, 1); // or 2, does not matter here
+                    }
+                } else {
+                    dst[dp++] = (byte)(0xf0 | ((uc >> 18)));
+                    dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
+                    dst[dp++] = (byte)(0x80 | ((uc >>  6) & 0x3f));
+                    dst[dp++] = (byte)(0x80 | (uc & 0x3f));
+                    sp++;  // 2 chars
+                }
+            } else {
+                // 3 bytes, 16 bits
+                dst[dp++] = (byte)(0xe0 | ((c >> 12)));
+                dst[dp++] = (byte)(0x80 | ((c >>  6) & 0x3f));
+                dst[dp++] = (byte)(0x80 | (c & 0x3f));
+            }
+        }
+        if (dp == dst.length) {
+            return dst;
+        }
+        return Arrays.copyOf(dst, dp);
+    }
+
+    ////////////////////// for j.u.z.ZipCoder //////////////////////////
+
+    /*
+     * Throws iae, instead of replacing, if malformed or unmappble.
      */
-    private static native void err(String msg);
+    static String newStringUTF8NoRepl(byte[] src, int off, int len) {
+        if (COMPACT_STRINGS && !hasNegatives(src, off, len))
+            return new String(Arrays.copyOfRange(src, off, off + len), LATIN1);
+        Result ret = decodeUTF8_0(src, off, len, false);
+        return new String(ret.value, ret.coder);
+    }
+
+    /*
+     * Throws iae, instead of replacing, if unmappble.
+     */
+    static byte[] getBytesUTF8NoRepl(String s) {
+        return encodeUTF8(s.coder(), s.value(), false);
+    }
 }
--- a/src/java.base/share/classes/java/lang/StringDecoderUTF8.java	Wed Dec 13 14:41:27 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-
-import static java.lang.String.LATIN1;
-import static java.lang.String.UTF16;
-import static java.lang.String.COMPACT_STRINGS;
-import static java.lang.Character.isSurrogate;
-import static java.lang.Character.highSurrogate;
-import static java.lang.Character.lowSurrogate;
-import static java.lang.Character.isSupplementaryCodePoint;
-import static java.lang.StringUTF16.putChar;
-
-class StringDecoderUTF8 extends StringCoding.StringDecoder {
-
-    StringDecoderUTF8(Charset cs, String rcn) {
-        super(cs, rcn);
-    }
-
-    private static boolean isNotContinuation(int b) {
-        return (b & 0xc0) != 0x80;
-    }
-
-    private static boolean isMalformed3(int b1, int b2, int b3) {
-        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
-               (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
-    }
-
-    private static boolean isMalformed3_2(int b1, int b2) {
-        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
-               (b2 & 0xc0) != 0x80;
-    }
-
-    private static boolean isMalformed4(int b2, int b3, int b4) {
-        return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
-               (b4 & 0xc0) != 0x80;
-    }
-
-    private static boolean isMalformed4_2(int b1, int b2) {
-        return (b1 == 0xf0 && (b2  < 0x90 || b2 > 0xbf)) ||
-               (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
-               (b2 & 0xc0) != 0x80;
-    }
-
-    private static boolean isMalformed4_3(int b3) {
-        return (b3 & 0xc0) != 0x80;
-    }
-
-    // for nb == 3/4
-    private static int malformedN(byte[] src, int sp, int nb) {
-        if (nb == 3) {
-            int b1 = src[sp++];
-            int b2 = src[sp++];    // no need to lookup b3
-            return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
-                    isNotContinuation(b2)) ? 1 : 2;
-        } else if (nb == 4) { // we don't care the speed here
-            int b1 = src[sp++] & 0xff;
-            int b2 = src[sp++] & 0xff;
-            if (b1 > 0xf4 ||
-                (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
-                (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
-                isNotContinuation(b2))
-                return 1;
-            if (isNotContinuation(src[sp++]))
-                return 2;
-            return 3;
-        }
-        assert false;
-        return -1;
-    }
-
-    private static char repl = '\ufffd';
-
-    StringCoding.Result decode(byte[] src, int sp, int len) {
-        return decode(src, sp, len, result);
-    }
-
-    static StringCoding.Result decode(byte[] src, int sp, int len,
-                                      StringCoding.Result ret) {
-        int sl = sp + len;
-        byte[] dst = new byte[len];
-        int dp = 0;
-        if (COMPACT_STRINGS) {   // Latin1 only loop
-            while (sp < sl) {
-                int b1 = src[sp];
-                if (b1 >= 0) {
-                    dst[dp++] = (byte)b1;
-                    sp++;
-                    continue;
-                }
-                if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) &&
-                    sp + 1 < sl) {
-                    int b2 = src[sp + 1];
-                    if (!isNotContinuation(b2)) {
-                        dst[dp++] = (byte)(((b1 << 6) ^ b2)^
-                                           (((byte) 0xC0 << 6) ^
-                                           ((byte) 0x80 << 0)));
-                        sp += 2;
-                        continue;
-                    }
-                }
-                // anything not a latin1, including the repl
-                // we have to go with the utf16
-                break;
-            }
-            if (sp == sl) {
-                if (dp != dst.length) {
-                    dst = Arrays.copyOf(dst, dp);
-                }
-                return ret.with(dst, LATIN1);
-            }
-        }
-        if (dp == 0) {
-            dst = new byte[len << 1];
-        } else {
-            byte[] buf = new byte[len << 1];
-            StringLatin1.inflate(dst, 0, buf, 0, dp);
-            dst = buf;
-        }
-        while (sp < sl) {
-            int b1 = src[sp++];
-            if (b1 >= 0) {
-                putChar(dst, dp++, (char) b1);
-            } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
-                if (sp < sl) {
-                    int b2 = src[sp++];
-                    if (isNotContinuation(b2)) {
-                        putChar(dst, dp++, repl);
-                        sp--;
-                    } else {
-                        putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^
-                                                  (((byte) 0xC0 << 6) ^
-                                                  ((byte) 0x80 << 0))));
-                    }
-                    continue;
-                }
-                putChar(dst, dp++, repl);
-                break;
-            } else if ((b1 >> 4) == -2) {
-                if (sp + 1 < sl) {
-                    int b2 = src[sp++];
-                    int b3 = src[sp++];
-                    if (isMalformed3(b1, b2, b3)) {
-                        putChar(dst, dp++, repl);
-                        sp -= 3;
-                        sp += malformedN(src, sp, 3);
-                    } else {
-                        char c = (char)((b1 << 12) ^
-                                        (b2 <<  6) ^
-                                        (b3 ^
-                                         (((byte) 0xE0 << 12) ^
-                                         ((byte) 0x80 <<  6) ^
-                                         ((byte) 0x80 <<  0))));
-                        putChar(dst, dp++, isSurrogate(c) ?  repl : c);
-                    }
-                    continue;
-                }
-                if (sp  < sl && isMalformed3_2(b1, src[sp])) {
-                    putChar(dst, dp++, repl);
-                    continue;
-                }
-                putChar(dst, dp++, repl);
-                break;
-            } else if ((b1 >> 3) == -2) {
-                if (sp + 2 < sl) {
-                    int b2 = src[sp++];
-                    int b3 = src[sp++];
-                    int b4 = src[sp++];
-                    int uc = ((b1 << 18) ^
-                              (b2 << 12) ^
-                              (b3 <<  6) ^
-                              (b4 ^
-                               (((byte) 0xF0 << 18) ^
-                               ((byte) 0x80 << 12) ^
-                               ((byte) 0x80 <<  6) ^
-                               ((byte) 0x80 <<  0))));
-                    if (isMalformed4(b2, b3, b4) ||
-                        !isSupplementaryCodePoint(uc)) { // shortest form check
-                        putChar(dst, dp++, repl);
-                        sp -= 4;
-                        sp += malformedN(src, sp, 4);
-                    } else {
-                        putChar(dst, dp++, highSurrogate(uc));
-                        putChar(dst, dp++, lowSurrogate(uc));
-                    }
-                    continue;
-                }
-                b1 &= 0xff;
-                if (b1 > 0xf4 ||
-                    sp  < sl && isMalformed4_2(b1, src[sp] & 0xff)) {
-                    putChar(dst, dp++, repl);
-                    continue;
-                }
-                sp++;
-                putChar(dst, dp++, repl);
-                if (sp  < sl && isMalformed4_3(src[sp])) {
-                    continue;
-                }
-                break;
-            } else {
-                putChar(dst, dp++, repl);
-            }
-        }
-        if (dp != len) {
-            dst = Arrays.copyOf(dst, dp << 1);
-        }
-        return ret.with(dst, UTF16);
-    }
-}
--- a/src/java.base/share/classes/java/lang/System.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/lang/System.java	Wed Dec 13 10:56:50 2017 -0800
@@ -2184,6 +2184,15 @@
             public Stream<ModuleLayer> layers(ClassLoader loader) {
                 return ModuleLayer.layers(loader);
             }
+
+            public String newStringUTF8NoRepl(byte[] bytes, int off, int len) {
+                return StringCoding.newStringUTF8NoRepl(bytes, off, len);
+            }
+
+            public byte[] getBytesUTF8NoRepl(String s) {
+                return StringCoding.getBytesUTF8NoRepl(s);
+            }
+
         });
     }
 }
--- a/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Dec 13 10:56:50 2017 -0800
@@ -105,23 +105,10 @@
     private @Stable String methodDescriptor;  // cache for toMethodDescriptorString
 
     /**
-     * Check the given parameters for validity and store them into the final fields.
+     * Constructor that performs no copying or validation.
+     * Should only be called from the factory method makeImpl
      */
-    private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
-        checkRtype(rtype);
-        checkPtypes(ptypes);
-        this.rtype = rtype;
-        // defensively copy the array passed in by the user
-        this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
-    }
-
-    /**
-     * Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
-     * Does not check the given parameters for validity, and must discarded (if untrusted) or checked
-     * (if trusted) after it has been used as a searching key.
-     * The parameters are reversed for this constructor, so that it is not accidentally used.
-     */
-    private MethodType(Class<?>[] ptypes, Class<?> rtype) {
+    private MethodType(Class<?> rtype, Class<?>[] ptypes) {
         this.rtype = rtype;
         this.ptypes = ptypes;
     }
@@ -308,18 +295,21 @@
         if (ptypes.length == 0) {
             ptypes = NO_PTYPES; trusted = true;
         }
-        MethodType primordialMT = new MethodType(ptypes, rtype);
+        MethodType primordialMT = new MethodType(rtype, ptypes);
         MethodType mt = internTable.get(primordialMT);
         if (mt != null)
             return mt;
 
         // promote the object to the Real Thing, and reprobe
+        MethodType.checkRtype(rtype);
         if (trusted) {
-            MethodType.checkRtype(rtype);
             MethodType.checkPtypes(ptypes);
             mt = primordialMT;
         } else {
-            mt = new MethodType(rtype, ptypes, false);
+            // Make defensive copy then validate
+            ptypes = Arrays.copyOf(ptypes, ptypes.length);
+            MethodType.checkPtypes(ptypes);
+            mt = new MethodType(rtype, ptypes);
         }
         mt.form = MethodTypeForm.findForm(mt);
         return internTable.add(mt);
--- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Wed Dec 13 10:56:50 2017 -0800
@@ -39,6 +39,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -2603,7 +2604,8 @@
      * Returns a string containing the given set of modifiers and label.
      */
     private static <M> String toString(Set<M> mods, String what) {
-        return (Stream.concat(mods.stream().map(e -> e.toString().toLowerCase()),
+        return (Stream.concat(mods.stream().map(e -> e.toString()
+                                                      .toLowerCase(Locale.ROOT)),
                               Stream.of(what)))
                 .collect(Collectors.joining(" "));
     }
--- a/src/java.base/share/classes/java/net/URLClassLoader.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/net/URLClassLoader.java	Wed Dec 13 10:56:50 2017 -0800
@@ -658,8 +658,8 @@
      *
      * @param name the resource name
      * @exception IOException if an I/O exception occurs
-     * @return an {@code Enumeration} of {@code URL}s
-     *         If the loader is closed, the Enumeration will be empty.
+     * @return An {@code Enumeration} of {@code URL}s.
+     *         If the loader is closed, the Enumeration contains no elements.
      */
     public Enumeration<URL> findResources(final String name)
         throws IOException
--- a/src/java.base/share/classes/java/net/URLDecoder.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/net/URLDecoder.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,10 @@
 package java.net;
 
 import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Objects;
 
 /**
  * Utility class for HTML form decoding. This class contains static methods
@@ -108,7 +112,43 @@
     /**
      * Decodes an {@code application/x-www-form-urlencoded} string using
      * a specific encoding scheme.
-     * The supplied encoding is used to determine
+     *
+     * <p>
+     * This method behaves the same as {@linkplain decode(String s, Charset charset)}
+     * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset}
+     * using the given encoding name.
+     *
+     * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException}
+     * when illegal strings are encountered.
+     *
+     * @param s the {@code String} to decode
+     * @param enc   The name of a supported
+     *    <a href="../lang/package-summary.html#charenc">character
+     *    encoding</a>.
+     * @return the newly decoded {@code String}
+     * @throws UnsupportedEncodingException
+     *             If character encoding needs to be consulted, but
+     *             named character encoding is not supported
+     * @see URLEncoder#encode(java.lang.String, java.lang.String)
+     * @since 1.4
+     */
+    public static String decode(String s, String enc) throws UnsupportedEncodingException {
+        if (enc.length() == 0) {
+            throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
+        }
+
+        try {
+            Charset charset = Charset.forName(enc);
+            return decode(s, charset);
+        } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+            throw new UnsupportedEncodingException(enc);
+        }
+    }
+
+    /**
+     * Decodes an {@code application/x-www-form-urlencoded} string using
+     * a specific {@linkplain java.nio.charset.Charset Charset}.
+     * The supplied charset is used to determine
      * what characters are represented by any consecutive sequences of the
      * form "<i>{@code %xy}</i>".
      * <p>
@@ -118,29 +158,25 @@
      * UTF-8 should be used. Not doing so may introduce
      * incompatibilities.</em>
      *
+     * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException}
+     * when illegal strings are encountered.
+     *
      * @param s the {@code String} to decode
-     * @param enc   The name of a supported
-     *    <a href="../lang/package-summary.html#charenc">character
-     *    encoding</a>.
+     * @param charset the given charset
      * @return the newly decoded {@code String}
-     * @exception  UnsupportedEncodingException
-     *             If character encoding needs to be consulted, but
-     *             named character encoding is not supported
-     * @see URLEncoder#encode(java.lang.String, java.lang.String)
-     * @since 1.4
+     * @throws NullPointerException if {@code s} or {@code charset} is {@code null}
+     * @throws IllegalArgumentException if the implementation encounters illegal
+     * characters
+     * @see URLEncoder#encode(java.lang.String, java.nio.charset.Charset)
+     * @since 10
      */
-    public static String decode(String s, String enc)
-        throws UnsupportedEncodingException{
-
+    public static String decode(String s, Charset charset) {
+        Objects.requireNonNull(charset, "Charset");
         boolean needToChange = false;
         int numChars = s.length();
         StringBuilder sb = new StringBuilder(numChars > 500 ? numChars / 2 : numChars);
         int i = 0;
 
-        if (enc.length() == 0) {
-            throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
-        }
-
         char c;
         byte[] bytes = null;
         while (i < numChars) {
@@ -173,7 +209,9 @@
                             (c=='%')) {
                         int v = Integer.parseInt(s, i + 1, i + 3, 16);
                         if (v < 0)
-                            throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value");
+                            throw new IllegalArgumentException(
+                                    "URLDecoder: Illegal hex characters in escape "
+                                            + "(%) pattern - negative value");
                         bytes[pos++] = (byte) v;
                         i+= 3;
                         if (i < numChars)
@@ -187,7 +225,7 @@
                         throw new IllegalArgumentException(
                          "URLDecoder: Incomplete trailing escape (%) pattern");
 
-                    sb.append(new String(bytes, 0, pos, enc));
+                    sb.append(new String(bytes, 0, pos, charset));
                 } catch (NumberFormatException e) {
                     throw new IllegalArgumentException(
                     "URLDecoder: Illegal hex characters in escape (%) pattern - "
--- a/src/java.base/share/classes/java/net/URLEncoder.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/net/URLEncoder.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException ;
 import java.util.BitSet;
+import java.util.Objects;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -168,45 +169,61 @@
 
     /**
      * Translates a string into {@code application/x-www-form-urlencoded}
-     * format using a specific encoding scheme. This method uses the
-     * supplied encoding scheme to obtain the bytes for unsafe
-     * characters.
+     * format using a specific encoding scheme.
      * <p>
-     * <em><strong>Note:</strong> The <a href=
-     * "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
-     * World Wide Web Consortium Recommendation</a> states that
-     * UTF-8 should be used. Not doing so may introduce
-     * incompatibilities.</em>
+     * This method behaves the same as {@linkplain encode(String s, Charset charset)}
+     * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset}
+     * using the given encoding name.
      *
      * @param   s   {@code String} to be translated.
      * @param   enc   The name of a supported
      *    <a href="../lang/package-summary.html#charenc">character
      *    encoding</a>.
      * @return  the translated {@code String}.
-     * @exception  UnsupportedEncodingException
+     * @throws  UnsupportedEncodingException
      *             If the named encoding is not supported
      * @see URLDecoder#decode(java.lang.String, java.lang.String)
      * @since 1.4
      */
     public static String encode(String s, String enc)
         throws UnsupportedEncodingException {
+        if (enc == null) {
+            throw new NullPointerException("charsetName");
+        }
+
+        try {
+            Charset charset = Charset.forName(enc);
+            return encode(s, charset);
+        } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+            throw new UnsupportedEncodingException(enc);
+        }
+    }
+
+    /**
+     * Translates a string into {@code application/x-www-form-urlencoded}
+     * format using a specific {@linkplain java.nio.charset.Charset Charset}.
+     * This method uses the supplied charset to obtain the bytes for unsafe
+     * characters.
+     * <p>
+     * <em><strong>Note:</strong> The <a href=
+     * "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
+     * World Wide Web Consortium Recommendation</a> states that
+     * UTF-8 should be used. Not doing so may introduce incompatibilities.</em>
+     *
+     * @param   s   {@code String} to be translated.
+     * @param charset the given charset
+     * @return  the translated {@code String}.
+     * @throws NullPointerException if {@code s} or {@code charset} is {@code null}.
+     * @see URLDecoder#decode(java.lang.String, java.nio.charset.Charset)
+     * @since 10
+     */
+    public static String encode(String s, Charset charset) {
+        Objects.requireNonNull(charset, "charset");
 
         boolean needToChange = false;
         StringBuilder out = new StringBuilder(s.length());
-        Charset charset;
         CharArrayWriter charArrayWriter = new CharArrayWriter();
 
-        if (enc == null)
-            throw new NullPointerException("charsetName");
-
-        try {
-            charset = Charset.forName(enc);
-        } catch (IllegalCharsetNameException e) {
-            throw new UnsupportedEncodingException(enc);
-        } catch (UnsupportedCharsetException e) {
-            throw new UnsupportedEncodingException(enc);
-        }
-
         for (int i = 0; i < s.length();) {
             int c = (int) s.charAt(i);
             //System.out.println("Examining character: " + c);
--- a/src/java.base/share/classes/java/net/URLStreamHandler.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/net/URLStreamHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -480,39 +480,14 @@
      * @return  a string representation of the {@code URL} argument.
      */
     protected String toExternalForm(URL u) {
-
-        // pre-compute length of StringBuffer
-        int len = u.getProtocol().length() + 1;
-        if (u.getAuthority() != null && u.getAuthority().length() > 0)
-            len += 2 + u.getAuthority().length();
-        if (u.getPath() != null) {
-            len += u.getPath().length();
-        }
-        if (u.getQuery() != null) {
-            len += 1 + u.getQuery().length();
-        }
-        if (u.getRef() != null)
-            len += 1 + u.getRef().length();
-
-        StringBuilder result = new StringBuilder(len);
-        result.append(u.getProtocol());
-        result.append(":");
-        if (u.getAuthority() != null && u.getAuthority().length() > 0) {
-            result.append("//");
-            result.append(u.getAuthority());
-        }
-        if (u.getPath() != null) {
-            result.append(u.getPath());
-        }
-        if (u.getQuery() != null) {
-            result.append('?');
-            result.append(u.getQuery());
-        }
-        if (u.getRef() != null) {
-            result.append("#");
-            result.append(u.getRef());
-        }
-        return result.toString();
+        String s;
+        return u.getProtocol()
+            + ':'
+            + (((s = u.getAuthority()) != null && s.length() > 0)
+               ? "//" + s : "")
+            + (((s = u.getPath()) != null) ? s : "")
+            + (((s = u.getQuery()) != null) ? '?' + s : "")
+            + (((s = u.getRef()) != null) ? '#' + s : "");
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/channels/Channels.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/nio/channels/Channels.java	Wed Dec 13 10:56:50 2017 -0800
@@ -527,7 +527,7 @@
      * behaves in exactly the same way as the expression
      *
      * <pre> {@code
-     *     Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
+     *     Channels.newReader(ch, Charset.forName(csName))
      * } </pre>
      *
      * @param  ch
@@ -550,6 +550,38 @@
     }
 
     /**
+     * Constructs a reader that decodes bytes from the given channel according
+     * to the given charset.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <pre> {@code
+     *     Channels.newReader(ch, charset)
+     * } </pre>
+     *
+     * behaves in exactly the same way as the expression
+     *
+     * <pre> {@code
+     *     Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
+     * } </pre>
+     *
+     * <p> The reader's default action for malformed-input and unmappable-character
+     * errors is to {@linkplain java.nio.charset.CodingErrorAction#REPORT report}
+     * them. When more control over the error handling is required, the constructor
+     * that takes a {@linkplain java.nio.charset.CharsetDecoder} should be used.
+     *
+     * @param  ch The channel from which bytes will be read
+     *
+     * @param  charset The charset to be used
+     *
+     * @return  A new reader
+     */
+    public static Reader newReader(ReadableByteChannel ch, Charset charset) {
+        Objects.requireNonNull(charset, "charset");
+        return newReader(ch, charset.newDecoder(), -1);
+    }
+
+    /**
      * Constructs a writer that encodes characters using the given encoder and
      * writes the resulting bytes to the given channel.
      *
@@ -595,7 +627,7 @@
      * behaves in exactly the same way as the expression
      *
      * <pre> {@code
-     *     Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
+     *     Channels.newWriter(ch, Charset.forName(csName))
      * } </pre>
      *
      * @param  ch
@@ -616,4 +648,38 @@
         Objects.requireNonNull(csName, "csName");
         return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
     }
+
+    /**
+     * Constructs a writer that encodes characters according to the given
+     * charset and writes the resulting bytes to the given channel.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <pre> {@code
+     *     Channels.newWriter(ch, charset)
+     * } </pre>
+     *
+     * behaves in exactly the same way as the expression
+     *
+     * <pre> {@code
+     *     Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
+     * } </pre>
+     *
+     * <p> The writer's default action for malformed-input and unmappable-character
+     * errors is to {@linkplain java.nio.charset.CodingErrorAction#REPORT report}
+     * them. When more control over the error handling is required, the constructor
+     * that takes a {@linkplain java.nio.charset.CharsetEncoder} should be used.
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @param  charset
+     *         The charset to be used
+     *
+     * @return  A new writer
+     */
+    public static Writer newWriter(WritableByteChannel ch, Charset charset) {
+        Objects.requireNonNull(charset, "charset");
+        return newWriter(ch, charset.newEncoder(), -1);
 }
+}
--- a/src/java.base/share/classes/java/text/DateFormat.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/text/DateFormat.java	Wed Dec 13 10:56:50 2017 -0800
@@ -97,6 +97,13 @@
  * DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
  * }</pre>
  * </blockquote>
+ *
+ * <p>If the specified locale contains "ca" (calendar), "rg" (region override),
+ * and/or "tz" (timezone) <a href="../util/Locale.html#def_locale_extension">Unicode
+ * extensions</a>, the calendar, the country and/or the time zone for formatting
+ * are overridden. If both "ca" and "rg" are specified, the calendar from the "ca"
+ * extension supersedes the implicit one from the "rg" extension.
+ *
  * <p>You can use a DateFormat to parse also.
  * <blockquote>
  * <pre>{@code
--- a/src/java.base/share/classes/java/text/DateFormatSymbols.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/text/DateFormatSymbols.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
 import java.util.ResourceBundle;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleServiceProviderPool;
 import sun.util.locale.provider.ResourceBundleBasedAdapter;
@@ -82,6 +83,10 @@
  * </pre>
  * </blockquote>
  *
+ * <p>If the locale contains "rg" (region override)
+ * <a href="../util/Locale.html#def_locale_extension">Unicode extension</a>,
+ * the symbols are overridden for the designated region.
+ *
  * <p>
  * <code>DateFormatSymbols</code> objects are cloneable. When you obtain
  * a <code>DateFormatSymbols</code> object, feel free to modify the
@@ -716,15 +721,18 @@
             }
             dfs = new DateFormatSymbols(false);
 
+            // check for region override
+            Locale override = CalendarDataUtility.findRegionOverride(locale);
+
             // Initialize the fields from the ResourceBundle for locale.
             LocaleProviderAdapter adapter
-                = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale);
+                = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, override);
             // Avoid any potential recursions
             if (!(adapter instanceof ResourceBundleBasedAdapter)) {
                 adapter = LocaleProviderAdapter.getResourceBundleBased();
             }
             ResourceBundle resource
-                = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale);
+                = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(override);
 
             dfs.locale = locale;
             // JRE and CLDR use different keys
--- a/src/java.base/share/classes/java/text/DecimalFormatSymbols.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/text/DecimalFormatSymbols.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
 import java.text.spi.DecimalFormatSymbolsProvider;
 import java.util.Currency;
 import java.util.Locale;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleServiceProviderPool;
 import sun.util.locale.provider.ResourceBundleBasedAdapter;
@@ -56,6 +57,10 @@
  * of these symbols, you can get the <code>DecimalFormatSymbols</code> object from
  * your <code>DecimalFormat</code> and modify it.
  *
+ * <p>If the locale contains "rg" (region override)
+ * <a href="../util/Locale.html#def_locale_extension">Unicode extension</a>,
+ * the symbols are overridden for the designated region.
+ *
  * @see          java.util.Locale
  * @see          DecimalFormat
  * @author       Mark Davis
@@ -609,13 +614,18 @@
     private void initialize( Locale locale ) {
         this.locale = locale;
 
+        // check for region override
+        Locale override = locale.getUnicodeLocaleType("nu") == null ?
+            CalendarDataUtility.findRegionOverride(locale) :
+            locale;
+
         // get resource bundle data
-        LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale);
+        LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, override);
         // Avoid potential recursions
         if (!(adapter instanceof ResourceBundleBasedAdapter)) {
             adapter = LocaleProviderAdapter.getResourceBundleBased();
         }
-        Object[] data = adapter.getLocaleResources(locale).getDecimalFormatSymbolsData();
+        Object[] data = adapter.getLocaleResources(override).getDecimalFormatSymbolsData();
         String[] numberElements = (String[]) data[0];
 
         decimalSeparator = numberElements[0].charAt(0);
--- a/src/java.base/share/classes/java/text/NumberFormat.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/text/NumberFormat.java	Wed Dec 13 10:56:50 2017 -0800
@@ -96,7 +96,14 @@
  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
  * }</pre>
  * </blockquote>
- * You can also use a <code>NumberFormat</code> to parse numbers:
+ *
+ * <p>If the locale contains "nu" (numbers) and/or "rg" (region override)
+ * <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>,
+ * the decimal digits, and/or the country used for formatting are overridden.
+ * If both "nu" and "rg" are specified, the decimal digits from the "nu"
+ * extension supersedes the implicit one from the "rg" extension.
+ *
+ * <p>You can also use a {@code NumberFormat} to parse numbers:
  * <blockquote>
  * <pre>{@code
  * myNumber = nf.parse(myString);
--- a/src/java.base/share/classes/java/text/SimpleDateFormat.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/text/SimpleDateFormat.java	Wed Dec 13 10:56:50 2017 -0800
@@ -672,7 +672,7 @@
             // However, the calendar should use the current default TimeZone.
             // If this is not contained in the locale zone strings, then the zone
             // will be formatted using generic GMT+/-H:MM nomenclature.
-            calendar = Calendar.getInstance(TimeZone.getDefault(), loc);
+            calendar = Calendar.getInstance(loc);
         }
     }
 
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -97,6 +97,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import sun.util.locale.provider.TimeZoneNameUtility;
 
 /**
  * Formatter for printing and parsing date-time objects.
@@ -548,7 +549,7 @@
      * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.
      * <p>
      * The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
+     * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter.
      * Alternatively use the {@link #ofPattern(String, Locale)} variant of this method.
      * <p>
      * The returned formatter has no override chronology or zone.
@@ -572,7 +573,7 @@
      * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.
      * <p>
      * The formatter will use the specified locale.
-     * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
+     * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter.
      * <p>
      * The returned formatter has no override chronology or zone.
      * It uses {@link ResolverStyle#SMART SMART} resolver style.
@@ -1443,10 +1444,17 @@
      * This is used to lookup any part of the formatter needing specific
      * localization, such as the text or localized pattern.
      * <p>
+     * The locale is stored as passed in, without further processing.
+     * If the locale has <a href="../../util/Locale.html#def_locale_extension">
+     * Unicode extensions</a>, they may be used later in text
+     * processing. To set the chronology, time-zone and decimal style from
+     * unicode extensions, see {@link #localizedBy localizedBy()}.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param locale  the new locale, not null
      * @return a formatter based on this formatter with the requested locale, not null
+     * @see #localizedBy(Locale)
      */
     public DateTimeFormatter withLocale(Locale locale) {
         if (this.locale.equals(locale)) {
@@ -1455,6 +1463,52 @@
         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
     }
 
+    /**
+     * Returns a copy of this formatter with localized values of the locale,
+     * calendar, region, decimal style and/or timezone, that supercede values in
+     * this formatter.
+     * <p>
+     * This is used to lookup any part of the formatter needing specific
+     * localization, such as the text or localized pattern. If the locale contains the
+     * "ca" (calendar), "nu" (numbering system), "rg" (region override), and/or
+     * "tz" (timezone)
+     * <a href="../../util/Locale.html#def_locale_extension">Unicode extensions</a>,
+     * the chronology, numbering system and/or the zone are overridden. If both "ca"
+     * and "rg" are specified, the chronology from the "ca" extension supersedes the
+     * implicit one from the "rg" extension. Same is true for the "nu" extension.
+     * <p>
+     * Unlike the {@link #withLocale withLocale} method, the call to this method may
+     * produce a different formatter depending on the order of method chaining with
+     * other withXXXX() methods.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param locale  the locale, not null
+     * @return a formatter based on this formatter with localized values of
+     *      the calendar, decimal style and/or timezone, that supercede values in this
+     *      formatter.
+     * @see #withLocale(Locale)
+     * @since 10
+     */
+    public DateTimeFormatter localizedBy(Locale locale) {
+        if (this.locale.equals(locale)) {
+            return this;
+        }
+
+        // Check for decimalStyle/chronology/timezone in locale object
+        Chronology c = locale.getUnicodeLocaleType("ca") != null ?
+                       Chronology.ofLocale(locale) : chrono;
+        DecimalStyle ds = locale.getUnicodeLocaleType("nu") != null ?
+                       DecimalStyle.of(locale) : decimalStyle;
+        String tzType = locale.getUnicodeLocaleType("tz");
+        ZoneId z  = tzType != null ?
+                    TimeZoneNameUtility.convertLDMLShortID(tzType)
+                        .map(ZoneId::of)
+                        .orElse(zone) :
+                    zone;
+        return new DateTimeFormatter(printerParser, locale, ds, resolverStyle, resolverFields, c, z);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Gets the DecimalStyle to be used during formatting.
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,6 +120,7 @@
 import java.util.concurrent.ConcurrentMap;
 
 import sun.text.spi.JavaTimeDateTimePatternProvider;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 import sun.util.locale.provider.TimeZoneNameUtility;
@@ -198,6 +199,10 @@
      * Gets the formatting pattern for date and time styles for a locale and chronology.
      * The locale and chronology are used to lookup the locale specific format
      * for the requested dateStyle and/or timeStyle.
+     * <p>
+     * If the locale contains the "rg" (region override)
+     * <a href="../../util/Locale.html#def_locale_extension">Unicode extensions</a>,
+     * the formatting pattern is overridden with the one appropriate for the region.
      *
      * @param dateStyle  the FormatStyle for the date, null for time-only pattern
      * @param timeStyle  the FormatStyle for the time, null for date-only pattern
@@ -216,7 +221,8 @@
         LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(JavaTimeDateTimePatternProvider.class, locale);
         JavaTimeDateTimePatternProvider provider = adapter.getJavaTimeDateTimePatternProvider();
         String pattern = provider.getJavaTimeDateTimePattern(convertStyle(timeStyle),
-                         convertStyle(dateStyle), chrono.getCalendarType(), locale);
+                         convertStyle(dateStyle), chrono.getCalendarType(),
+                         CalendarDataUtility.findRegionOverride(locale));
         return pattern;
     }
 
--- a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java	Wed Dec 13 10:56:50 2017 -0800
@@ -510,7 +510,8 @@
     @SuppressWarnings("unchecked")
     static <T> T getLocalizedResource(String key, Locale locale) {
         LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
-                                    .getLocaleResources(locale);
+                                    .getLocaleResources(
+                                        CalendarDataUtility.findRegionOverride(locale));
         ResourceBundle rb = lr.getJavaTimeFormatData();
         return rb.containsKey(key) ? (T) rb.getObject(key) : null;
     }
--- a/src/java.base/share/classes/java/time/format/DecimalStyle.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/format/DecimalStyle.java	Wed Dec 13 10:56:50 2017 -0800
@@ -147,6 +147,11 @@
      * Obtains the DecimalStyle for the specified locale.
      * <p>
      * This method provides access to locale sensitive decimal style symbols.
+     * If the locale contains "nu" (Numbering System) and/or "rg"
+     * (Region Override) <a href="../../util/Locale.html#def_locale_extension">
+     * Unicode extensions</a>, returned instance will reflect the values specified with
+     * those extensions. If both "nu" and "rg" are specified, the value from
+     * the "nu" extension supersedes the implicit one from the "rg" extension.
      *
      * @param locale  the locale, not null
      * @return the decimal style, not null
--- a/src/java.base/share/classes/java/time/temporal/ChronoField.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/temporal/ChronoField.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,7 @@
 import java.util.Locale;
 import java.util.Objects;
 import java.util.ResourceBundle;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 
@@ -632,7 +633,9 @@
         }
 
         LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
-                                    .getLocaleResources(locale);
+                                    .getLocaleResources(
+                                        CalendarDataUtility
+                                            .findRegionOverride(locale));
         ResourceBundle rb = lr.getJavaTimeFormatData();
         String key = "field." + displayNameKey;
         return rb.containsKey(key) ? rb.getString(key) : name;
--- a/src/java.base/share/classes/java/time/temporal/IsoFields.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/temporal/IsoFields.java	Wed Dec 13 10:56:50 2017 -0800
@@ -81,6 +81,7 @@
 import java.util.Objects;
 import java.util.ResourceBundle;
 
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 
@@ -430,7 +431,9 @@
             public String getDisplayName(Locale locale) {
                 Objects.requireNonNull(locale, "locale");
                 LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
-                                            .getLocaleResources(locale);
+                                            .getLocaleResources(
+                                                CalendarDataUtility
+                                                    .findRegionOverride(locale));
                 ResourceBundle rb = lr.getJavaTimeFormatData();
                 return rb.containsKey("field.week") ? rb.getString("field.week") : toString();
             }
--- a/src/java.base/share/classes/java/time/temporal/WeekFields.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java	Wed Dec 13 10:56:50 2017 -0800
@@ -286,13 +286,17 @@
      * Obtains an instance of {@code WeekFields} appropriate for a locale.
      * <p>
      * This will look up appropriate values from the provider of localization data.
+     * If the locale contains "fw" (First day of week) and/or "rg"
+     * (Region Override) <a href="../../util/Locale.html#def_locale_extension">
+     * Unicode extensions</a>, returned instance will reflect the values specified with
+     * those extensions. If both "fw" and "rg" are specified, the value from
+     * the "fw" extension supersedes the implicit one from the "rg" extension.
      *
      * @param locale  the locale to use, not null
      * @return the week-definition, not null
      */
     public static WeekFields of(Locale locale) {
         Objects.requireNonNull(locale, "locale");
-        locale = new Locale(locale.getLanguage(), locale.getCountry());  // elminate variants
 
         int calDow = CalendarDataUtility.retrieveFirstDayOfWeek(locale);
         DayOfWeek dow = DayOfWeek.SUNDAY.plus(calDow - 1);
@@ -1041,7 +1045,8 @@
             Objects.requireNonNull(locale, "locale");
             if (rangeUnit == YEARS) {  // only have values for week-of-year
                 LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
-                        .getLocaleResources(locale);
+                        .getLocaleResources(
+                            CalendarDataUtility.findRegionOverride(locale));
                 ResourceBundle rb = lr.getJavaTimeFormatData();
                 return rb.containsKey("field.week") ? rb.getString("field.week") : name;
             }
--- a/src/java.base/share/classes/java/util/Calendar.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Calendar.java	Wed Dec 13 10:56:50 2017 -0800
@@ -58,6 +58,7 @@
 import sun.util.calendar.ZoneInfo;
 import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.TimeZoneNameUtility;
 import sun.util.spi.CalendarProvider;
 
 /**
@@ -128,9 +129,14 @@
  *
  * <code>Calendar</code> defines a locale-specific seven day week using two
  * parameters: the first day of the week and the minimal days in first week
- * (from 1 to 7).  These numbers are taken from the locale resource data when a
- * <code>Calendar</code> is constructed.  They may also be specified explicitly
- * through the methods for setting their values.
+ * (from 1 to 7).  These numbers are taken from the locale resource data or the
+ * locale itself when a {@code Calendar} is constructed. If the designated
+ * locale contains "fw" and/or "rg" <a href="./Locale.html#def_locale_extension">
+ * Unicode extensions</a>, the first day of the week will be obtained according to
+ * those extensions. If both "fw" and "rg" are specified, the value from the "fw"
+ * extension supersedes the implicit one from the "rg" extension.
+ * They may also be specified explicitly through the methods for setting their
+ * values.
  *
  * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
  * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
@@ -1444,6 +1450,11 @@
          *
          * <p>The default values are used for locale and time zone if these
          * parameters haven't been given explicitly.
+         * <p>
+         * If the locale contains the time zone with "tz"
+         * <a href="Locale.html#def_locale_extension">Unicode extension</a>,
+         * and time zone hasn't been given explicitly, time zone in the locale
+         * is used.
          *
          * <p>Any out of range field values are either normalized in lenient
          * mode or detected as an invalid value in non-lenient mode.
@@ -1463,7 +1474,7 @@
                 locale = Locale.getDefault();
             }
             if (zone == null) {
-                zone = TimeZone.getDefault();
+                zone = defaultTimeZone(locale);
             }
             Calendar cal;
             if (type == null) {
@@ -1605,12 +1616,17 @@
      * <code>Calendar</code> returned is based on the current time
      * in the default time zone with the default
      * {@link Locale.Category#FORMAT FORMAT} locale.
+     * <p>
+     * If the locale contains the time zone with "tz"
+     * <a href="Locale.html#def_locale_extension">Unicode extension</a>,
+     * that time zone is used instead.
      *
      * @return a Calendar.
      */
     public static Calendar getInstance()
     {
-        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
+        Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
+        return createCalendar(defaultTimeZone(aLocale), aLocale);
     }
 
     /**
@@ -1631,13 +1647,17 @@
      * Gets a calendar using the default time zone and specified locale.
      * The <code>Calendar</code> returned is based on the current time
      * in the default time zone with the given locale.
+     * <p>
+     * If the locale contains the time zone with "tz"
+     * <a href="Locale.html#def_locale_extension">Unicode extension</a>,
+     * that time zone is used instead.
      *
      * @param aLocale the locale for the week data
      * @return a Calendar.
      */
     public static Calendar getInstance(Locale aLocale)
     {
-        return createCalendar(TimeZone.getDefault(), aLocale);
+        return createCalendar(defaultTimeZone(aLocale), aLocale);
     }
 
     /**
@@ -1655,6 +1675,16 @@
         return createCalendar(zone, aLocale);
     }
 
+    private static TimeZone defaultTimeZone(Locale l) {
+        TimeZone defaultTZ = TimeZone.getDefault();
+        String shortTZID = l.getUnicodeLocaleType("tz");
+        return shortTZID != null ?
+            TimeZoneNameUtility.convertLDMLShortID(shortTZID)
+                .map(TimeZone::getTimeZone)
+                .orElse(defaultTZ) :
+            defaultTZ;
+    }
+
     private static Calendar createCalendar(TimeZone zone,
                                            Locale aLocale)
     {
--- a/src/java.base/share/classes/java/util/Collections.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Collections.java	Wed Dec 13 10:56:50 2017 -0800
@@ -24,9 +24,10 @@
  */
 
 package java.util;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
 import java.lang.reflect.Array;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
@@ -5164,14 +5165,19 @@
      *         specified comparator.
      * @since 1.5
      */
+    @SuppressWarnings("unchecked")
     public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
-        if (cmp == null)
-            return reverseOrder();
-
-        if (cmp instanceof ReverseComparator2)
-            return ((ReverseComparator2<T>)cmp).cmp;
-
-        return new ReverseComparator2<>(cmp);
+        if (cmp == null) {
+            return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
+        } else if (cmp == ReverseComparator.REVERSE_ORDER) {
+            return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
+        } else if (cmp == Comparators.NaturalOrderComparator.INSTANCE) {
+            return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
+        } else if (cmp instanceof ReverseComparator2) {
+            return ((ReverseComparator2<T>) cmp).cmp;
+        } else {
+            return new ReverseComparator2<>(cmp);
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/util/Currency.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Currency.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import java.io.BufferedInputStream;
 import java.io.DataInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.InputStream;
 import java.io.IOException;
@@ -42,6 +41,7 @@
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import java.util.spi.CurrencyNameProvider;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleServiceProviderPool;
 import sun.util.logging.PlatformLogger;
 
@@ -348,6 +348,13 @@
      * until December 31, 2001, and the Euro from January 1, 2002, local time
      * of the respective countries.
      * <p>
+     * If the specified {@code locale} contains "cu" and/or "rg"
+     * <a href="./Locale.html#def_locale_extension">Unicode extensions</a>,
+     * the instance returned from this method reflects
+     * the values specified with those extensions. If both "cu" and "rg" are
+     * specified, the currency from the "cu" extension supersedes the implicit one
+     * from the "rg" extension.
+     * <p>
      * The method returns <code>null</code> for territories that don't
      * have a currency, such as Antarctica.
      *
@@ -361,12 +368,19 @@
      * is not a supported ISO 3166 country code.
      */
     public static Currency getInstance(Locale locale) {
-        String country = locale.getCountry();
-        if (country == null) {
-            throw new NullPointerException();
+        // check for locale overrides
+        String override = locale.getUnicodeLocaleType("cu");
+        if (override != null) {
+            try {
+                return getInstance(override.toUpperCase(Locale.ROOT));
+            } catch (IllegalArgumentException iae) {
+                // override currency is invalid. Fall through.
+            }
         }
 
-        if (country.length() != 2) {
+        String country = CalendarDataUtility.findRegionOverride(locale).getCountry();
+
+        if (country == null || !country.matches("^[a-zA-Z]{2}$")) {
             throw new IllegalArgumentException();
         }
 
@@ -482,6 +496,12 @@
      * locale is the US, while for other locales it may be "US$". If no
      * symbol can be determined, the ISO 4217 currency code is returned.
      * <p>
+     * If the default {@link Locale.Category#DISPLAY DISPLAY} locale
+     * contains "rg" (region override)
+     * <a href="./Locale.html#def_locale_extension">Unicode extension</a>,
+     * the symbol returned from this method reflects
+     * the value specified with that extension.
+     * <p>
      * This is equivalent to calling
      * {@link #getSymbol(Locale)
      *     getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}.
@@ -498,6 +518,11 @@
      * For example, for the US Dollar, the symbol is "$" if the specified
      * locale is the US, while for other locales it may be "US$". If no
      * symbol can be determined, the ISO 4217 currency code is returned.
+     * <p>
+     * If the specified {@code locale} contains "rg" (region override)
+     * <a href="./Locale.html#def_locale_extension">Unicode extension</a>,
+     * the symbol returned from this method reflects
+     * the value specified with that extension.
      *
      * @param locale the locale for which a display name for this currency is
      * needed
@@ -507,6 +532,7 @@
     public String getSymbol(Locale locale) {
         LocaleServiceProviderPool pool =
             LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
+        locale = CalendarDataUtility.findRegionOverride(locale);
         String symbol = pool.getLocalizedObject(
                                 CurrencyNameGetter.INSTANCE,
                                 locale, currencyCode, SYMBOL);
--- a/src/java.base/share/classes/java/util/Formatter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Formatter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -2137,6 +2137,39 @@
     }
 
     /**
+     * Constructs a new formatter with the specified file name, charset, and
+     * locale.
+     *
+     * @param  fileName
+     *         The name of the file to use as the destination of this
+     *         formatter.  If the file exists then it will be truncated to
+     *         zero size; otherwise, a new file will be created.  The output
+     *         will be written to the file and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @param  l
+     *         The {@linkplain java.util.Locale locale} to apply during
+     *         formatting.  If {@code l} is {@code null} then no localization
+     *         is applied.
+     *
+     * @throws  IOException
+     *          if an I/O error occurs while opening or creating the file
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and {@link
+     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
+     *          access to the file
+     *
+     * @throws NullPointerException
+     *         if {@code fileName} or {@code charset} is {@code null}.
+     */
+    public Formatter(String fileName, Charset charset, Locale l) throws IOException {
+        this(Objects.requireNonNull(charset, "charset"), l, new File(fileName));
+    }
+
+    /**
      * Constructs a new formatter with the specified file.
      *
      * <p> The charset used is the {@linkplain
@@ -2248,6 +2281,40 @@
     }
 
     /**
+     * Constructs a new formatter with the specified file, charset, and
+     * locale.
+     *
+     * @param  file
+     *         The file to use as the destination of this formatter.  If the
+     *         file exists then it will be truncated to zero size; otherwise,
+     *         a new file will be created.  The output will be written to the
+     *         file and is buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @param  l
+     *         The {@linkplain java.util.Locale locale} to apply during
+     *         formatting.  If {@code l} is {@code null} then no localization
+     *         is applied.
+     *
+     * @throws IOException
+     *         if an I/O error occurs while opening or creating the file
+     *
+     * @throws SecurityException
+     *         If a security manager is present and {@link
+     *         SecurityManager#checkWrite checkWrite(file.getPath())} denies
+     *         write access to the file
+     *
+     * @throws NullPointerException
+     *         if {@code file} or {@code charset} is {@code null}.
+     */
+    public Formatter(File file, Charset charset, Locale l) throws IOException {
+        this(Objects.requireNonNull(charset, "charset"), l, file);
+    }
+
+
+    /**
      * Constructs a new formatter with the specified print stream.
      *
      * <p> The locale used is the {@linkplain
@@ -2340,6 +2407,29 @@
         this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
     }
 
+    /**
+     * Constructs a new formatter with the specified output stream, charset,
+     * and locale.
+     *
+     * @param  os
+     *         The output stream to use as the destination of this formatter.
+     *         The output will be buffered.
+     *
+     * @param  charset
+     *         A {@linkplain java.nio.charset.Charset charset}
+     *
+     * @param  l
+     *         The {@linkplain java.util.Locale locale} to apply during
+     *         formatting.  If {@code l} is {@code null} then no localization
+     *         is applied.
+     *
+     * @throws NullPointerException
+     *         if {@code os} or {@code charset} is {@code null}.
+     */
+    public Formatter(OutputStream os, Charset charset, Locale l) {
+        this(l, new BufferedWriter(new OutputStreamWriter(os, charset)));
+    }
+
     private static char getZero(Locale l) {
         if ((l != null) && !l.equals(Locale.US)) {
             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
--- a/src/java.base/share/classes/java/util/Locale.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Locale.java	Wed Dec 13 10:56:50 2017 -0800
@@ -48,6 +48,7 @@
 import java.text.MessageFormat;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.spi.LocaleNameProvider;
+import java.util.stream.Collectors;
 
 import sun.security.action.GetPropertyAction;
 import sun.util.locale.BaseLocale;
@@ -62,6 +63,7 @@
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 import sun.util.locale.provider.LocaleServiceProviderPool;
+import sun.util.locale.provider.TimeZoneNameUtility;
 
 /**
  * A <code>Locale</code> object represents a specific geographical, political,
@@ -665,10 +667,12 @@
     /**
      * Display types for retrieving localized names from the name providers.
      */
-    private static final int DISPLAY_LANGUAGE = 0;
-    private static final int DISPLAY_COUNTRY  = 1;
-    private static final int DISPLAY_VARIANT  = 2;
-    private static final int DISPLAY_SCRIPT   = 3;
+    private static final int DISPLAY_LANGUAGE  = 0;
+    private static final int DISPLAY_COUNTRY   = 1;
+    private static final int DISPLAY_VARIANT   = 2;
+    private static final int DISPLAY_SCRIPT    = 3;
+    private static final int DISPLAY_UEXT_KEY  = 4;
+    private static final int DISPLAY_UEXT_TYPE = 5;
 
     /**
      * Private constructor used by getInstance method
@@ -942,11 +946,14 @@
             variant = props.getProperty("user.variant", "");
         }
 
-        return getInstance(language, script, country, variant, null);
+        return getInstance(language, script, country, variant,
+                getDefaultExtensions(props.getProperty("user.extensions", ""))
+                    .orElse(null));
     }
 
     private static Locale initDefault(Locale.Category category) {
         Properties props = GetPropertyAction.privilegedGetProperties();
+
         return getInstance(
             props.getProperty(category.languageKey,
                     defaultLocale.getLanguage()),
@@ -956,7 +963,22 @@
                     defaultLocale.getCountry()),
             props.getProperty(category.variantKey,
                     defaultLocale.getVariant()),
-            null);
+            getDefaultExtensions(props.getProperty(category.extensionsKey, ""))
+                .orElse(defaultLocale.getLocaleExtensions()));
+    }
+
+    private static Optional<LocaleExtensions> getDefaultExtensions(String extensionsProp) {
+        LocaleExtensions exts = null;
+
+        try {
+            exts = new InternalLocaleBuilder()
+                .setExtensions(extensionsProp)
+                .getLocaleExtensions();
+        } catch (LocaleSyntaxException e) {
+            // just ignore this incorrect property
+        }
+
+        return Optional.ofNullable(exts);
     }
 
     /**
@@ -1771,7 +1793,7 @@
      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
      */
     public String getDisplayLanguage(Locale inLocale) {
-        return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
+        return getDisplayString(baseLocale.getLanguage(), null, inLocale, DISPLAY_LANGUAGE);
     }
 
     /**
@@ -1801,7 +1823,7 @@
      * @since 1.7
      */
     public String getDisplayScript(Locale inLocale) {
-        return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
+        return getDisplayString(baseLocale.getScript(), null, inLocale, DISPLAY_SCRIPT);
     }
 
     /**
@@ -1844,29 +1866,24 @@
      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
      */
     public String getDisplayCountry(Locale inLocale) {
-        return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
+        return getDisplayString(baseLocale.getRegion(), null, inLocale, DISPLAY_COUNTRY);
     }
 
-    private String getDisplayString(String code, Locale inLocale, int type) {
-        if (code.length() == 0) {
+    private String getDisplayString(String code, String cat, Locale inLocale, int type) {
+        Objects.requireNonNull(inLocale);
+        Objects.requireNonNull(code);
+
+        if (code.isEmpty()) {
             return "";
         }
 
-        if (inLocale == null) {
-            throw new NullPointerException();
-        }
-
         LocaleServiceProviderPool pool =
             LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
-        String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
+        String rbKey = (type == DISPLAY_VARIANT ? "%%"+code : code);
         String result = pool.getLocalizedObject(
                                 LocaleNameGetter.INSTANCE,
-                                inLocale, key, type, code);
-            if (result != null) {
-                return result;
-            }
-
-        return code;
+                                inLocale, rbKey, type, code, cat);
+        return result != null ? result : code;
     }
 
     /**
@@ -1894,29 +1911,31 @@
         if (baseLocale.getVariant().length() == 0)
             return "";
 
-        LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale);
+        LocaleResources lr = LocaleProviderAdapter
+            .getResourceBundleBased()
+            .getLocaleResources(inLocale);
 
         String names[] = getDisplayVariantArray(inLocale);
 
         // Get the localized patterns for formatting a list, and use
         // them to format the list.
         return formatList(names,
-                          lr.getLocaleName("ListPattern"),
                           lr.getLocaleName("ListCompositionPattern"));
     }
 
     /**
      * Returns a name for the locale that is appropriate for display to the
      * user. This will be the values returned by getDisplayLanguage(),
-     * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
-     * into a single string. The non-empty values are used in order,
-     * with the second and subsequent names in parentheses.  For example:
+     * getDisplayScript(), getDisplayCountry(), getDisplayVariant() and
+     * optional <a href="./Locale.html#def_locale_extension">Unicode extensions</a>
+     * assembled into a single string. The non-empty values are used in order, with
+     * the second and subsequent names in parentheses.  For example:
      * <blockquote>
-     * language (script, country, variant)<br>
-     * language (country)<br>
-     * language (variant)<br>
-     * script (country)<br>
-     * country<br>
+     * language (script, country, variant(, extension)*)<br>
+     * language (country(, extension)*)<br>
+     * language (variant(, extension)*)<br>
+     * script (country(, extension)*)<br>
+     * country (extension)*<br>
      * </blockquote>
      * depending on which fields are specified in the locale.  If the
      * language, script, country, and variant fields are all empty,
@@ -1931,16 +1950,17 @@
     /**
      * Returns a name for the locale that is appropriate for display
      * to the user.  This will be the values returned by
-     * getDisplayLanguage(), getDisplayScript(),getDisplayCountry(),
-     * and getDisplayVariant() assembled into a single string.
-     * The non-empty values are used in order,
-     * with the second and subsequent names in parentheses.  For example:
+     * getDisplayLanguage(), getDisplayScript(),getDisplayCountry()
+     * getDisplayVariant(), and optional <a href="./Locale.html#def_locale_extension">
+     * Unicode extensions</a> assembled into a single string. The non-empty
+     * values are used in order, with the second and subsequent names in
+     * parentheses.  For example:
      * <blockquote>
-     * language (script, country, variant)<br>
-     * language (country)<br>
-     * language (variant)<br>
-     * script (country)<br>
-     * country<br>
+     * language (script, country, variant(, extension)*)<br>
+     * language (country(, extension)*)<br>
+     * language (variant(, extension)*)<br>
+     * script (country(, extension)*)<br>
+     * country (extension)*<br>
      * </blockquote>
      * depending on which fields are specified in the locale.  If the
      * language, script, country, and variant fields are all empty,
@@ -1951,7 +1971,9 @@
      * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
      */
     public String getDisplayName(Locale inLocale) {
-        LocaleResources lr =  LocaleProviderAdapter.forJRE().getLocaleResources(inLocale);
+        LocaleResources lr =  LocaleProviderAdapter
+            .getResourceBundleBased()
+            .getLocaleResources(inLocale);
 
         String languageName = getDisplayLanguage(inLocale);
         String scriptName = getDisplayScript(inLocale);
@@ -1960,7 +1982,6 @@
 
         // Get the localized patterns for formatting a display name.
         String displayNamePattern = lr.getLocaleName("DisplayNamePattern");
-        String listPattern = lr.getLocaleName("ListPattern");
         String listCompositionPattern = lr.getLocaleName("ListCompositionPattern");
 
         // The display name consists of a main name, followed by qualifiers.
@@ -1977,7 +1998,7 @@
             if (variantNames.length == 0) {
                 return "";
             } else {
-                return formatList(variantNames, listPattern, listCompositionPattern);
+                return formatList(variantNames, listCompositionPattern);
             }
         }
         ArrayList<String> names = new ArrayList<>(4);
@@ -1994,6 +2015,16 @@
             names.addAll(Arrays.asList(variantNames));
         }
 
+        // add Unicode extensions
+        if (localeExtensions != null) {
+            localeExtensions.getUnicodeLocaleAttributes().stream()
+                .map(key -> getDisplayString(key, null, inLocale, DISPLAY_UEXT_KEY))
+                .forEach(names::add);
+            localeExtensions.getUnicodeLocaleKeys().stream()
+                .map(key -> getDisplayKeyTypeExtensionString(key, lr, inLocale))
+                .forEach(names::add);
+        }
+
         // The first one in the main name
         mainName = names.get(0);
 
@@ -2014,7 +2045,7 @@
             // list case, but this is more efficient, and we want it to be
             // efficient since all the language-only locales will not have any
             // qualifiers.
-            qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null
+            qualifierNames.length != 0 ? formatList(qualifierNames, listCompositionPattern) : null
         };
 
         if (displayNamePattern != null) {
@@ -2121,74 +2152,78 @@
         // For each variant token, lookup the display name.  If
         // not found, use the variant name itself.
         for (int i=0; i<names.length; ++i) {
-            names[i] = getDisplayString(tokenizer.nextToken(),
+            names[i] = getDisplayString(tokenizer.nextToken(), null,
                                 inLocale, DISPLAY_VARIANT);
         }
 
         return names;
     }
 
+    private String getDisplayKeyTypeExtensionString(String key, LocaleResources lr, Locale inLocale) {
+        String type = localeExtensions.getUnicodeLocaleType(key);
+        String ret = getDisplayString(type, key, inLocale, DISPLAY_UEXT_TYPE);
+
+        if (ret == null || ret.equals(type)) {
+            // no localization for this type. try combining key/type separately
+            String displayType = type;
+            switch (key) {
+            case "cu":
+                displayType = lr.getCurrencyName(type.toLowerCase(Locale.ROOT));
+                break;
+            case "rg":
+                if (type != null &&
+                    // UN M.49 code should not be allowed here
+                    type.matches("^[a-zA-Z]{2}[zZ]{4}$")) {
+                        displayType = lr.getLocaleName(type.substring(0, 2).toUpperCase(Locale.ROOT));
+                }
+                break;
+            case "tz":
+                displayType = TimeZoneNameUtility.retrieveGenericDisplayName(
+                    TimeZoneNameUtility.convertLDMLShortID(type).orElse(type),
+                    TimeZone.LONG, inLocale);
+                break;
+            }
+            ret = MessageFormat.format(lr.getLocaleName("ListKeyTypePattern"),
+                getDisplayString(key, null, inLocale, DISPLAY_UEXT_KEY),
+                Optional.ofNullable(displayType).orElse(type));
+        }
+
+        return ret;
+    }
+
     /**
      * Format a list using given pattern strings.
      * If either of the patterns is null, then a the list is
      * formatted by concatenation with the delimiter ','.
      * @param stringList the list of strings to be formatted.
-     * @param listPattern should create a MessageFormat taking 0-3 arguments
      * and formatting them into a list.
-     * @param listCompositionPattern should take 2 arguments
-     * and is used by composeList.
+     * @param pattern should take 2 arguments for reduction
      * @return a string representing the list.
      */
-    private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
+    private static String formatList(String[] stringList, String pattern) {
         // If we have no list patterns, compose the list in a simple,
         // non-localized way.
-        if (listPattern == null || listCompositionPattern == null) {
-            StringJoiner sj = new StringJoiner(",");
-            for (int i = 0; i < stringList.length; ++i) {
-                sj.add(stringList[i]);
-            }
-            return sj.toString();
+        if (pattern == null) {
+            return Arrays.stream(stringList).collect(Collectors.joining(","));
         }
 
-        // Compose the list down to three elements if necessary
-        if (stringList.length > 3) {
-            MessageFormat format = new MessageFormat(listCompositionPattern);
-            stringList = composeList(format, stringList);
+        switch (stringList.length) {
+            case 0:
+                return "";
+            case 1:
+                return stringList[0];
+            default:
+                return Arrays.stream(stringList).reduce("",
+                    (s1, s2) -> {
+                        if (s1.equals("")) {
+                            return s2;
+                        }
+                        if (s2.equals("")) {
+                            return s1;
+                        }
+                        return MessageFormat.format(pattern, s1, s2);
+                    });
         }
-
-        // Rebuild the argument list with the list length as the first element
-        Object[] args = new Object[stringList.length + 1];
-        System.arraycopy(stringList, 0, args, 1, stringList.length);
-        args[0] = stringList.length;
-
-        // Format it using the pattern in the resource
-        MessageFormat format = new MessageFormat(listPattern);
-        return format.format(args);
-    }
-
-    /**
-     * Given a list of strings, return a list shortened to three elements.
-     * Shorten it by applying the given format to the first two elements
-     * recursively.
-     * @param format a format which takes two arguments
-     * @param list a list of strings
-     * @return if the list is three elements or shorter, the same list;
-     * otherwise, a new list of three elements.
-     */
-    private static String[] composeList(MessageFormat format, String[] list) {
-        if (list.length <= 3) return list;
-
-        // Use the given format to compose the first two elements into one
-        String[] listItems = { list[0], list[1] };
-        String newItem = format.format(listItems);
-
-        // Form a new list one element shorter
-        String[] newList = new String[list.length-1];
-        System.arraycopy(list, 2, newList, 1, newList.length-1);
-        newList[0] = newItem;
-
-        // Recurse
-        return composeList(format, newList);
     }
 
     // Duplicate of sun.util.locale.UnicodeLocaleExtension.isKey in order to
@@ -2345,9 +2380,10 @@
                                 Locale locale,
                                 String key,
                                 Object... params) {
-            assert params.length == 2;
+            assert params.length == 3;
             int type = (Integer)params[0];
             String code = (String)params[1];
+            String cat = (String)params[2];
 
             switch(type) {
             case DISPLAY_LANGUAGE:
@@ -2358,6 +2394,10 @@
                 return localeNameProvider.getDisplayVariant(code, locale);
             case DISPLAY_SCRIPT:
                 return localeNameProvider.getDisplayScript(code, locale);
+            case DISPLAY_UEXT_KEY:
+                return localeNameProvider.getDisplayUnicodeExtensionKey(code, locale);
+            case DISPLAY_UEXT_TYPE:
+                return localeNameProvider.getDisplayUnicodeExtensionType(code, cat, locale);
             default:
                 assert false; // shouldn't happen
             }
@@ -2384,7 +2424,8 @@
         DISPLAY("user.language.display",
                 "user.script.display",
                 "user.country.display",
-                "user.variant.display"),
+                "user.variant.display",
+                "user.extensions.display"),
 
         /**
          * Category used to represent the default locale for
@@ -2393,19 +2434,23 @@
         FORMAT("user.language.format",
                "user.script.format",
                "user.country.format",
-               "user.variant.format");
+               "user.variant.format",
+               "user.extensions.format");
 
-        Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
+        Category(String languageKey, String scriptKey, String countryKey,
+                String variantKey, String extensionsKey) {
             this.languageKey = languageKey;
             this.scriptKey = scriptKey;
             this.countryKey = countryKey;
             this.variantKey = variantKey;
+            this.extensionsKey = extensionsKey;
         }
 
         final String languageKey;
         final String scriptKey;
         final String countryKey;
         final String variantKey;
+        final String extensionsKey;
     }
 
     /**
--- a/src/java.base/share/classes/java/util/Properties.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Properties.java	Wed Dec 13 10:56:50 2017 -0800
@@ -37,6 +37,10 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.StreamCorruptedException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
@@ -997,6 +1001,11 @@
      *
      * <p>The specified stream remains open after this method returns.
      *
+     * <p>This method behaves the same as
+     * {@linkplain #storeToXML(OutputStream os, String comment, Charset charset)}
+     * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset}
+     * using the given encoding name.
+     *
      * @param os        the output stream on which to emit the XML document.
      * @param comment   a description of the property list, or {@code null}
      *                  if no comment is desired.
@@ -1011,20 +1020,67 @@
      * @throws NullPointerException if {@code os} is {@code null},
      *         or if {@code encoding} is {@code null}.
      * @throws ClassCastException  if this {@code Properties} object
-     *         contains any keys or values that are not
-     *         {@code Strings}.
+     *         contains any keys or values that are not {@code Strings}.
      * @see    #loadFromXML(InputStream)
      * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
      *         Encoding in Entities</a>
      * @since 1.5
      */
     public void storeToXML(OutputStream os, String comment, String encoding)
-        throws IOException
-    {
+        throws IOException {
         Objects.requireNonNull(os);
         Objects.requireNonNull(encoding);
+
+        try {
+            Charset charset = Charset.forName(encoding);
+            storeToXML(os, comment, charset);
+        } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+            throw new UnsupportedEncodingException(encoding);
+        }
+    }
+
+    /**
+     * Emits an XML document representing all of the properties contained
+     * in this table, using the specified encoding.
+     *
+     * <p>The XML document will have the following DOCTYPE declaration:
+     * <pre>
+     * &lt;!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"&gt;
+     * </pre>
+     *
+     * <p>If the specified comment is {@code null} then no comment
+     * will be stored in the document.
+     *
+     * <p> An implementation is required to support writing of XML documents
+     * that use the "{@code UTF-8}" or "{@code UTF-16}" encoding. An
+     * implementation may support additional encodings.
+     *
+     * <p> Unmappable characters for the specified charset will be encoded as
+     * numeric character references.
+     *
+     * <p>The specified stream remains open after this method returns.
+     *
+     * @param os        the output stream on which to emit the XML document.
+     * @param comment   a description of the property list, or {@code null}
+     *                  if no comment is desired.
+     * @param charset   the charset
+     *
+     * @throws IOException if writing to the specified output stream
+     *         results in an {@code IOException}.
+     * @throws NullPointerException if {@code os} or {@code charset} is {@code null}.
+     * @throws ClassCastException  if this {@code Properties} object
+     *         contains any keys or values that are not {@code Strings}.
+     * @see    #loadFromXML(InputStream)
+     * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
+     *         Encoding in Entities</a>
+     * @since 10
+     */
+    public void storeToXML(OutputStream os, String comment, Charset charset)
+        throws IOException {
+        Objects.requireNonNull(os, "OutputStream");
+        Objects.requireNonNull(charset, "Charset");
         PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
-        handler.store(this, os, comment, encoding);
+        handler.store(this, os, comment, charset);
     }
 
     /**
--- a/src/java.base/share/classes/java/util/Scanner.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/Scanner.java	Wed Dec 13 10:56:50 2017 -0800
@@ -33,10 +33,13 @@
 import java.nio.file.Path;
 import java.nio.file.Files;
 import java.text.*;
+import java.text.spi.NumberFormatProvider;
 import java.util.function.Consumer;
 import java.util.regex.*;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.ResourceBundleBasedAdapter;
 
 /**
  * A simple text scanner which can parse primitive types and strings using
@@ -575,7 +578,21 @@
      *         does not exist
      */
     public Scanner(InputStream source, String charsetName) {
-        this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
+        this(source, toCharset(charsetName));
+    }
+
+    /**
+     * Constructs a new {@code Scanner} that produces values scanned
+     * from the specified input stream. Bytes from the stream are converted
+     * into characters using the specified charset.
+     *
+     * @param  source an input stream to be scanned
+     * @param  charset the charset used to convert bytes from the file
+     *         into characters to be scanned
+     * @since  10
+     */
+    public Scanner(InputStream source, Charset charset) {
+        this(makeReadable(Objects.requireNonNull(source, "source"), charset),
              WHITESPACE_PATTERN);
     }
 
@@ -594,7 +611,18 @@
         }
     }
 
+    /*
+     * This method is added so that null-check on charset can be performed before
+     * creating InputStream as an existing test required it.
+    */
+    private static Readable makeReadable(Path source, Charset charset)
+            throws IOException {
+        Objects.requireNonNull(charset, "charset");
+        return makeReadable(Files.newInputStream(source), charset);
+    }
+
     private static Readable makeReadable(InputStream source, Charset charset) {
+        Objects.requireNonNull(charset, "charset");
         return new InputStreamReader(source, charset);
     }
 
@@ -629,6 +657,22 @@
         this(Objects.requireNonNull(source), toDecoder(charsetName));
     }
 
+    /**
+     * Constructs a new {@code Scanner} that produces values scanned
+     * from the specified file. Bytes from the file are converted into
+     * characters using the specified charset.
+     *
+     * @param  source A file to be scanned
+     * @param  charset The charset used to convert bytes from the file
+     *         into characters to be scanned
+     * @throws IOException
+     *         if an I/O error occurs opening the source
+     * @since  10
+     */
+    public Scanner(File source, Charset charset) throws IOException {
+        this(Objects.requireNonNull(source), charset.newDecoder());
+    }
+
     private Scanner(File source, CharsetDecoder dec)
         throws FileNotFoundException
     {
@@ -649,6 +693,12 @@
         return Channels.newReader(source, dec, -1);
     }
 
+    private static Readable makeReadable(ReadableByteChannel source,
+                                         Charset charset) {
+        Objects.requireNonNull(charset, "charset");
+        return Channels.newReader(source, charset);
+    }
+
     /**
      * Constructs a new {@code Scanner} that produces values scanned
      * from the specified file. Bytes from the file are converted into
@@ -688,8 +738,22 @@
         this(Objects.requireNonNull(source), toCharset(charsetName));
     }
 
-    private Scanner(Path source, Charset charset)  throws IOException {
-        this(makeReadable(Files.newInputStream(source), charset));
+    /**
+     * Constructs a new {@code Scanner} that produces values scanned
+     * from the specified file. Bytes from the file are converted into
+     * characters using the specified charset.
+     *
+     * @param   source
+     *          the path to the file to be scanned
+     * @param   charset
+     *          the charset used to convert bytes from the file
+     *          into characters to be scanned
+     * @throws  IOException
+     *          if an I/O error occurs opening the source
+     * @since   10
+     */
+    public Scanner(Path source, Charset charset)  throws IOException {
+        this(makeReadable(source, charset));
     }
 
     /**
@@ -735,6 +799,21 @@
              WHITESPACE_PATTERN);
     }
 
+    /**
+     * Constructs a new {@code Scanner} that produces values scanned
+     * from the specified channel. Bytes from the source are converted into
+     * characters using the specified charset.
+     *
+     * @param source a channel to scan
+     * @param charset the encoding type used to convert bytes from the
+     *        channel into characters to be scanned
+     * @since 10
+     */
+    public Scanner(ReadableByteChannel source, Charset charset) {
+        this(makeReadable(Objects.requireNonNull(source, "source"), charset),
+             WHITESPACE_PATTERN);
+    }
+
     // Private primitives used to support scanning
 
     private void saveState() {
@@ -1186,9 +1265,27 @@
 
         modCount++;
         this.locale = locale;
-        DecimalFormat df =
-            (DecimalFormat)NumberFormat.getNumberInstance(locale);
+
+        DecimalFormat df = null;
+        NumberFormat nf = NumberFormat.getNumberInstance(locale);
         DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
+        if (nf instanceof DecimalFormat) {
+             df = (DecimalFormat) nf;
+        } else {
+
+            // In case where NumberFormat.getNumberInstance() returns
+            // other instance (non DecimalFormat) based on the provider
+            // used and java.text.spi.NumberFormatProvider implementations,
+            // DecimalFormat constructor is used to obtain the instance
+            LocaleProviderAdapter adapter = LocaleProviderAdapter
+                    .getAdapter(NumberFormatProvider.class, locale);
+            if (!(adapter instanceof ResourceBundleBasedAdapter)) {
+                adapter = LocaleProviderAdapter.getResourceBundleBased();
+            }
+            String[] all = adapter.getLocaleResources(locale)
+                    .getNumberPatterns();
+            df = new DecimalFormat(all[0], dfs);
+        }
 
         // These must be literalized to avoid collision with regex
         // metacharacters such as dot or parenthesis
--- a/src/java.base/share/classes/java/util/SimpleTimeZone.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/SimpleTimeZone.java	Wed Dec 13 10:56:50 2017 -0800
@@ -548,12 +548,11 @@
 
       computeOffset:
         if (useDaylight) {
-            synchronized (this) {
-                if (cacheStart != 0) {
-                    if (date >= cacheStart && date < cacheEnd) {
-                        offset += dstSavings;
-                        break computeOffset;
-                    }
+            Cache cache = this.cache;
+            if (cache != null) {
+                if (date >= cache.start && date < cache.end) {
+                    offset += dstSavings;
+                    break computeOffset;
                 }
             }
             BaseCalendar cal = date >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER ?
@@ -671,14 +670,13 @@
     }
 
     private int getOffset(BaseCalendar cal, BaseCalendar.Date cdate, int year, long time) {
-        synchronized (this) {
-            if (cacheStart != 0) {
-                if (time >= cacheStart && time < cacheEnd) {
-                    return rawOffset + dstSavings;
-                }
-                if (year == cacheYear) {
-                    return rawOffset;
-                }
+        Cache cache = this.cache;
+        if (cache != null) {
+            if (time >= cache.start && time < cache.end) {
+                return rawOffset + dstSavings;
+            }
+            if (year == cache.year) {
+                return rawOffset;
             }
         }
 
@@ -689,11 +687,7 @@
             if (time >= start && time < end) {
                 offset += dstSavings;
             }
-            synchronized (this) {
-                cacheYear = year;
-                cacheStart = start;
-                cacheEnd = end;
-            }
+            this.cache = new Cache(year, start, end);
         } else {
             if (time < end) {
                 // TODO: support Gregorian cutover. The previous year
@@ -711,12 +705,7 @@
                 }
             }
             if (start <= end) {
-                synchronized (this) {
-                    // The start and end transitions are in multiple years.
-                    cacheYear = (long) startYear - 1;
-                    cacheStart = start;
-                    cacheEnd = end;
-                }
+                this.cache = new Cache((long) startYear - 1, start, end);
             }
         }
         return offset;
@@ -876,7 +865,7 @@
      * Generates the hash code for the SimpleDateFormat object.
      * @return the hash code for this object
      */
-    public synchronized int hashCode()
+    public int hashCode()
     {
         return startMonth ^ startDay ^ startDayOfWeek ^ startTime ^
             endMonth ^ endDay ^ endDayOfWeek ^ endTime ^ rawOffset;
@@ -1201,19 +1190,27 @@
 
     /**
      * Cache values representing a single period of daylight saving
-     * time. When the cache values are valid, cacheStart is the start
-     * time (inclusive) of daylight saving time and cacheEnd is the
-     * end time (exclusive).
+     * time. Cache.start is the start time (inclusive) of daylight
+     * saving time and Cache.end is the end time (exclusive).
      *
-     * cacheYear has a year value if both cacheStart and cacheEnd are
-     * in the same year. cacheYear is set to startYear - 1 if
-     * cacheStart and cacheEnd are in different years. cacheStart is 0
-     * if the cache values are void. cacheYear is a long to support
-     * Integer.MIN_VALUE - 1 (JCK requirement).
+     * Cache.year has a year value if both Cache.start and Cache.end are
+     * in the same year. Cache.year is set to startYear - 1 if
+     * Cache.start and Cache.end are in different years.
+     * Cache.year is a long to support Integer.MIN_VALUE - 1 (JCK requirement).
      */
-    private transient long cacheYear;
-    private transient long cacheStart;
-    private transient long cacheEnd;
+    private static final class Cache {
+        final long year;
+        final long start;
+        final long end;
+
+        Cache(long year, long start, long end) {
+            this.year = year;
+            this.start = start;
+            this.end = end;
+        }
+    }
+
+    private transient volatile Cache cache;
 
     /**
      * Constants specifying values of startMode and endMode.
@@ -1282,9 +1279,8 @@
     // Maximum number of rules.
     private static final int MAX_RULE_NUM = 6;
 
-    private synchronized void invalidateCache() {
-        cacheYear = startYear - 1;
-        cacheStart = cacheEnd = 0;
+    private void invalidateCache() {
+        cache = null;
     }
 
     //----------------------------------------------------------------------
--- a/src/java.base/share/classes/java/util/spi/LocaleNameProvider.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/spi/LocaleNameProvider.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package java.util.spi;
 
 import java.util.Locale;
+import java.util.Objects;
 
 /**
  * An abstract class for service providers that
@@ -141,4 +142,54 @@
      * @see java.util.Locale#getDisplayVariant(java.util.Locale)
      */
     public abstract String getDisplayVariant(String variant, Locale locale);
+
+    /**
+     * Returns a localized name for the given
+     * <a href="../Locale.html#def_locale_extension">Unicode extension</a> key,
+     * and the given locale that is appropriate for display to the user.
+     * If the name returned cannot be localized according to {@code locale},
+     * this method returns null.
+     * @implSpec the default implementation returns {@code null}.
+     * @param key the Unicode Extension key, not null.
+     * @param locale the desired locale, not null.
+     * @return the name of the given key string for the specified locale,
+     *  or null if it's not available.
+     * @exception NullPointerException if {@code key} or {@code locale} is null
+     * @exception IllegalArgumentException if {@code locale} isn't
+     *     one of the locales returned from
+     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
+     *     getAvailableLocales()}.
+     * @since 10
+     */
+    public String getDisplayUnicodeExtensionKey(String key, Locale locale) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(locale);
+        return null;
+    }
+
+    /**
+     * Returns a localized name for the given
+     * <a href="../Locale.html#def_locale_extension">Unicode extension</a> type,
+     * and the given locale that is appropriate for display to the user.
+     * If the name returned cannot be localized according to {@code locale},
+     * this method returns null.
+     * @implSpec the default implementation returns {@code null}.
+     * @param type the Unicode Extension type, not null.
+     * @param key the Unicode Extension key for this {@code type}, not null.
+     * @param locale the desired locale, not null.
+     * @return the name of the given type string for the specified locale,
+     *  or null if it's not available.
+     * @exception NullPointerException if {@code key}, {@code type} or {@code locale} is null
+     * @exception IllegalArgumentException if {@code locale} isn't
+     *     one of the locales returned from
+     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
+     *     getAvailableLocales()}.
+     * @since 10
+     */
+    public String getDisplayUnicodeExtensionType(String type, String key, Locale locale) {
+        Objects.requireNonNull(type);
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(locale);
+        return null;
+    }
 }
--- a/src/java.base/share/classes/java/util/zip/Deflater.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/zip/Deflater.java	Wed Dec 13 10:56:50 2017 -0800
@@ -67,12 +67,26 @@
  * }
  * </pre></blockquote>
  *
+ * @apiNote
+ * To release resources used by this {@code Deflater}, the {@link #end()} method
+ * should be called explicitly. Subclasses are responsible for the cleanup of resources
+ * acquired by the subclass. Subclasses that override {@link #finalize()} in order
+ * to perform cleanup should be modified to use alternative cleanup mechanisms such
+ * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
+ *
+ * @implSpec
+ * If this {@code Deflater} has been subclassed and the {@code end} method has been
+ * overridden, the {@code end} method will be called by the finalization when the
+ * deflater is unreachable. But the subclasses should not depend on this specific
+ * implementation; the finalization is not reliable and the {@code finalize} method
+ * is deprecated to be removed.
+ *
  * @see         Inflater
  * @author      David Connelly
  * @since 1.1
  */
-public
-class Deflater {
+
+public class Deflater {
 
     private final ZStreamRef zsRef;
     private byte[] buf = new byte[0];
@@ -169,7 +183,9 @@
     public Deflater(int level, boolean nowrap) {
         this.level = level;
         this.strategy = DEFAULT_STRATEGY;
-        this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
+        this.zsRef = ZStreamRef.get(this,
+                () -> init(level, DEFAULT_STRATEGY, nowrap),
+                Deflater::end);
     }
 
     /**
@@ -534,38 +550,32 @@
 
     /**
      * Closes the compressor and discards any unprocessed input.
+     *
      * This method should be called when the compressor is no longer
-     * being used, but will also be called automatically by the
-     * finalize() method. Once this method is called, the behavior
-     * of the Deflater object is undefined.
+     * being used. Once this method is called, the behavior of the
+     * Deflater object is undefined.
      */
     public void end() {
         synchronized (zsRef) {
-            long addr = zsRef.address();
-            zsRef.clear();
-            if (addr != 0) {
-                end(addr);
-                buf = null;
-            }
+            zsRef.clean();
+            buf = null;
         }
     }
 
     /**
      * Closes the compressor when garbage is collected.
      *
-     * @deprecated The {@code finalize} method has been deprecated.
-     *     Subclasses that override {@code finalize} in order to perform cleanup
-     *     should be modified to use alternative cleanup mechanisms and
-     *     to remove the overriding {@code finalize} method.
-     *     When overriding the {@code finalize} method, its implementation must explicitly
-     *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
-     *     See the specification for {@link Object#finalize()} for further
-     *     information about migration options.
+     * @deprecated The {@code finalize} method has been deprecated and will be
+     *     removed. It is implemented as a no-op. Subclasses that override
+     *     {@code finalize} in order to perform cleanup should be modified to use
+     *     alternative cleanup mechanisms and to remove the overriding {@code finalize}
+     *     method. The recommended cleanup for compressor is to explicitly call
+     *     {@code end} method when it is no longer in use. If the {@code end} is
+     *     not invoked explicitly the resource of the compressor will be released
+     *     when the instance becomes unreachable.
      */
-    @Deprecated(since="9")
-    protected void finalize() {
-        end();
-    }
+    @Deprecated(since="9", forRemoval=true)
+    protected void finalize() {}
 
     private void ensureOpen() {
         assert Thread.holdsLock(zsRef);
--- a/src/java.base/share/classes/java/util/zip/Inflater.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/zip/Inflater.java	Wed Dec 13 10:56:50 2017 -0800
@@ -66,13 +66,27 @@
  * }
  * </pre></blockquote>
  *
+ * @apiNote
+ * To release resources used by this {@code Inflater}, the {@link #end()} method
+ * should be called explicitly. Subclasses are responsible for the cleanup of resources
+ * acquired by the subclass. Subclasses that override {@link #finalize()} in order
+ * to perform cleanup should be modified to use alternative cleanup mechanisms such
+ * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
+ *
+ * @implSpec
+ * If this {@code Inflater} has been subclassed and the {@code end} method has been
+ * overridden, the {@code end} method will be called by the finalization when the
+ * inflater is unreachable. But the subclasses should not depend on this specific
+ * implementation; the finalization is not reliable and the {@code finalize} method
+ * is deprecated to be removed.
+ *
  * @see         Deflater
  * @author      David Connelly
  * @since 1.1
  *
  */
-public
-class Inflater {
+
+public class Inflater {
 
     private final ZStreamRef zsRef;
     private byte[] buf = defaultBuf;
@@ -101,7 +115,7 @@
      * @param nowrap if true then support GZIP compatible compression
      */
     public Inflater(boolean nowrap) {
-        zsRef = new ZStreamRef(init(nowrap));
+        this.zsRef = ZStreamRef.get(this, () -> init(nowrap), Inflater::end);
     }
 
     /**
@@ -361,38 +375,37 @@
 
     /**
      * Closes the decompressor and discards any unprocessed input.
+     *
      * This method should be called when the decompressor is no longer
-     * being used, but will also be called automatically by the finalize()
-     * method. Once this method is called, the behavior of the Inflater
-     * object is undefined.
+     * being used. Once this method is called, the behavior of the
+     * Inflater object is undefined.
      */
     public void end() {
         synchronized (zsRef) {
-            long addr = zsRef.address();
-            zsRef.clear();
-            if (addr != 0) {
-                end(addr);
-                buf = null;
-            }
+            zsRef.clean();
+            buf = null;
         }
     }
 
     /**
      * Closes the decompressor when garbage is collected.
      *
-     * @deprecated The {@code finalize} method has been deprecated.
-     *     Subclasses that override {@code finalize} in order to perform cleanup
-     *     should be modified to use alternative cleanup mechanisms and
-     *     to remove the overriding {@code finalize} method.
-     *     When overriding the {@code finalize} method, its implementation must explicitly
-     *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
-     *     See the specification for {@link Object#finalize()} for further
-     *     information about migration options.
+     * @implSpec
+     * If this {@code Inflater} has been subclassed and the {@code end} method
+     * has been overridden, the {@code end} method will be called when the
+     * inflater is unreachable.
+     *
+     * @deprecated The {@code finalize} method has been deprecated and will be
+     *     removed. It is implemented as a no-op. Subclasses that override
+     *     {@code finalize} in order to perform cleanup should be modified to use
+     *     alternative cleanup mechanisms and remove the overriding {@code finalize}
+     *     method. The recommended cleanup for compressor is to explicitly call
+     *     {@code end} method when it is no longer in use. If the {@code end} is
+     *     not invoked explicitly the resource of the compressor will be released
+     *     when the instance becomes unreachable,
      */
-    @Deprecated(since="9")
-    protected void finalize() {
-        end();
-    }
+    @Deprecated(since="9", forRemoval=true)
+    protected void finalize() {}
 
     private void ensureOpen () {
         assert Thread.holdsLock(zsRef);
--- a/src/java.base/share/classes/java/util/zip/ZStreamRef.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/zip/ZStreamRef.java	Wed Dec 13 10:56:50 2017 -0800
@@ -25,22 +25,89 @@
 
 package java.util.zip;
 
+import java.util.function.LongConsumer;
+import java.util.function.LongSupplier;
+import java.lang.ref.Cleaner.Cleanable;
+import jdk.internal.ref.CleanerFactory;
+
 /**
- * A reference to the native zlib's z_stream structure.
+ * A reference to the native zlib's z_stream structure. It also
+ * serves as the "cleaner" to clean up the native resource when
+ * the deflater or infalter is ended, closed or cleaned.
  */
+class ZStreamRef implements Runnable {
 
-class ZStreamRef {
+    private LongConsumer end;
+    private long address;
+    private final Cleanable cleanable;
 
-    private volatile long address;
-    ZStreamRef (long address) {
-        this.address = address;
+    private ZStreamRef (Object owner, LongSupplier addr, LongConsumer end) {
+        this.cleanable = CleanerFactory.cleaner().register(owner, this);
+        this.end = end;
+        this.address = addr.getAsLong();
     }
 
     long address() {
         return address;
     }
 
-    void clear() {
+    void clean() {
+        cleanable.clean();
+    }
+
+    public synchronized void run() {
+        long addr = address;
         address = 0;
+        if (addr != 0) {
+            end.accept(addr);
+        }
+    }
+
+    private ZStreamRef (LongSupplier addr, LongConsumer end) {
+        this.cleanable = null;
+        this.end = end;
+        this.address = addr.getAsLong();
+    }
+
+    /*
+     * If {@code Inflater/Deflater} has been subclassed and the {@code end} method
+     * is overridden, uses {@code finalizer} mechanism for resource cleanup. So
+     * {@code end} method can be called when the {@code Inflater/Deflater} is
+     * unreachable. This mechanism will be removed when the {@code finalize} method
+     * is removed from {@code Inflater/Deflater}.
+     */
+    static ZStreamRef get(Object owner, LongSupplier addr, LongConsumer end) {
+        Class<?> clz = owner.getClass();
+        while (clz != Deflater.class && clz != Inflater.class) {
+            try {
+                clz.getDeclaredMethod("end");
+                return new FinalizableZStreamRef(owner, addr, end);
+            } catch (NoSuchMethodException nsme) {}
+            clz = clz.getSuperclass();
+        }
+        return new ZStreamRef(owner, addr, end);
+    }
+
+    private static class FinalizableZStreamRef extends ZStreamRef {
+        final Object owner;
+
+        FinalizableZStreamRef (Object owner, LongSupplier addr, LongConsumer end) {
+            super(addr, end);
+            this.owner = owner;
+        }
+
+        @Override
+        void clean() {
+            run();
+        }
+
+        @Override
+        @SuppressWarnings("deprecation")
+        protected void finalize() {
+            if (owner instanceof Inflater)
+                ((Inflater)owner).end();
+            else
+                ((Deflater)owner).end();
+        }
     }
 }
--- a/src/java.base/share/classes/java/util/zip/ZipCoder.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java	Wed Dec 13 10:56:50 2017 -0800
@@ -28,72 +28,60 @@
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
+import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CodingErrorAction;
-import java.util.Arrays;
-import sun.nio.cs.ArrayDecoder;
-import sun.nio.cs.ArrayEncoder;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 /**
  * Utility class for zipfile name and comment decoding and encoding
  */
 
-final class ZipCoder {
+class ZipCoder {
 
-    private static boolean isASCII(byte[] ba, int off, int len) {
-        for (int i = off; i < off + len; i++) {
-            if (ba[i] < 0)
-                return false;
+    private static final jdk.internal.misc.JavaLangAccess JLA =
+        jdk.internal.misc.SharedSecrets.getJavaLangAccess();
+
+    static final class UTF8 extends ZipCoder {
+
+        UTF8(Charset utf8) {
+            super(utf8);
         }
-        return true;
+
+        @Override
+        boolean isUTF8() {
+            return true;
+        }
+
+        @Override
+        String toString(byte[] ba, int off, int length) {
+            return JLA.newStringUTF8NoRepl(ba, off, length);
+        }
+
+        @Override
+        byte[] getBytes(String s) {
+            return JLA.getBytesUTF8NoRepl(s);
+        }
     }
 
-    private static boolean hasReplaceChar(byte[] ba) {
-        for (int i = 0; i < ba.length; i++) {
-            if (ba[i] == (byte)'?')
-                return true;
-        }
-        return false;
+    // UTF_8.ArrayEn/Decoder is stateless, so make it singleton.
+    private static ZipCoder utf8 = new UTF8(UTF_8);
+
+    public static ZipCoder get(Charset charset) {
+        if (charset == UTF_8)
+            return utf8;
+        return new ZipCoder(charset);
     }
 
     String toString(byte[] ba, int off, int length) {
+        try {
+              return decoder().decode(ByteBuffer.wrap(ba, off, length)).toString();
 
-        // fastpath for UTF-8 cs and ascii only name, leverage the
-        // compact string impl to avoid the unnecessary char[] copy/
-        // paste. A temporary workaround before we have better approach,
-        // such as a String constructor that throws exception for
-        // malformed and/or unmappable characters, instead of silently
-        // replacing with repl char
-        if (isUTF8 && isASCII(ba, off, length)) {
-            return new String(ba, off, length, cs);
+        } catch (CharacterCodingException x) {
+            throw new IllegalArgumentException(x);
         }
-
-        CharsetDecoder cd = decoder().reset();
-        int len = (int)(length * cd.maxCharsPerByte());
-        char[] ca = new char[len];
-        if (len == 0)
-            return new String(ca);
-        // UTF-8 only for now. Other ArrayDeocder only handles
-        // CodingErrorAction.REPLACE mode. ZipCoder uses
-        // REPORT mode.
-        if (isUTF8 && cd instanceof ArrayDecoder) {
-            int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
-            if (clen == -1)    // malformed
-                throw new IllegalArgumentException("MALFORMED");
-            return new String(ca, 0, clen);
-        }
-        ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
-        CharBuffer cb = CharBuffer.wrap(ca);
-        CoderResult cr = cd.decode(bb, cb, true);
-        if (!cr.isUnderflow())
-            throw new IllegalArgumentException(cr.toString());
-        cr = cd.flush(cb);
-        if (!cr.isUnderflow())
-            throw new IllegalArgumentException(cr.toString());
-        return new String(ca, 0, cb.position());
     }
 
     String toString(byte[] ba, int length) {
@@ -105,84 +93,47 @@
     }
 
     byte[] getBytes(String s) {
-        if (isUTF8) {
-            // fastpath for UTF8. should only occur when the string
-            // has malformed surrogates. A postscan should still be
-            // faster and use less memory.
-            byte[] ba = s.getBytes(cs);
-            if (!hasReplaceChar(ba)) {
-                return ba;
+        try {
+            ByteBuffer bb = encoder().encode(CharBuffer.wrap(s));
+            int pos = bb.position();
+            int limit = bb.limit();
+            if (bb.hasArray() && pos == 0 && limit == bb.capacity()) {
+                return bb.array();
             }
+            byte[] bytes = new byte[bb.limit() - bb.position()];
+            bb.get(bytes);
+            return bytes;
+        } catch (CharacterCodingException x) {
+            throw new IllegalArgumentException(x);
         }
-        CharsetEncoder ce = encoder().reset();
-        char[] ca = s.toCharArray();
-        int len = (int)(ca.length * ce.maxBytesPerChar());
-        byte[] ba = new byte[len];
-        if (len == 0)
-            return ba;
-        // UTF-8 only for now. Other ArrayDeocder only handles
-        // CodingErrorAction.REPLACE mode.
-        if (isUTF8 && ce instanceof ArrayEncoder) {
-            int blen = ((ArrayEncoder)ce).encode(ca, 0, ca.length, ba);
-            if (blen == -1)    // malformed
-                throw new IllegalArgumentException("MALFORMED");
-            return Arrays.copyOf(ba, blen);
-        }
-        ByteBuffer bb = ByteBuffer.wrap(ba);
-        CharBuffer cb = CharBuffer.wrap(ca);
-        CoderResult cr = ce.encode(cb, bb, true);
-        if (!cr.isUnderflow())
-            throw new IllegalArgumentException(cr.toString());
-        cr = ce.flush(bb);
-        if (!cr.isUnderflow())
-            throw new IllegalArgumentException(cr.toString());
-        if (bb.position() == ba.length)  // defensive copy?
-            return ba;
-        else
-            return Arrays.copyOf(ba, bb.position());
     }
 
     // assume invoked only if "this" is not utf8
     byte[] getBytesUTF8(String s) {
-        if (isUTF8)
-            return getBytes(s);
-        if (utf8 == null)
-            utf8 = new ZipCoder(StandardCharsets.UTF_8);
         return utf8.getBytes(s);
     }
 
     String toStringUTF8(byte[] ba, int len) {
-        return toStringUTF8(ba, 0, len);
+        return utf8.toString(ba, 0, len);
     }
 
     String toStringUTF8(byte[] ba, int off, int len) {
-        if (isUTF8)
-            return toString(ba, off, len);
-        if (utf8 == null)
-            utf8 = new ZipCoder(StandardCharsets.UTF_8);
         return utf8.toString(ba, off, len);
     }
 
     boolean isUTF8() {
-        return isUTF8;
+        return false;
     }
 
     private Charset cs;
     private CharsetDecoder dec;
     private CharsetEncoder enc;
-    private boolean isUTF8;
-    private ZipCoder utf8;
 
     private ZipCoder(Charset cs) {
         this.cs = cs;
-        this.isUTF8 = cs.name().equals(StandardCharsets.UTF_8.name());
     }
 
-    static ZipCoder get(Charset charset) {
-        return new ZipCoder(charset);
-    }
-
-    private CharsetDecoder decoder() {
+    protected CharsetDecoder decoder() {
         if (dec == null) {
             dec = cs.newDecoder()
               .onMalformedInput(CodingErrorAction.REPORT)
@@ -191,7 +142,7 @@
         return dec;
     }
 
-    private CharsetEncoder encoder() {
+    protected CharsetEncoder encoder() {
         if (enc == null) {
             enc = cs.newEncoder()
               .onMalformedInput(CodingErrorAction.REPORT)
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java	Wed Dec 13 10:56:50 2017 -0800
@@ -31,22 +31,24 @@
 import java.io.EOFException;
 import java.io.File;
 import java.io.RandomAccessFile;
+import java.io.UncheckedIOException;
+import java.lang.ref.Cleaner.Cleanable;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.Path;
 import java.nio.file.Files;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Deque;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Objects;
 import java.util.NoSuchElementException;
+import java.util.Set;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.WeakHashMap;
@@ -61,8 +63,8 @@
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.VM;
 import jdk.internal.perf.PerfCounter;
+import jdk.internal.ref.CleanerFactory;
 
-import static java.util.zip.ZipConstants.*;
 import static java.util.zip.ZipConstants64.*;
 import static java.util.zip.ZipUtils.*;
 
@@ -73,6 +75,21 @@
  * or method in this class will cause a {@link NullPointerException} to be
  * thrown.
  *
+ * @apiNote
+ * To release resources used by this {@code ZipFile}, the {@link #close()} method
+ * should be called explicitly or by try-with-resources. Subclasses are responsible
+ * for the cleanup of resources acquired by the subclass. Subclasses that override
+ * {@link #finalize()} in order to perform cleanup should be modified to use alternative
+ * cleanup mechanisms such as {@link java.lang.ref.Cleaner} and remove the overriding
+ * {@code finalize} method.
+ *
+ * @implSpec
+ * If this {@code ZipFile} has been subclassed and the {@code close} method has
+ * been overridden, the {@code close} method will be called by the finalization
+ * when {@code ZipFile} is unreachable. But the subclasses should not depend on
+ * this specific implementation; the finalization is not reliable and the
+ * {@code finalize} method is deprecated to be removed.
+ *
  * @author      David Connelly
  * @since 1.1
  */
@@ -81,9 +98,15 @@
 
     private final String name;     // zip file name
     private volatile boolean closeRequested;
-    private Source zsrc;
     private ZipCoder zc;
 
+    // The "resource" used by this zip file that needs to be
+    // cleaned after use.
+    // a) the input streams that need to be closed
+    // b) the list of cached Inflater objects
+    // c) the "native" source of this zip file.
+    private final CleanableResource res;
+
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
 
@@ -214,10 +237,13 @@
             }
         }
         Objects.requireNonNull(charset, "charset");
+
         this.zc = ZipCoder.get(charset);
         this.name = name;
         long t0 = System.nanoTime();
-        this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
+
+        this.res = CleanableResource.get(this, file, mode);
+
         PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
         PerfCounter.getZipFileCount().increment();
     }
@@ -284,10 +310,10 @@
     public String getComment() {
         synchronized (this) {
             ensureOpen();
-            if (zsrc.comment == null) {
+            if (res.zsrc.comment == null) {
                 return null;
             }
-            return zc.toString(zsrc.comment);
+            return zc.toString(res.zsrc.comment);
         }
     }
 
@@ -318,7 +344,7 @@
         synchronized (this) {
             ensureOpen();
             byte[] bname = zc.getBytes(name);
-            int pos = zsrc.getEntryPos(bname, true);
+            int pos = res.zsrc.getEntryPos(bname, true);
             if (pos != -1) {
                 return getZipEntry(name, bname, pos, func);
             }
@@ -326,10 +352,6 @@
         return null;
     }
 
-    // The outstanding inputstreams that need to be closed,
-    // mapped to the inflater objects they use.
-    private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
-
     /**
      * Returns an input stream for reading the contents of the specified
      * zip file entry.
@@ -348,6 +370,8 @@
         Objects.requireNonNull(entry, "entry");
         int pos = -1;
         ZipFileInputStream in = null;
+        Source zsrc = res.zsrc;
+        Set<InputStream> istreams = res.istreams;
         synchronized (this) {
             ensureOpen();
             if (Objects.equals(lastEntryName, entry.name)) {
@@ -363,8 +387,8 @@
             in = new ZipFileInputStream(zsrc.cen, pos);
             switch (CENHOW(zsrc.cen, pos)) {
             case STORED:
-                synchronized (streams) {
-                    streams.put(in, null);
+                synchronized (istreams) {
+                    istreams.add(in);
                 }
                 return in;
             case DEFLATED:
@@ -377,10 +401,9 @@
                 if (size <= 0) {
                     size = 4096;
                 }
-                Inflater inf = getInflater();
-                InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size);
-                synchronized (streams) {
-                    streams.put(is, inf);
+                InputStream is = new ZipFileInflaterInputStream(in, res, (int)size);
+                synchronized (istreams) {
+                    istreams.add(is);
                 }
                 return is;
             default:
@@ -392,25 +415,30 @@
     private class ZipFileInflaterInputStream extends InflaterInputStream {
         private volatile boolean closeRequested;
         private boolean eof = false;
+        private final Cleanable cleanable;
 
-        ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf,
-                int size) {
+        ZipFileInflaterInputStream(ZipFileInputStream zfin,
+                                   CleanableResource res, int size) {
+            this(zfin, res, res.getInflater(), size);
+        }
+
+        private ZipFileInflaterInputStream(ZipFileInputStream zfin,
+                                           CleanableResource res,
+                                           Inflater inf, int size) {
             super(zfin, inf, size);
-        }
+            this.cleanable = CleanerFactory.cleaner().register(this,
+                    () -> res.releaseInflater(inf));
+       }
 
         public void close() throws IOException {
             if (closeRequested)
                 return;
             closeRequested = true;
-
             super.close();
-            Inflater inf;
-            synchronized (streams) {
-                inf = streams.remove(this);
+            synchronized (res.istreams) {
+                res.istreams.remove(this);
             }
-            if (inf != null) {
-                releaseInflater(inf);
-            }
+            cleanable.clean();
         }
 
         // Override fill() method to provide an extra "dummy" byte
@@ -436,44 +464,8 @@
             return (avail > (long) Integer.MAX_VALUE ?
                     Integer.MAX_VALUE : (int) avail);
         }
-
-        @SuppressWarnings("deprecation")
-        protected void finalize() throws Throwable {
-            close();
-        }
     }
 
-    /*
-     * Gets an inflater from the list of available inflaters or allocates
-     * a new one.
-     */
-    private Inflater getInflater() {
-        Inflater inf;
-        synchronized (inflaterCache) {
-            while ((inf = inflaterCache.poll()) != null) {
-                if (!inf.ended()) {
-                    return inf;
-                }
-            }
-        }
-        return new Inflater(true);
-    }
-
-    /*
-     * Releases the specified inflater to the list of available inflaters.
-     */
-    private void releaseInflater(Inflater inf) {
-        if (!inf.ended()) {
-            inf.reset();
-            synchronized (inflaterCache) {
-                inflaterCache.add(inf);
-            }
-        }
-    }
-
-    // List of available Inflater objects for decompression
-    private final Deque<Inflater> inflaterCache = new ArrayDeque<>();
-
     /**
      * Returns the path name of the ZIP file.
      * @return the path name of the ZIP file
@@ -518,7 +510,7 @@
                     throw new NoSuchElementException();
                 }
                 // each "entry" has 3 ints in table entries
-                return (T)getZipEntry(null, null, zsrc.getEntryPos(i++ * 3), gen);
+                return (T)getZipEntry(null, null, res.zsrc.getEntryPos(i++ * 3), gen);
             }
         }
 
@@ -536,14 +528,14 @@
     public Enumeration<? extends ZipEntry> entries() {
         synchronized (this) {
             ensureOpen();
-            return new ZipEntryIterator<ZipEntry>(zsrc.total, ZipEntry::new);
+            return new ZipEntryIterator<ZipEntry>(res.zsrc.total, ZipEntry::new);
         }
     }
 
     private Enumeration<JarEntry> entries(Function<String, JarEntry> func) {
         synchronized (this) {
             ensureOpen();
-            return new ZipEntryIterator<JarEntry>(zsrc.total, func);
+            return new ZipEntryIterator<JarEntry>(res.zsrc.total, func);
         }
     }
 
@@ -568,7 +560,7 @@
             if (index >= 0 && index < fence) {
                 synchronized (ZipFile.this) {
                     ensureOpen();
-                    action.accept(gen.apply(zsrc.getEntryPos(index++ * 3)));
+                    action.accept(gen.apply(res.zsrc.getEntryPos(index++ * 3)));
                 }
                 return true;
             }
@@ -589,13 +581,13 @@
     public Stream<? extends ZipEntry> stream() {
         synchronized (this) {
             ensureOpen();
-            return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total,
+            return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total,
                 pos -> getZipEntry(null, null, pos, ZipEntry::new)), false);
        }
     }
 
     private String getEntryName(int pos) {
-        byte[] cen = zsrc.cen;
+        byte[] cen = res.zsrc.cen;
         int nlen = CENNAM(cen, pos);
         int clen = CENCOM(cen, pos);
         int flag = CENFLG(cen, pos);
@@ -620,7 +612,7 @@
         synchronized (this) {
             ensureOpen();
             return StreamSupport.stream(
-                new EntrySpliterator<>(0, zsrc.total, this::getEntryName), false);
+                new EntrySpliterator<>(0, res.zsrc.total, this::getEntryName), false);
         }
     }
 
@@ -638,7 +630,7 @@
     private Stream<JarEntry> stream(Function<String, JarEntry> func) {
         synchronized (this) {
             ensureOpen();
-            return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total,
+            return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total,
                 pos -> (JarEntry)getZipEntry(null, null, pos, func)), false);
         }
     }
@@ -649,7 +641,7 @@
     /* Checks ensureOpen() before invoke this method */
     private ZipEntry getZipEntry(String name, byte[] bname, int pos,
                                  Function<String, ? extends ZipEntry> func) {
-        byte[] cen = zsrc.cen;
+        byte[] cen = res.zsrc.cen;
         int nlen = CENNAM(cen, pos);
         int elen = CENEXT(cen, pos);
         int clen = CENCOM(cen, pos);
@@ -698,12 +690,170 @@
     public int size() {
         synchronized (this) {
             ensureOpen();
-            return zsrc.total;
+            return res.zsrc.total;
+        }
+    }
+
+    private static class CleanableResource implements Runnable {
+        // The outstanding inputstreams that need to be closed
+        final Set<InputStream> istreams;
+
+        // List of cached Inflater objects for decompression
+        Deque<Inflater> inflaterCache;
+
+        final Cleanable cleanable;
+
+        Source zsrc;
+
+        CleanableResource(ZipFile zf, File file, int mode) throws IOException {
+            this.cleanable = CleanerFactory.cleaner().register(zf, this);
+            this.istreams = Collections.newSetFromMap(new WeakHashMap<>());
+            this.inflaterCache = new ArrayDeque<>();
+            this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
+        }
+
+        void clean() {
+            cleanable.clean();
+        }
+
+        /*
+         * Gets an inflater from the list of available inflaters or allocates
+         * a new one.
+         */
+        Inflater getInflater() {
+            Inflater inf;
+            synchronized (inflaterCache) {
+                if ((inf = inflaterCache.poll()) != null) {
+                    return inf;
+                }
+            }
+            return new Inflater(true);
+        }
+
+        /*
+         * Releases the specified inflater to the list of available inflaters.
+         */
+        void releaseInflater(Inflater inf) {
+            Deque<Inflater> inflaters = this.inflaterCache;
+            if (inflaters != null) {
+                synchronized (inflaters) {
+                    // double checked!
+                    if (inflaters == this.inflaterCache) {
+                        inf.reset();
+                        inflaters.add(inf);
+                        return;
+                    }
+                }
+            }
+            // inflaters cache already closed - just end it.
+            inf.end();
+        }
+
+        public void run() {
+            IOException ioe = null;
+
+            // Release cached inflaters and close the cache first
+            Deque<Inflater> inflaters = this.inflaterCache;
+            if (inflaters != null) {
+                synchronized (inflaters) {
+                    // no need to double-check as only one thread gets a
+                    // chance to execute run() (Cleaner guarantee)...
+                    Inflater inf;
+                    while ((inf = inflaters.poll()) != null) {
+                        inf.end();
+                    }
+                    // close inflaters cache
+                    this.inflaterCache = null;
+                }
+            }
+
+            // Close streams, release their inflaters
+            if (istreams != null) {
+                synchronized (istreams) {
+                    if (!istreams.isEmpty()) {
+                        InputStream[] copy = istreams.toArray(new InputStream[0]);
+                        istreams.clear();
+                        for (InputStream is : copy) {
+                            try {
+                                is.close();
+                            }  catch (IOException e) {
+                                if (ioe == null) ioe = e;
+                                else ioe.addSuppressed(e);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Release zip src
+            if (zsrc != null) {
+                synchronized (zsrc) {
+                    try {
+                        Source.release(zsrc);
+                        zsrc = null;
+                     }  catch (IOException e) {
+                         if (ioe == null) ioe = e;
+                         else ioe.addSuppressed(e);
+                    }
+                }
+            }
+            if (ioe != null) {
+                throw new UncheckedIOException(ioe);
+            }
+        }
+
+        CleanableResource(File file, int mode)
+            throws IOException {
+            this.cleanable = null;
+            this.istreams = Collections.newSetFromMap(new WeakHashMap<>());
+            this.inflaterCache = new ArrayDeque<>();
+            this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
+        }
+
+        /*
+         * If {@code ZipFile} has been subclassed and the {@code close} method is
+         * overridden, uses the {@code finalizer} mechanism for resource cleanup.
+         * So {@code close} method can be called when the the {@code ZipFile} is
+         * unreachable. This mechanism will be removed when {@code finalize} method
+         * is removed from {@code ZipFile}.
+         */
+        static CleanableResource get(ZipFile zf, File file, int mode)
+            throws IOException {
+            Class<?> clz = zf.getClass();
+            while (clz != ZipFile.class) {
+                try {
+                    clz.getDeclaredMethod("close");
+                    return new FinalizableResource(zf, file, mode);
+                } catch (NoSuchMethodException nsme) {}
+                clz = clz.getSuperclass();
+            }
+            return new CleanableResource(zf, file, mode);
+        }
+
+        static class FinalizableResource extends CleanableResource {
+            ZipFile zf;
+            FinalizableResource(ZipFile zf, File file, int mode)
+                throws IOException {
+                super(file, mode);
+                this.zf = zf;
+            }
+
+            @Override
+            void clean() {
+                run();
+            }
+
+            @Override
+            @SuppressWarnings("deprecation")
+            protected void finalize() throws IOException {
+                zf.close();
+            }
         }
     }
 
     /**
      * Closes the ZIP file.
+     *
      * <p> Closing this ZIP file will close all of the input streams
      * previously returned by invocations of the {@link #getInputStream
      * getInputStream} method.
@@ -717,31 +867,12 @@
         closeRequested = true;
 
         synchronized (this) {
-            // Close streams, release their inflaters
-            synchronized (streams) {
-                if (!streams.isEmpty()) {
-                    Map<InputStream, Inflater> copy = new HashMap<>(streams);
-                    streams.clear();
-                    for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
-                        e.getKey().close();
-                        Inflater inf = e.getValue();
-                        if (inf != null) {
-                            inf.end();
-                        }
-                    }
-                }
-            }
-            // Release cached inflaters
-            synchronized (inflaterCache) {
-                Inflater inf;
-                while ((inf = inflaterCache.poll()) != null) {
-                    inf.end();
-                }
-            }
-            // Release zip src
-            if (zsrc != null) {
-                Source.close(zsrc);
-                zsrc = null;
+            // Close streams, release their inflaters, release cached inflaters
+            // and release zip source
+            try {
+                res.clean();
+            } catch (UncheckedIOException ioe) {
+                throw ioe.getCause();
             }
         }
     }
@@ -750,34 +881,26 @@
      * Ensures that the system resources held by this ZipFile object are
      * released when there are no more references to it.
      *
-     * <p>
-     * Since the time when GC would invoke this method is undetermined,
-     * it is strongly recommended that applications invoke the {@code close}
-     * method as soon they have finished accessing this {@code ZipFile}.
-     * This will prevent holding up system resources for an undetermined
-     * length of time.
+     * @deprecated The {@code finalize} method has been deprecated and will be
+     *     removed. It is implemented as a no-op. Subclasses that override
+     *     {@code finalize} in order to perform cleanup should be modified to
+     *     use alternative cleanup mechanisms and to remove the overriding
+     *     {@code finalize} method. The recommended cleanup for ZipFile object
+     *     is to explicitly invoke {@code close} method when it is no longer in
+     *     use, or use try-with-resources. If the {@code close} is not invoked
+     *     explicitly the resources held by this object will be released when
+     *     the instance becomes unreachable.
      *
-     * @deprecated The {@code finalize} method has been deprecated.
-     *     Subclasses that override {@code finalize} in order to perform cleanup
-     *     should be modified to use alternative cleanup mechanisms and
-     *     to remove the overriding {@code finalize} method.
-     *     When overriding the {@code finalize} method, its implementation must explicitly
-     *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
-     *     See the specification for {@link Object#finalize()} for further
-     *     information about migration options.
      * @throws IOException if an I/O error has occurred
-     * @see    java.util.zip.ZipFile#close()
      */
-    @Deprecated(since="9")
-    protected void finalize() throws IOException {
-        close();
-    }
+    @Deprecated(since="9", forRemoval=true)
+    protected void finalize() throws IOException {}
 
     private void ensureOpen() {
         if (closeRequested) {
             throw new IllegalStateException("zip file closed");
         }
-        if (zsrc == null) {
+        if (res.zsrc == null) {
             throw new IllegalStateException("The object is not initialized.");
         }
     }
@@ -798,7 +921,7 @@
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
 
-        ZipFileInputStream(byte[] cen, int cenpos) throws IOException {
+        ZipFileInputStream(byte[] cen, int cenpos) {
             rem = CENSIZ(cen, cenpos);
             size = CENLEN(cen, cenpos);
             pos = CENOFF(cen, cenpos);
@@ -808,10 +931,10 @@
                 checkZIP64(cen, cenpos);
             }
             // negative for lazy initialization, see getDataOffset();
-            pos = - (pos + ZipFile.this.zsrc.locpos);
+            pos = - (pos + ZipFile.this.res.zsrc.locpos);
         }
 
-        private void checkZIP64(byte[] cen, int cenpos) throws IOException {
+         private void checkZIP64(byte[] cen, int cenpos) {
             int off = cenpos + CENHDR + CENNAM(cen, cenpos);
             int end = off + CENEXT(cen, cenpos);
             while (off + 4 < end) {
@@ -857,7 +980,7 @@
             if (pos <= 0) {
                 byte[] loc = new byte[LOCHDR];
                 pos = -pos;
-                int len = ZipFile.this.zsrc.readFullyAt(loc, 0, loc.length, pos);
+                int len = ZipFile.this.res.zsrc.readFullyAt(loc, 0, loc.length, pos);
                 if (len != LOCHDR) {
                     throw new ZipException("ZipFile error reading zip file");
                 }
@@ -882,7 +1005,7 @@
                 if (len <= 0) {
                     return 0;
                 }
-                len = ZipFile.this.zsrc.readAt(b, off, len, pos);
+                len = ZipFile.this.res.zsrc.readAt(b, off, len, pos);
                 if (len > 0) {
                     pos += len;
                     rem -= len;
@@ -932,15 +1055,11 @@
             }
             closeRequested = true;
             rem = 0;
-            synchronized (streams) {
-                streams.remove(this);
+            synchronized (res.istreams) {
+                res.istreams.remove(this);
             }
         }
 
-        @SuppressWarnings("deprecation")
-        protected void finalize() {
-            close();
-        }
     }
 
     /**
@@ -952,6 +1071,7 @@
     private String[] getMetaInfEntryNames() {
         synchronized (this) {
             ensureOpen();
+            Source zsrc = res.zsrc;
             if (zsrc.metanames == null) {
                 return null;
             }
@@ -972,7 +1092,7 @@
             new JavaUtilZipFileAccess() {
                 @Override
                 public boolean startsWithLocHeader(ZipFile zip) {
-                    return zip.zsrc.startsWithLoc;
+                    return zip.res.zsrc.startsWithLoc;
                 }
                 @Override
                 public String[] getMetaInfEntryNames(ZipFile zip) {
@@ -1080,7 +1200,7 @@
         private static final HashMap<Key, Source> files = new HashMap<>();
 
 
-        public static Source get(File file, boolean toDelete) throws IOException {
+        static Source get(File file, boolean toDelete) throws IOException {
             Key key = new Key(file,
                               Files.readAttributes(file.toPath(), BasicFileAttributes.class));
             Source src = null;
@@ -1105,9 +1225,9 @@
             }
         }
 
-        private static void close(Source src) throws IOException {
+        static void release(Source src) throws IOException {
             synchronized (files) {
-                if (--src.refs == 0) {
+                if (src != null && --src.refs == 0) {
                     files.remove(src.key);
                     src.close();
                 }
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Wed Dec 13 10:56:50 2017 -0800
@@ -254,4 +254,23 @@
      * given class loader.
      */
     Stream<ModuleLayer> layers(ClassLoader loader);
+
+    /**
+     * Returns a new string by decoding from the given utf8 bytes array.
+     *
+     * @param off the index of the first byte to decode
+     * @param len the number of bytes to decode
+     * @return the newly created string
+     * @throws IllegalArgumentException for malformed or unmappable bytes.
+     */
+    String newStringUTF8NoRepl(byte[] bytes, int off, int len);
+
+    /**
+     * Encode the given string into a sequence of bytes using utf8.
+     *
+     * @param s the string to encode
+     * @return the encoded bytes in utf8
+     * @throws IllegalArgumentException for malformed surrogates
+     */
+    byte[] getBytesUTF8NoRepl(String s);
 }
--- a/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package jdk.internal.util.xml;
 
 import java.io.*;
+import java.nio.charset.Charset;
 import java.util.InvalidPropertiesFormatException;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -94,11 +95,11 @@
          */
     }
 
-    public void store(Properties props, OutputStream os, String comment, String encoding)
+    public void store(Properties props, OutputStream os, String comment, Charset charset)
         throws IOException
     {
         try {
-            XMLStreamWriter writer = new XMLStreamWriterImpl(os, encoding);
+            XMLStreamWriter writer = new XMLStreamWriterImpl(os, charset);
             writer.writeStartDocument();
             writer.writeDTD(PROPS_DTD_DECL);
             writer.writeStartElement(ELEMENT_ROOT);
--- a/src/java.base/share/classes/jdk/internal/util/xml/XMLStreamWriter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/util/xml/XMLStreamWriter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,9 @@
 
 package jdk.internal.util.xml;
 
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
 /**
  * Basic XMLStreamWriter for writing simple XML files such as those
  * defined in java.util.Properties
@@ -38,6 +41,7 @@
     //Defaults the XML version to 1.0, and the encoding to utf-8
     public static final String DEFAULT_XML_VERSION = "1.0";
     public static final String DEFAULT_ENCODING = "UTF-8";
+    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
 
     /**
      * Writes a start tag to the output.  All writeStartElement methods
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@
     private int _state = 0;
     private Element _currentEle;
     private XMLWriter _writer;
-    private String _encoding;
+    private Charset _charset;
     /**
      * This flag can be used to turn escaping off for content. It does
      * not apply to attribute content.
@@ -79,26 +79,23 @@
             System.getProperty("line.separator").toCharArray();
 
     public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException {
-        this(os, XMLStreamWriter.DEFAULT_ENCODING);
+        this(os, XMLStreamWriter.DEFAULT_CHARSET);
     }
 
-    public XMLStreamWriterImpl(OutputStream os, String encoding)
+    public XMLStreamWriterImpl(OutputStream os, Charset cs)
         throws XMLStreamException
     {
-        Charset cs = null;
-        if (encoding == null) {
-            _encoding = XMLStreamWriter.DEFAULT_ENCODING;
+        if (cs == null) {
+            _charset = XMLStreamWriter.DEFAULT_CHARSET;
         } else {
             try {
-                cs = getCharset(encoding);
+                _charset = checkCharset(cs);
             } catch (UnsupportedEncodingException e) {
                 throw new XMLStreamException(e);
             }
-
-            this._encoding = encoding;
         }
 
-        _writer = new XMLWriter(os, encoding, cs);
+        _writer = new XMLWriter(os, null, _charset);
     }
 
     /**
@@ -108,7 +105,7 @@
      * @throws XMLStreamException
      */
     public void writeStartDocument() throws XMLStreamException {
-        writeStartDocument(_encoding, XMLStreamWriter.DEFAULT_XML_VERSION);
+        writeStartDocument(_charset.name(), XMLStreamWriter.DEFAULT_XML_VERSION);
     }
 
     /**
@@ -118,7 +115,7 @@
      * @throws XMLStreamException
      */
     public void writeStartDocument(String version) throws XMLStreamException {
-        writeStartDocument(_encoding, version, null);
+        writeStartDocument(_charset.name(), version, null);
     }
 
     /**
@@ -155,7 +152,7 @@
         _state = STATE_XML_DECL;
         String enc = encoding;
         if (enc == null) {
-            enc = _encoding;
+            enc = _charset.name();
         } else {
             //check if the encoding is supported
             try {
@@ -564,6 +561,20 @@
         return cs;
     }
 
+    /**
+     * Checks for charset support.
+     * @param charset the specified charset
+     * @return the charset
+     * @throws UnsupportedEncodingException if the charset is not supported
+     */
+    private Charset checkCharset(Charset charset) throws UnsupportedEncodingException {
+        if (charset.name().equalsIgnoreCase("UTF-32")) {
+            throw new UnsupportedEncodingException("The basic XMLWriter does "
+                    + "not support " + charset.name());
+        }
+        return charset;
+    }
+
     /*
      * Start of Internal classes.
      *
--- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Wed Dec 13 10:56:50 2017 -0800
@@ -268,7 +268,7 @@
         Locale locale = Locale.getDefault();
         ostream.println(LOCALE_SETTINGS);
         ostream.println(INDENT + "default locale = " +
-                locale.getDisplayLanguage());
+                locale.getDisplayName());
         ostream.println(INDENT + "default display locale = " +
                 Locale.getDefault(Category.DISPLAY).getDisplayName());
         ostream.println(INDENT + "default format locale = " +
--- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Wed Dec 13 10:56:50 2017 -0800
@@ -63,8 +63,8 @@
         return new Encoder(this);
     }
 
-    private static class Decoder extends CharsetDecoder
-                                 implements ArrayDecoder {
+    private static class Decoder extends CharsetDecoder {
+
         private Decoder(Charset cs) {
             super(cs, 1.0f, 1.0f);
         }
@@ -124,23 +124,10 @@
             else
                 return decodeBufferLoop(src, dst);
         }
-
-        public int decode(byte[] src, int sp, int len, char[] dst) {
-            if (len > dst.length)
-                len = dst.length;
-            int dp = 0;
-            while (dp < len)
-                dst[dp++] = (char)(src[sp++] & 0xff);
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
 
-    private static class Encoder extends CharsetEncoder
-                                 implements ArrayEncoder {
+    private static class Encoder extends CharsetEncoder {
+
         private Encoder(Charset cs) {
             super(cs, 1.0f, 1.0f);
         }
@@ -271,39 +258,5 @@
             else
                 return encodeBufferLoop(src, dst);
         }
-
-        private byte repl = (byte)'?';
-        protected void implReplaceWith(byte[] newReplacement) {
-            repl = newReplacement[0];
-        }
-
-        public int encode(char[] src, int sp, int len, byte[] dst) {
-            int dp = 0;
-            int slen = Math.min(len, dst.length);
-            int sl = sp + slen;
-            while (sp < sl) {
-                int ret = encodeISOArray(src, sp, dst, dp, slen);
-                sp = sp + ret;
-                dp = dp + ret;
-                if (ret != slen) {
-                    char c = src[sp++];
-                    if (Character.isHighSurrogate(c) && sp < sl &&
-                        Character.isLowSurrogate(src[sp])) {
-                        if (len > dst.length) {
-                            sl++;
-                            len--;
-                        }
-                        sp++;
-                    }
-                    dst[dp++] = repl;
-                    slen = Math.min((sl - sp), (dst.length - dp));
-                }
-            }
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
 }
--- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Wed Dec 13 10:56:50 2017 -0800
@@ -58,8 +58,7 @@
         return new Encoder(this);
     }
 
-    private static class Decoder extends CharsetDecoder
-                                 implements ArrayDecoder {
+    private static class Decoder extends CharsetDecoder {
 
         private Decoder(Charset cs) {
             super(cs, 1.0f, 1.0f);
@@ -128,32 +127,9 @@
             else
                 return decodeBufferLoop(src, dst);
         }
-
-        private char repl = '\uFFFD';
-        protected void implReplaceWith(String newReplacement) {
-            repl = newReplacement.charAt(0);
-        }
-
-        public int decode(byte[] src, int sp, int len, char[] dst) {
-            int dp = 0;
-            len = Math.min(len, dst.length);
-            while (dp < len) {
-                byte b = src[sp++];
-                if (b >= 0)
-                    dst[dp++] = (char)b;
-                else
-                    dst[dp++] = repl;
-            }
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
 
-    private static class Encoder extends CharsetEncoder
-                                 implements ArrayEncoder {
+    private static class Encoder extends CharsetEncoder {
 
         private Encoder(Charset cs) {
             super(cs, 1.0f, 1.0f);
@@ -237,36 +213,5 @@
                 return encodeBufferLoop(src, dst);
         }
 
-        private byte repl = (byte)'?';
-        protected void implReplaceWith(byte[] newReplacement) {
-            repl = newReplacement[0];
-        }
-
-        public int encode(char[] src, int sp, int len, byte[] dst) {
-            int dp = 0;
-            int sl = sp + Math.min(len, dst.length);
-            while (sp < sl) {
-                char c = src[sp++];
-                if (c < 0x80) {
-                    dst[dp++] = (byte)c;
-                    continue;
-                }
-                if (Character.isHighSurrogate(c) && sp < sl &&
-                    Character.isLowSurrogate(src[sp])) {
-                    if (len > dst.length) {
-                        sl++;
-                        len--;
-                    }
-                    sp++;
-                }
-                dst[dp++] = repl;
-            }
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
-
 }
--- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Wed Dec 13 10:56:50 2017 -0800
@@ -80,8 +80,8 @@
         dst.position(dp - dst.arrayOffset());
     }
 
-    private static class Decoder extends CharsetDecoder
-                                 implements ArrayDecoder {
+    private static class Decoder extends CharsetDecoder {
+
         private Decoder(Charset cs) {
             super(cs, 1.0f, 1.0f);
         }
@@ -423,142 +423,9 @@
             bb.position(sp);
             return bb;
         }
-
-        // returns -1 if there is/are malformed byte(s) and the
-        // "action" for malformed input is not REPLACE.
-        public int decode(byte[] sa, int sp, int len, char[] da) {
-            final int sl = sp + len;
-            int dp = 0;
-            int dlASCII = Math.min(len, da.length);
-            ByteBuffer bb = null;  // only necessary if malformed
-
-            // ASCII only optimized loop
-            while (dp < dlASCII && sa[sp] >= 0)
-                da[dp++] = (char) sa[sp++];
-
-            while (sp < sl) {
-                int b1 = sa[sp++];
-                if (b1 >= 0) {
-                    // 1 byte, 7 bits: 0xxxxxxx
-                    da[dp++] = (char) b1;
-                } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
-                    // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
-                    if (sp < sl) {
-                        int b2 = sa[sp++];
-                        if (isNotContinuation(b2)) {
-                            if (malformedInputAction() != CodingErrorAction.REPLACE)
-                                return -1;
-                            da[dp++] = replacement().charAt(0);
-                            sp--;            // malformedN(bb, 2) always returns 1
-                        } else {
-                            da[dp++] = (char) (((b1 << 6) ^ b2)^
-                                           (((byte) 0xC0 << 6) ^
-                                            ((byte) 0x80 << 0)));
-                        }
-                        continue;
-                    }
-                    if (malformedInputAction() != CodingErrorAction.REPLACE)
-                        return -1;
-                    da[dp++] = replacement().charAt(0);
-                    return dp;
-                } else if ((b1 >> 4) == -2) {
-                    // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
-                    if (sp + 1 < sl) {
-                        int b2 = sa[sp++];
-                        int b3 = sa[sp++];
-                        if (isMalformed3(b1, b2, b3)) {
-                            if (malformedInputAction() != CodingErrorAction.REPLACE)
-                                return -1;
-                            da[dp++] = replacement().charAt(0);
-                            sp -= 3;
-                            bb = getByteBuffer(bb, sa, sp);
-                            sp += malformedN(bb, 3).length();
-                        } else {
-                            char c = (char)((b1 << 12) ^
-                                              (b2 <<  6) ^
-                                              (b3 ^
-                                              (((byte) 0xE0 << 12) ^
-                                              ((byte) 0x80 <<  6) ^
-                                              ((byte) 0x80 <<  0))));
-                            if (Character.isSurrogate(c)) {
-                                if (malformedInputAction() != CodingErrorAction.REPLACE)
-                                    return -1;
-                                da[dp++] = replacement().charAt(0);
-                            } else {
-                                da[dp++] = c;
-                            }
-                        }
-                        continue;
-                    }
-                    if (malformedInputAction() != CodingErrorAction.REPLACE)
-                        return -1;
-                    if (sp  < sl && isMalformed3_2(b1, sa[sp])) {
-                        da[dp++] = replacement().charAt(0);
-                        continue;
-
-                    }
-                    da[dp++] = replacement().charAt(0);
-                    return dp;
-                } else if ((b1 >> 3) == -2) {
-                    // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-                    if (sp + 2 < sl) {
-                        int b2 = sa[sp++];
-                        int b3 = sa[sp++];
-                        int b4 = sa[sp++];
-                        int uc = ((b1 << 18) ^
-                                  (b2 << 12) ^
-                                  (b3 <<  6) ^
-                                  (b4 ^
-                                   (((byte) 0xF0 << 18) ^
-                                   ((byte) 0x80 << 12) ^
-                                   ((byte) 0x80 <<  6) ^
-                                   ((byte) 0x80 <<  0))));
-                        if (isMalformed4(b2, b3, b4) ||
-                            // shortest form check
-                            !Character.isSupplementaryCodePoint(uc)) {
-                            if (malformedInputAction() != CodingErrorAction.REPLACE)
-                                return -1;
-                            da[dp++] = replacement().charAt(0);
-                            sp -= 4;
-                            bb = getByteBuffer(bb, sa, sp);
-                            sp += malformedN(bb, 4).length();
-                        } else {
-                            da[dp++] = Character.highSurrogate(uc);
-                            da[dp++] = Character.lowSurrogate(uc);
-                        }
-                        continue;
-                    }
-                    if (malformedInputAction() != CodingErrorAction.REPLACE)
-                        return -1;
-                    b1 &= 0xff;
-                    if (b1 > 0xf4 ||
-                        sp  < sl && isMalformed4_2(b1, sa[sp] & 0xff)) {
-                        da[dp++] = replacement().charAt(0);
-                        continue;
-                    }
-                    sp++;
-                    if (sp  < sl && isMalformed4_3(sa[sp])) {
-                        da[dp++] = replacement().charAt(0);
-                        continue;
-                    }
-                    da[dp++] = replacement().charAt(0);
-                    return dp;
-                } else {
-                    if (malformedInputAction() != CodingErrorAction.REPLACE)
-                        return -1;
-                    da[dp++] = replacement().charAt(0);
-                }
-            }
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
 
-    private static final class Encoder extends CharsetEncoder
-                                 implements ArrayEncoder {
+    private static final class Encoder extends CharsetEncoder {
 
         private Encoder(Charset cs) {
             super(cs, 1.1f, 3.0f);
@@ -699,58 +566,5 @@
                 return encodeBufferLoop(src, dst);
         }
 
-        private byte repl = (byte)'?';
-        protected void implReplaceWith(byte[] newReplacement) {
-            repl = newReplacement[0];
-        }
-
-        // returns -1 if there is malformed char(s) and the
-        // "action" for malformed input is not REPLACE.
-        public int encode(char[] sa, int sp, int len, byte[] da) {
-            int sl = sp + len;
-            int dp = 0;
-            int dlASCII = dp + Math.min(len, da.length);
-
-            // ASCII only optimized loop
-            while (dp < dlASCII && sa[sp] < '\u0080')
-                da[dp++] = (byte) sa[sp++];
-
-            while (sp < sl) {
-                char c = sa[sp++];
-                if (c < 0x80) {
-                    // Have at most seven bits
-                    da[dp++] = (byte)c;
-                } else if (c < 0x800) {
-                    // 2 bytes, 11 bits
-                    da[dp++] = (byte)(0xc0 | (c >> 6));
-                    da[dp++] = (byte)(0x80 | (c & 0x3f));
-                } else if (Character.isSurrogate(c)) {
-                    if (sgp == null)
-                        sgp = new Surrogate.Parser();
-                    int uc = sgp.parse(c, sa, sp - 1, sl);
-                    if (uc < 0) {
-                        if (malformedInputAction() != CodingErrorAction.REPLACE)
-                            return -1;
-                        da[dp++] = repl;
-                    } else {
-                        da[dp++] = (byte)(0xf0 | ((uc >> 18)));
-                        da[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
-                        da[dp++] = (byte)(0x80 | ((uc >>  6) & 0x3f));
-                        da[dp++] = (byte)(0x80 | (uc & 0x3f));
-                        sp++;  // 2 chars
-                    }
-                } else {
-                    // 3 bytes, 16 bits
-                    da[dp++] = (byte)(0xe0 | ((c >> 12)));
-                    da[dp++] = (byte)(0x80 | ((c >>  6) & 0x3f));
-                    da[dp++] = (byte)(0x80 | (c & 0x3f));
-                }
-            }
-            return dp;
-        }
-
-        public boolean isASCIICompatible() {
-            return true;
-        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRCalendarDataProviderImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.cldr;
+
+import static sun.util.locale.provider.LocaleProviderAdapter.Type;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleResources;
+import sun.util.locale.provider.CalendarDataProviderImpl;
+import sun.util.locale.provider.CalendarDataUtility;
+
+/**
+ * Concrete implementation of the
+ * {@link java.util.spi.CalendarDataProvider CalendarDataProvider} class
+ * for the CLDR LocaleProviderAdapter.
+ *
+ * @author Naoto Sato
+ */
+public class CLDRCalendarDataProviderImpl extends CalendarDataProviderImpl {
+
+    private static Map<String, Integer> firstDay = new ConcurrentHashMap<>();
+    private static Map<String, Integer> minDays = new ConcurrentHashMap<>();
+
+    public CLDRCalendarDataProviderImpl(Type type, Set<String> langtags) {
+        super(type, langtags);
+    }
+
+    @Override
+    public int getFirstDayOfWeek(Locale locale) {
+        return findValue(CalendarDataUtility.FIRST_DAY_OF_WEEK, locale);
+    }
+
+    @Override
+    public int getMinimalDaysInFirstWeek(Locale locale) {
+        return findValue(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK, locale);
+    }
+
+    /**
+     * Finds the requested integer value for the locale.
+     * Each resource consists of the following:
+     *
+     *    (n: cc1 cc2 ... ccx;)*
+     *
+     * where 'n' is the integer for the following region codes, terminated by
+     * a ';'.
+     *
+     */
+    private static int findValue(String key, Locale locale) {
+        Map<String, Integer> map = CalendarDataUtility.FIRST_DAY_OF_WEEK.equals(key) ?
+            firstDay : minDays;
+        String region = locale.getCountry();
+
+        if (region.isEmpty()) {
+            return 0;
+        }
+
+        Integer val = map.get(region);
+        if (val == null) {
+            String valStr =
+                LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(Locale.ROOT)
+                   .getCalendarData(key);
+            val = retrieveInteger(valStr, region)
+                .orElse(retrieveInteger(valStr, "001").orElse(0));
+            map.putIfAbsent(region, val);
+        }
+
+        return val;
+    }
+
+    private static Optional<Integer> retrieveInteger(String src, String region) {
+        return Arrays.stream(src.split(";"))
+            .filter(entry -> entry.contains(region))
+            .map(entry -> entry.substring(0, entry.indexOf(":")))
+            .findAny()
+            .map(Integer::parseInt);
+    }
+}
--- a/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -27,6 +27,7 @@
 
 import java.security.AccessController;
 import java.security.AccessControlException;
+import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.text.spi.BreakIteratorProvider;
@@ -37,15 +38,16 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Objects;
+import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.ServiceConfigurationError;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.spi.CalendarDataProvider;
 import sun.util.locale.provider.JRELocaleProviderAdapter;
+import sun.util.locale.provider.LocaleDataMetaInfo;
 import sun.util.locale.provider.LocaleProviderAdapter;
-import sun.util.locale.provider.LocaleDataMetaInfo;
 
 /**
  * LocaleProviderAdapter implementation for the CLDR locale data.
@@ -106,6 +108,24 @@
     }
 
     @Override
+    public CalendarDataProvider getCalendarDataProvider() {
+        if (calendarDataProvider == null) {
+            CalendarDataProvider provider = AccessController.doPrivileged(
+                (PrivilegedAction<CalendarDataProvider>) () ->
+                    new CLDRCalendarDataProviderImpl(
+                        getAdapterType(),
+                        getLanguageTagSet("CalendarData")));
+
+            synchronized (this) {
+                if (calendarDataProvider == null) {
+                    calendarDataProvider = provider;
+                }
+            }
+        }
+        return calendarDataProvider;
+    }
+
+    @Override
     public CollatorProvider getCollatorProvider() {
         return null;
     }
@@ -123,6 +143,10 @@
 
     @Override
     protected Set<String> createLanguageTagSet(String category) {
+        // Assume all categories support the same set as AvailableLocales
+        // in CLDR adapter.
+        category = "AvailableLocales";
+
         // Directly call Base tags, as we know it's in the base module.
         String supportedLocaleString = baseMetaInfo.availableLanguageTags(category);
         String nonBaseTags = null;
@@ -220,4 +244,11 @@
                 || langtags.contains(locale.stripExtensions().toLanguageTag())
                 || langtags.contains(getEquivalentLoc(locale).toLanguageTag());
     }
+
+    /**
+     * Returns the time zone ID from an LDML's short ID
+     */
+    public Optional<String> getTimeZoneID(String shortID) {
+        return Optional.ofNullable(baseMetaInfo.tzShortIDs().get(shortID));
+    }
 }
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,14 +46,16 @@
 
     @Override
     public int getFirstDayOfWeek(Locale locale) {
-        return LocaleProviderAdapter.forType(type).getLocaleResources(locale)
+        String fw = LocaleProviderAdapter.forType(type).getLocaleResources(locale)
                    .getCalendarData(CalendarDataUtility.FIRST_DAY_OF_WEEK);
+        return convertToCalendarData(fw);
     }
 
     @Override
     public int getMinimalDaysInFirstWeek(Locale locale) {
-        return LocaleProviderAdapter.forType(type).getLocaleResources(locale)
+        String md = LocaleProviderAdapter.forType(type).getLocaleResources(locale)
                    .getCalendarData(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK);
+        return convertToCalendarData(md);
     }
 
     @Override
@@ -65,4 +67,9 @@
     public Set<String> getAvailableLanguageTags() {
         return langtags;
     }
+
+    private int convertToCalendarData(String src) {
+        int val = Integer.parseInt(src);
+        return (src.isEmpty() || val <= 0 || val > 7) ? 0 : val;
+    }
 }
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,10 +47,34 @@
     }
 
     public static int retrieveFirstDayOfWeek(Locale locale) {
+        // Look for the Unicode Extension in the locale parameter
+        if (locale.hasExtensions()) {
+            String fw = locale.getUnicodeLocaleType("fw");
+            if (fw != null) {
+                switch (fw.toLowerCase(Locale.ROOT)) {
+                    case "mon":
+                        return MONDAY;
+                    case "tue":
+                        return TUESDAY;
+                    case "wed":
+                        return WEDNESDAY;
+                    case "thu":
+                        return THURSDAY;
+                    case "fri":
+                        return FRIDAY;
+                    case "sat":
+                        return SATURDAY;
+                    case "sun":
+                        return SUNDAY;
+                }
+            }
+        }
+
         LocaleServiceProviderPool pool =
                 LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
         Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
-                                                locale, true, FIRST_DAY_OF_WEEK);
+                                                findRegionOverride(locale),
+                                                true, FIRST_DAY_OF_WEEK);
         return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY;
     }
 
@@ -58,7 +82,8 @@
         LocaleServiceProviderPool pool =
                 LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
         Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
-                                                locale, true, MINIMAL_DAYS_IN_FIRST_WEEK);
+                                                findRegionOverride(locale),
+                                                true, MINIMAL_DAYS_IN_FIRST_WEEK);
         return (value != null && (value >= 1 && value <= 7)) ? value : 1;
     }
 
@@ -102,6 +127,32 @@
         return map;
     }
 
+    /**
+     * Utility to look for a region override extension.
+     * If no region override is found, returns the original locale.
+     */
+    public static Locale findRegionOverride(Locale l) {
+        String rg = l.getUnicodeLocaleType("rg");
+        Locale override = l;
+
+        if (rg != null && rg.length() == 6) {
+            // UN M.49 code should not be allowed here
+            // cannot use regex here, as it could be a recursive call
+            rg = rg.toUpperCase(Locale.ROOT);
+            if (rg.charAt(0) >= 0x0041 &&
+                rg.charAt(0) <= 0x005A &&
+                rg.charAt(1) >= 0x0041 &&
+                rg.charAt(1) <= 0x005A &&
+                rg.substring(2).equals("ZZZZ")) {
+                override = new Locale.Builder().setLocale(l)
+                    .setRegion(rg.substring(0, 2))
+                    .build();
+            }
+        }
+
+        return override;
+    }
+
     static String normalizeCalendarType(String requestID) {
         String type;
         if (requestID.equals("gregorian") || requestID.equals("iso8601")) {
@@ -179,7 +230,7 @@
         }
     }
 
-     private static class CalendarWeekParameterGetter
+    private static class CalendarWeekParameterGetter
         implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,
                                                                    Integer> {
         private static final CalendarWeekParameterGetter INSTANCE =
--- a/src/java.base/share/classes/sun/util/locale/provider/DateFormatProviderImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/DateFormatProviderImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.Set;
+import java.util.TimeZone;
 
 /**
  * Concrete implementation of the  {@link java.text.spi.DateFormatProvider
@@ -147,11 +148,14 @@
             throw new NullPointerException();
         }
 
-        SimpleDateFormat sdf = new SimpleDateFormat("", locale);
+        // Check for region override
+        Locale rg = CalendarDataUtility.findRegionOverride(locale);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("", rg);
         Calendar cal = sdf.getCalendar();
         try {
             String pattern = LocaleProviderAdapter.forType(type)
-                .getLocaleResources(locale).getDateTimePattern(timeStyle, dateStyle,
+                .getLocaleResources(rg).getDateTimePattern(timeStyle, dateStyle,
                                                                cal);
             sdf.applyPattern(pattern);
         } catch (MissingResourceException mre) {
@@ -159,6 +163,15 @@
             sdf.applyPattern("M/d/yy h:mm a");
         }
 
+        // Check for timezone override
+        String tz = locale.getUnicodeLocaleType("tz");
+        if (tz != null) {
+            sdf.setTimeZone(
+                TimeZoneNameUtility.convertLDMLShortID(tz)
+                    .map(TimeZone::getTimeZone)
+                    .orElseGet(sdf::getTimeZone));
+        }
+
         return sdf;
     }
 
--- a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,7 +130,7 @@
     private volatile CurrencyNameProvider currencyNameProvider;
     private volatile LocaleNameProvider localeNameProvider;
     private volatile TimeZoneNameProvider timeZoneNameProvider;
-    private volatile CalendarDataProvider calendarDataProvider;
+    protected volatile CalendarDataProvider calendarDataProvider;
     private volatile CalendarNameProvider calendarNameProvider;
 
     private volatile CalendarProvider calendarProvider;
--- a/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package sun.util.locale.provider;
 
+import java.util.Map;
+
 /**
  * LocaleData meta info SPI
  *
@@ -46,4 +48,13 @@
      * @return concatenated language tags, separated by a space.
      */
     public String availableLanguageTags(String category);
+
+    /**
+     * Returns a map for short time zone ids in BCP47 Unicode extension and
+     * the long time zone ids.
+     * @return map of short id to long ids, separated by a space.
+     */
+    default public Map<String, String>  tzShortIDs() {
+        return null;
+    }
 }
--- a/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -168,6 +168,28 @@
         return getDisplayString("%%"+vrnt, locale);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public String getDisplayUnicodeExtensionKey(String key, Locale locale) {
+        super.getDisplayUnicodeExtensionKey(key, locale); // null check
+        String rbKey = "key." + key;
+        String name = getDisplayString(rbKey, locale);
+        return rbKey.equals(name) ? key : name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public String getDisplayUnicodeExtensionType(String extType, String key, Locale locale) {
+        super.getDisplayUnicodeExtensionType(extType, key, locale); // null check
+        String rbKey = "type." + key + "." + extType;
+        String name = getDisplayString(rbKey, locale);
+        return rbKey.equals(name) ? extType : name;
+    }
+
     private String getDisplayString(String key, Locale locale) {
         if (key == null || locale == null) {
             throw new NullPointerException();
--- a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,23 +122,21 @@
         return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key);
     }
 
-    int getCalendarData(String key) {
-        Integer caldata;
+    public String getCalendarData(String key) {
+        String caldata = "";
         String cacheKey = CALENDAR_DATA  + key;
 
         removeEmptyReferences();
 
         ResourceReference data = cache.get(cacheKey);
-        if (data == null || ((caldata = (Integer) data.get()) == null)) {
+        if (data == null || ((caldata = (String) data.get()) == null)) {
             ResourceBundle rb = localeData.getCalendarData(locale);
             if (rb.containsKey(key)) {
-                caldata = Integer.parseInt(rb.getString(key));
-            } else {
-                caldata = 0;
+                caldata = rb.getString(key);
             }
 
             cache.put(cacheKey,
-                      new ResourceReference(cacheKey, (Object) caldata, referenceQueue));
+                      new ResourceReference(cacheKey, caldata, referenceQueue));
         }
 
         return caldata;
--- a/src/java.base/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,9 +173,14 @@
             throw new NullPointerException();
         }
 
+        // Check for region override
+        Locale override = locale.getUnicodeLocaleType("nu") == null ?
+            CalendarDataUtility.findRegionOverride(locale) :
+            locale;
+
         LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type);
-        String[] numberPatterns = adapter.getLocaleResources(locale).getNumberPatterns();
-        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
+        String[] numberPatterns = adapter.getLocaleResources(override).getNumberPatterns();
+        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(override);
         int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
         DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
 
--- a/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -160,28 +160,24 @@
         @Override
         public BreakIterator getWordInstance(Locale locale) {
             BreakIteratorProvider bip = getImpl(locale);
-            assert bip != null;
             return bip.getWordInstance(locale);
         }
 
         @Override
         public BreakIterator getLineInstance(Locale locale) {
             BreakIteratorProvider bip = getImpl(locale);
-            assert bip != null;
             return bip.getLineInstance(locale);
         }
 
         @Override
         public BreakIterator getCharacterInstance(Locale locale) {
             BreakIteratorProvider bip = getImpl(locale);
-            assert bip != null;
             return bip.getCharacterInstance(locale);
         }
 
         @Override
         public BreakIterator getSentenceInstance(Locale locale) {
             BreakIteratorProvider bip = getImpl(locale);
-            assert bip != null;
             return bip.getSentenceInstance(locale);
         }
 
@@ -215,7 +211,6 @@
         @Override
         public Collator getInstance(Locale locale) {
             CollatorProvider cp = getImpl(locale);
-            assert cp != null;
             return cp.getInstance(locale);
         }
     }
@@ -249,21 +244,18 @@
         @Override
         public DateFormat getTimeInstance(int style, Locale locale) {
             DateFormatProvider dfp = getImpl(locale);
-            assert dfp != null;
             return dfp.getTimeInstance(style, locale);
         }
 
         @Override
         public DateFormat getDateInstance(int style, Locale locale) {
             DateFormatProvider dfp = getImpl(locale);
-            assert dfp != null;
             return dfp.getDateInstance(style, locale);
         }
 
         @Override
         public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
             DateFormatProvider dfp = getImpl(locale);
-            assert dfp != null;
             return dfp.getDateTimeInstance(dateStyle, timeStyle, locale);
         }
     }
@@ -297,7 +289,6 @@
         @Override
         public DateFormatSymbols getInstance(Locale locale) {
             DateFormatSymbolsProvider dfsp = getImpl(locale);
-            assert dfsp != null;
             return dfsp.getInstance(locale);
         }
     }
@@ -331,7 +322,6 @@
         @Override
         public DecimalFormatSymbols getInstance(Locale locale) {
             DecimalFormatSymbolsProvider dfsp = getImpl(locale);
-            assert dfsp != null;
             return dfsp.getInstance(locale);
         }
     }
@@ -365,28 +355,24 @@
         @Override
         public NumberFormat getCurrencyInstance(Locale locale) {
             NumberFormatProvider nfp = getImpl(locale);
-            assert nfp != null;
             return nfp.getCurrencyInstance(locale);
         }
 
         @Override
         public NumberFormat getIntegerInstance(Locale locale) {
             NumberFormatProvider nfp = getImpl(locale);
-            assert nfp != null;
             return nfp.getIntegerInstance(locale);
         }
 
         @Override
         public NumberFormat getNumberInstance(Locale locale) {
             NumberFormatProvider nfp = getImpl(locale);
-            assert nfp != null;
             return nfp.getNumberInstance(locale);
         }
 
         @Override
         public NumberFormat getPercentInstance(Locale locale) {
             NumberFormatProvider nfp = getImpl(locale);
-            assert nfp != null;
             return nfp.getPercentInstance(locale);
         }
     }
@@ -420,14 +406,12 @@
         @Override
         public int getFirstDayOfWeek(Locale locale) {
             CalendarDataProvider cdp = getImpl(locale);
-            assert cdp != null;
             return cdp.getFirstDayOfWeek(locale);
         }
 
         @Override
         public int getMinimalDaysInFirstWeek(Locale locale) {
             CalendarDataProvider cdp = getImpl(locale);
-            assert cdp != null;
             return cdp.getMinimalDaysInFirstWeek(locale);
         }
     }
@@ -463,7 +447,6 @@
                                               int field, int value,
                                               int style, Locale locale) {
             CalendarNameProvider cdp = getImpl(locale);
-            assert cdp != null;
             return cdp.getDisplayName(calendarType, field, value, style, locale);
         }
 
@@ -472,7 +455,6 @@
                                                              int field, int style,
                                                              Locale locale) {
             CalendarNameProvider cdp = getImpl(locale);
-            assert cdp != null;
             return cdp.getDisplayNames(calendarType, field, style, locale);
         }
     }
@@ -506,14 +488,12 @@
         @Override
         public String getSymbol(String currencyCode, Locale locale) {
             CurrencyNameProvider cnp = getImpl(locale);
-            assert cnp != null;
             return cnp.getSymbol(currencyCode, locale);
         }
 
         @Override
         public String getDisplayName(String currencyCode, Locale locale) {
             CurrencyNameProvider cnp = getImpl(locale);
-            assert cnp != null;
             return cnp.getDisplayName(currencyCode, locale);
         }
     }
@@ -547,30 +527,38 @@
         @Override
         public String getDisplayLanguage(String languageCode, Locale locale) {
             LocaleNameProvider lnp = getImpl(locale);
-            assert lnp != null;
             return lnp.getDisplayLanguage(languageCode, locale);
         }
 
         @Override
         public String getDisplayScript(String scriptCode, Locale locale) {
             LocaleNameProvider lnp = getImpl(locale);
-            assert lnp != null;
             return lnp.getDisplayScript(scriptCode, locale);
         }
 
         @Override
         public String getDisplayCountry(String countryCode, Locale locale) {
             LocaleNameProvider lnp = getImpl(locale);
-            assert lnp != null;
             return lnp.getDisplayCountry(countryCode, locale);
         }
 
         @Override
         public String getDisplayVariant(String variant, Locale locale) {
             LocaleNameProvider lnp = getImpl(locale);
-            assert lnp != null;
             return lnp.getDisplayVariant(variant, locale);
         }
+
+        @Override
+        public String getDisplayUnicodeExtensionKey(String key, Locale locale) {
+            LocaleNameProvider lnp = getImpl(locale);
+            return lnp.getDisplayUnicodeExtensionKey(key, locale);
+        }
+
+        @Override
+        public String getDisplayUnicodeExtensionType(String extType, String key, Locale locale) {
+            LocaleNameProvider lnp = getImpl(locale);
+            return lnp.getDisplayUnicodeExtensionType(extType, key, locale);
+        }
     }
 
     static class TimeZoneNameProviderDelegate extends TimeZoneNameProvider
@@ -602,14 +590,12 @@
         @Override
         public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {
             TimeZoneNameProvider tznp = getImpl(locale);
-            assert tznp != null;
             return tznp.getDisplayName(ID, daylight, style, locale);
         }
 
         @Override
         public String getGenericDisplayName(String ID, int style, Locale locale) {
             TimeZoneNameProvider tznp = getImpl(locale);
-            assert tznp != null;
             return tznp.getGenericDisplayName(ID, style, locale);
         }
     }
--- a/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,13 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.spi.TimeZoneNameProvider;
 import sun.util.calendar.ZoneInfo;
+import sun.util.cldr.CLDRLocaleProviderAdapter;
+import static sun.util.locale.provider.LocaleProviderAdapter.Type;
 
 /**
  * Utility class that deals with the localized time zone names
@@ -152,6 +155,18 @@
         }
     }
 
+    /**
+     * Converts the time zone id from LDML's 5-letter id to tzdb's id
+     *
+     * @param shortID       time zone short ID defined in LDML
+     * @return the tzdb's time zone ID
+     */
+    public static Optional<String> convertLDMLShortID(String shortID) {
+        return ((CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR))
+                    .getTimeZoneID(shortID)
+                    .map(id -> id.replaceAll("\\s.*", ""));
+    }
+
     private static String[] retrieveDisplayNamesImpl(String id, Locale locale) {
         LocaleServiceProviderPool pool =
             LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
--- a/src/java.base/share/classes/sun/util/resources/LocaleNames.properties	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/share/classes/sun/util/resources/LocaleNames.properties	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -1164,8 +1164,7 @@
 
 
 # locale name patterns
-# rarely localized
 
 DisplayNamePattern={0,choice,0#|1#{1}|2#{1} ({2})}
-ListPattern={0,choice,0#|1#{1}|2#{1},{2}|3#{1},{2},{3}}
+ListKeyTypePattern={0}:{1}
 ListCompositionPattern={0},{1}
Binary file src/java.base/share/lib/security/cacerts has changed
--- a/src/java.base/windows/native/libnio/ch/SocketDispatcher.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.base/windows/native/libnio/ch/SocketDispatcher.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -179,7 +179,7 @@
             }
         }
 
-        count += written;
+        count += (jint)written;
         address += written;
 
     } while ((count < total) && (written == MAX_BUFFER_SIZE));
--- a/src/java.xml/share/classes/org/w3c/dom/ls/DOMImplementationLS.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.xml/share/classes/org/w3c/dom/ls/DOMImplementationLS.java	Wed Dec 13 10:56:50 2017 -0800
@@ -51,12 +51,13 @@
  * binding-specific casting methods on an instance of the
  * <code>DOMImplementation</code> interface or, if the <code>Document</code>
  * supports the feature <code>"Core"</code> version <code>"3.0"</code>
- * defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+ * defined in
+ * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
  * , by using the method <code>DOMImplementation.getFeature</code> with
  * parameter values <code>"LS"</code> (or <code>"LS-Async"</code>) and
  * <code>"3.0"</code> (respectively).
- * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load
-and Save Specification</a>.
+ * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>
+Document Object Model (DOM) Level 3 Load and Save Specification</a>.
  *
  * @since 1.5
  */
@@ -90,9 +91,11 @@
      *   <code>LSParser</code> for any kind of schema types (i.e. the
      *   LSParser will be free to use any schema found), use the value
      *   <code>null</code>.
-     * <p ><b>Note:</b>    For W3C XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>]
+     * <p ><b>Note:</b>    For W3C XML Schema
+     * [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>]
      *   , applications must use the value
-     *   <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>],
+     *   <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD
+     * [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>],
      *   applications must use the value
      *   <code>"http://www.w3.org/TR/REC-xml"</code>. Other Schema languages
      *   are outside the scope of the W3C and therefore should recommend an
@@ -102,8 +105,8 @@
      *   depending on the value of the <code>mode</code> argument.
      * <p ><b>Note:</b>    By default, the newly created <code>LSParser</code>
      *   does not contain a <code>DOMErrorHandler</code>, i.e. the value of
-     *   the "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" configuration parameter is <code>null</code>. However, implementations
+     *   the "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     *   configuration parameter is <code>null</code>. However, implementations
      *   may provide a default error handler at creation time. In that case,
      *   the initial value of the <code>"error-handler"</code> configuration
      *   parameter on the new <code>LSParser</code> object contains a
--- a/src/java.xml/share/classes/org/w3c/dom/ls/LSParser.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.xml/share/classes/org/w3c/dom/ls/LSParser.java	Wed Dec 13 10:56:50 2017 -0800
@@ -53,7 +53,8 @@
  * corresponding DOM document structure. A <code>LSParser</code> instance
  * can be obtained by invoking the
  * <code>DOMImplementationLS.createLSParser()</code> method.
- * <p> As specified in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+ * <p> As specified in
+ * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
  * , when a document is first made available via the LSParser:
  * <ul>
  * <li> there will
@@ -63,16 +64,18 @@
  * <li> it is expected that the <code>value</code> and
  * <code>nodeValue</code> attributes of an <code>Attr</code> node initially
  * return the <a href='http://www.w3.org/TR/2004/REC-xml-20040204#AVNormalize'>XML 1.0
- * normalized value</a>. However, if the parameters "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate-if-schema'>
- * validate-if-schema</a>" and "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-datatype-normalization'>
- * datatype-normalization</a>" are set to <code>true</code>, depending on the attribute normalization
+ * normalized value</a>. However, if the parameters
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-validate-if-schema'>validate-if-schema</a>" and
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-datatype-normalization'>datatype-normalization</a>"
+ * are set to <code>true</code>, depending on the attribute normalization
  * used, the attribute values may differ from the ones obtained by the XML
- * 1.0 attribute normalization. If the parameters "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-datatype-normalization'>
- * datatype-normalization</a>" is set to <code>false</code>, the XML 1.0 attribute normalization is
+ * 1.0 attribute normalization. If the parameters
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-datatype-normalization'>datatype-normalization</a>"
+ * is set to <code>false</code>, the XML 1.0 attribute normalization is
  * guaranteed to occur, and if the attributes list does not contain
  * namespace declarations, the <code>attributes</code> attribute on
- * <code>Element</code> node represents the property <b>[attributes]</b> defined in [<a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/'>XML Information Set</a>]
- * .
+ * <code>Element</code> node represents the property <b>[attributes]</b> defined in
+ * [<a href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204/'>XML Information Set</a>].
  * </li>
  * </ul>
  * <p> Asynchronous <code>LSParser</code> objects are expected to also
@@ -102,17 +105,18 @@
  * <p ><b>Note:</b>  All events defined in this specification use the
  * namespace URI <code>"http://www.w3.org/2002/DOMLS"</code>.
  * <p> While parsing an input source, errors are reported to the application
- * through the error handler (<code>LSParser.domConfig</code>'s "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
- * error-handler</a>" parameter). This specification does in no way try to define all possible
+ * through the error handler (<code>LSParser.domConfig</code>'s
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+ * parameter). This specification does in no way try to define all possible
  * errors that can occur while parsing XML, or any other markup, but some
  * common error cases are defined. The types (<code>DOMError.type</code>) of
  * errors and warnings defined by this specification are:
  * <dl>
  * <dt>
  * <code>"check-character-normalization-failure" [error]</code> </dt>
- * <dd> Raised if
- * the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-check-character-normalization'>
- * check-character-normalization</a>" is set to true and a string is encountered that fails normalization
+ * <dd> Raised if the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-check-character-normalization'>check-character-normalization</a>"
+ * is set to true and a string is encountered that fails normalization
  * checking. </dd>
  * <dt><code>"doctype-not-allowed" [fatal]</code></dt>
  * <dd> Raised if the
@@ -127,8 +131,9 @@
  * <dd> Raised if a processing
  * instruction is encountered in a location where the base URI of the
  * processing instruction can not be preserved.  One example of a case where
- * this warning will be raised is if the configuration parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
- * entities</a>" is set to <code>false</code> and the following XML file is parsed:
+ * this warning will be raised is if the configuration parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-entities'>entities</a>"
+ * is set to <code>false</code> and the following XML file is parsed:
  * <pre>
  * &lt;!DOCTYPE root [ &lt;!ENTITY e SYSTEM 'subdir/myentity.ent' ]&gt;
  * &lt;root&gt; &amp;e; &lt;/root&gt;</pre>
@@ -139,9 +144,9 @@
  * </dd>
  * <dt><code>"unbound-prefix-in-entity" [warning]</code></dt>
  * <dd> An
- * implementation dependent warning that may be raised if the configuration
- * parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces'>
- * namespaces</a>" is set to <code>true</code> and an unbound namespace prefix is
+ * implementation dependent warning that may be raised if the configuration parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-namespaces'>namespaces</a>"
+ * is set to <code>true</code> and an unbound namespace prefix is
  * encountered in an entity's replacement text. Raising this warning is not
  * enforced since some existing parsers may not recognize unbound namespace
  * prefixes in the replacement text of entities. </dd>
@@ -164,8 +169,8 @@
  * are expected to raise implementation specific errors and warnings for any
  * other error and warning cases such as IO errors (file not found,
  * permission denied,...), XML well-formedness errors, and so on.
- * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load
-and Save Specification</a>.
+ * <p>See also the
+ * <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load and Save Specification</a>.
  *
  * @since 1.5
  */
@@ -180,8 +185,10 @@
      * needed parameter values from this <code>DOMConfiguration</code>
      * object to the <code>DOMConfiguration</code> object referenced by the
      * <code>Document</code> object.
-     * <br> In addition to the parameters recognized in on the <a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMConfiguration'>
-     * DOMConfiguration</a> interface defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+     * <br> In addition to the parameters recognized in on the
+     * <a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration'>DOMConfiguration</a>
+     * interface defined in
+     * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
      * , the <code>DOMConfiguration</code> objects for <code>LSParser</code>
      * add or modify the following parameters:
      * <dl>
@@ -190,7 +197,8 @@
      * <dd>
      * <dl>
      * <dt><code>true</code></dt>
-     * <dd>[<em>optional</em>] (<em>default</em>) If a higher level protocol such as HTTP [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>] provides an
+     * <dd>[<em>optional</em>] (<em>default</em>) If a higher level protocol such as HTTP
+     * [<a href='http://www.ietf.org/rfc/rfc2616.txt'>IETF RFC 2616</a>] provides an
      * indication of the character encoding of the input stream being
      * processed, that will override any encoding specified in the XML
      * declaration or the Text declaration (see also section 4.3.3,
@@ -206,7 +214,8 @@
      * <dl>
      * <dt>
      * <code>true</code></dt>
-     * <dd>[<em>optional</em>] Throw a fatal <b>"doctype-not-allowed"</b> error if a doctype node is found while parsing the document. This is
+     * <dd>[<em>optional</em>] Throw a fatal <b>"doctype-not-allowed"</b> error
+     * if a doctype node is found while parsing the document. This is
      * useful when dealing with things like SOAP envelopes where doctype
      * nodes are not allowed. </dd>
      * <dt><code>false</code></dt>
@@ -218,14 +227,17 @@
      * <dl>
      * <dt>
      * <code>true</code></dt>
-     * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is
+     * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when
+     * [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is
      * supported, a processor encounters characters for which it cannot
      * determine the normalization properties, then the processor will
      * ignore any possible denormalizations caused by these characters.
-     * This parameter is ignored for [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>]. </dd>
+     * This parameter is ignored for [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>].
+     * </dd>
      * <dt>
      * <code>false</code></dt>
-     * <dd>[<em>optional</em>] Report an fatal <b>"unknown-character-denormalization"</b> error if a character is encountered for which the processor cannot
+     * <dd>[<em>optional</em>] Report an fatal <b>"unknown-character-denormalization"</b>
+     * error if a character is encountered for which the processor cannot
      * determine the normalization properties. </dd>
      * </dl></dd>
      * <dt><code>"infoset"</code></dt>
@@ -238,7 +250,8 @@
      * <dd>
      * <dl>
      * <dt><code>true</code></dt>
-     * <dd>[<em>required</em>] (<em>default</em>) Perform the namespace processing as defined in [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
+     * <dd>[<em>required</em>] (<em>default</em>) Perform the namespace processing as defined in
+     * [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
      *  and [<a href='http://www.w3.org/TR/2004/REC-xml-names11-20040204/'>XML Namespaces 1.1</a>]
      * . </dd>
      * <dt><code>false</code></dt>
@@ -259,7 +272,8 @@
      * <code>true</code></dt>
      * <dd>[<em>optional</em>] Check that the media type of the parsed resource is a supported media
      * type. If an unsupported media type is encountered, a fatal error of
-     * type <b>"unsupported-media-type"</b> will be raised. The media types defined in [<a href='http://www.ietf.org/rfc/rfc3023.txt'>IETF RFC 3023</a>] must always
+     * type <b>"unsupported-media-type"</b> will be raised. The media types defined in
+     * [<a href='http://www.ietf.org/rfc/rfc3023.txt'>IETF RFC 3023</a>] must always
      * be accepted. </dd>
      * <dt><code>false</code></dt>
      * <dd>[<em>required</em>] (<em>default</em>) Accept any media type. </dd>
@@ -294,8 +308,8 @@
      * terminate the parsing early.
      * <br> The filter is invoked after the operations requested by the
      * <code>DOMConfiguration</code> parameters have been applied. For
-     * example, if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'>
-     * validate</a>" is set to <code>true</code>, the validation is done before invoking the
+     * example, if "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-validate'>validate</a>"
+     * is set to <code>true</code>, the validation is done before invoking the
      * filter.
      */
     public LSParserFilter getFilter();
@@ -306,8 +320,8 @@
      * terminate the parsing early.
      * <br> The filter is invoked after the operations requested by the
      * <code>DOMConfiguration</code> parameters have been applied. For
-     * example, if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'>
-     * validate</a>" is set to <code>true</code>, the validation is done before invoking the
+     * example, if "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-validate'>validate</a>"
+     * is set to <code>true</code>, the validation is done before invoking the
      * filter.
      */
     public void setFilter(LSParserFilter filter);
@@ -340,15 +354,18 @@
      * @exception LSException
      *    PARSE_ERR: Raised if the <code>LSParser</code> was unable to load
      *   the XML document. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public Document parse(LSInput input)
                           throws DOMException, LSException;
 
     /**
-     *  Parse an XML document from a location identified by a URI reference [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. If the URI
-     * contains a fragment identifier (see section 4.1 in [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the
+     *  Parse an XML document from a location identified by a URI reference
+     * [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]. If the URI
+     * contains a fragment identifier (see section 4.1 in
+     * [<a href='http://www.ietf.org/rfc/rfc2396.txt'>IETF RFC 2396</a>]), the
      * behavior is not defined by this specification, future versions of
      * this specification may define the behavior.
      * @param uri The location of the XML document to be read.
@@ -364,8 +381,9 @@
      * @exception LSException
      *    PARSE_ERR: Raised if the <code>LSParser</code> was unable to load
      *   the XML document. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public Document parseURI(String uri)
                              throws DOMException, LSException;
@@ -431,14 +449,17 @@
      * <code>LSParser</code> is asynchronous (<code>LSParser.async</code> is
      * <code>true</code>).
      * <br> If an error occurs while parsing, the caller is notified through
-     * the <code>ErrorHandler</code> instance associated with the "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     * error-handler</a>" parameter of the <code>DOMConfiguration</code>.
+     * the <code>ErrorHandler</code> instance associated with the
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * parameter of the <code>DOMConfiguration</code>.
      * <br> When calling <code>parseWithContext</code>, the values of the
      * following configuration parameters will be ignored and their default
-     * values will always be used instead: "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate'>
-     * validate</a>", "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-validate-if-schema'>
-     * validate-if-schema</a>", and "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-element-content-whitespace'>
-     * element-content-whitespace</a>". Other parameters will be treated normally, and the parser is expected
+     * values will always be used instead:
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-validate'>validate</a>",
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-validate-if-schema'>validate-if-schema</a>",
+     * and
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-element-content-whitespace'>element-content-whitespace</a>".
+     * Other parameters will be treated normally, and the parser is expected
      * to call the <code>LSParserFilter</code> just as if a whole document
      * was parsed.
      * @param input  The <code>LSInput</code> from which the source document
@@ -463,7 +484,8 @@
      * @exception DOMException
      *   HIERARCHY_REQUEST_ERR: Raised if the content cannot replace, be
      *   inserted before, after, or as a child of the context node (see also
-     *   <code>Node.insertBefore</code> or <code>Node.replaceChild</code> in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+     *   <code>Node.insertBefore</code> or <code>Node.replaceChild</code> in
+     * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
      *   ).
      *   <br> NOT_SUPPORTED_ERR: Raised if the <code>LSParser</code> doesn't
      *   support this method, or if the context node is of type
@@ -479,8 +501,9 @@
      * @exception LSException
      *    PARSE_ERR: Raised if the <code>LSParser</code> was unable to load
      *   the XML fragment. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public Node parseWithContext(LSInput input,
                                  Node contextArg,
--- a/src/java.xml/share/classes/org/w3c/dom/ls/LSParserFilter.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.xml/share/classes/org/w3c/dom/ls/LSParserFilter.java	Wed Dec 13 10:56:50 2017 -0800
@@ -56,10 +56,11 @@
  * <code>Document</code>, <code>DocumentType</code>, <code>Notation</code>,
  * <code>Entity</code>, and <code>Attr</code> nodes are never passed to the
  * <code>acceptNode</code> method on the filter. The child nodes of an
- * <code>EntityReference</code> node are passed to the filter if the
- * parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
- * entities</a>" is set to <code>false</code>. Note that, as described by the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
- * entities</a>", unexpanded entity reference nodes are never discarded and are always
+ * <code>EntityReference</code> node are passed to the filter if the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-entities'>entities</a>"
+ * is set to <code>false</code>. Note that, as described by the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-entities'>entities</a>",
+ * unexpanded entity reference nodes are never discarded and are always
  * passed to the filter.
  * <p> All validity checking while parsing a document occurs on the source
  * document as it appears on the input stream, not on the DOM document as it
@@ -71,8 +72,8 @@
  * passed to the filter methods.
  * <p> DOM applications must not raise exceptions in a filter. The effect of
  * throwing exceptions from a filter is DOM implementation dependent.
- * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load
-and Save Specification</a>.
+ * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>
+Document Object Model (DOM) Level 3 Load and Save Specification</a>.
  *
  * @since 1.5
  */
@@ -195,8 +196,8 @@
      * <code>SHOW_NOTATION</code>, <code>SHOW_ENTITY</code>, and
      * <code>SHOW_DOCUMENT_FRAGMENT</code> are meaningless here. Those nodes
      * will never be passed to <code>LSParserFilter.acceptNode</code>.
-     * <br> The constants used here are defined in [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and      Range</a>]
-     * .
+     * <br> The constants used here are defined in
+     * [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and Range</a>].
      */
     public int getWhatToShow();
 
--- a/src/java.xml/share/classes/org/w3c/dom/ls/LSSerializer.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/java.xml/share/classes/org/w3c/dom/ls/LSSerializer.java	Wed Dec 13 10:56:50 2017 -0800
@@ -51,7 +51,8 @@
  * output stream. Any changes or fixups made during the serialization affect
  * only the serialized data. The <code>Document</code> object and its
  * children are never altered by the serialization operation.
- * <p> During serialization of XML data, namespace fixup is done as defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+ * <p> During serialization of XML data, namespace fixup is done as defined in
+ * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
  * , Appendix B. [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>DOM Level 2 Core</a>]
  *  allows empty strings as a real namespace URI. If the
  * <code>namespaceURI</code> of a <code>Node</code> is empty string, the
@@ -80,12 +81,14 @@
  * namespace fixup is done. The resulting output will be valid as an
  * external entity.
  * </li>
- * <li> If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
- * entities</a>" is set to <code>true</code>, <code>EntityReference</code> nodes are
+ * <li> If the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-entities'>entities</a>"
+ * is set to <code>true</code>, <code>EntityReference</code> nodes are
  * serialized as an entity reference of the form "
  * <code>&amp;entityName;</code>" in the output. Child nodes (the expansion)
- * of the entity reference are ignored. If the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-entities'>
- * entities</a>" is set to <code>false</code>, only the children of the entity reference
+ * of the entity reference are ignored. If the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-entities'>entities</a>"
+ * is set to <code>false</code>, only the children of the entity reference
  * are serialized. <code>EntityReference</code> nodes with no children (no
  * corresponding <code>Entity</code> node or the corresponding
  * <code>Entity</code> nodes have no children) are always serialized.
@@ -93,15 +96,16 @@
  * <li>
  * <code>CDATAsections</code> containing content characters that cannot be
  * represented in the specified output encoding are handled according to the
- * "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-split-cdata-sections'>
- * split-cdata-sections</a>" parameter.  If the parameter is set to <code>true</code>,
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-split-cdata-sections'>split-cdata-sections</a>"
+ * parameter.  If the parameter is set to <code>true</code>,
  * <code>CDATAsections</code> are split, and the unrepresentable characters
  * are serialized as numeric character references in ordinary content. The
  * exact position and number of splits is not specified.  If the parameter
  * is set to <code>false</code>, unrepresentable characters in a
  * <code>CDATAsection</code> are reported as
- * <code>"wf-invalid-character"</code> errors if the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'>
- * well-formed</a>" is set to <code>true</code>. The error is not recoverable - there is no
+ * <code>"wf-invalid-character"</code> errors if the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-well-formed'>well-formed</a>"
+ * is set to <code>true</code>. The error is not recoverable - there is no
  * mechanism for supplying alternative characters and continuing with the
  * serialization.
  * </li>
@@ -138,12 +142,15 @@
  * as a <code>DOMError</code> fatal error. An example would be serializing
  * the element &lt;LaCa&ntilde;ada/&gt; with <code>encoding="us-ascii"</code>.
  * This will result with a generation of a <code>DOMError</code>
- * "wf-invalid-character-in-node-name" (as proposed in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-well-formed'>
- * well-formed</a>").
- * <p> When requested by setting the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-normalize-characters'>
- * normalize-characters</a>" on <code>LSSerializer</code> to true, character normalization is
- * performed according to the definition of <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully
- * normalized</a> characters included in appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] on all
+ * "wf-invalid-character-in-node-name" (as proposed in
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-well-formed'>well-formed</a>").
+ * <p> When requested by setting the parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-normalize-characters'>normalize-characters</a>"
+ * on <code>LSSerializer</code> to true, character normalization is
+ * performed according to the definition of
+ * <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully
+ * normalized</a> characters included in appendix E of
+ * [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] on all
  * data to be serialized, both markup and character data. The character
  * normalization process affects only the data as it is being written; it
  * does not alter the DOM's view of the document after serialization has
@@ -170,13 +177,15 @@
  * inconsistencies are found, the serialized form of the document will be
  * altered to remove them. The method used for doing the namespace fixup
  * while serializing a document is the algorithm defined in Appendix B.1,
- * "Namespace normalization", of [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+ * "Namespace normalization", of
+ * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
  * .
  * <p> While serializing a document, the parameter "discard-default-content"
  * controls whether or not non-specified data is serialized.
  * <p> While serializing, errors and warnings are reported to the application
- * through the error handler (<code>LSSerializer.domConfig</code>'s "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
- * error-handler</a>" parameter). This specification does in no way try to define all possible
+ * through the error handler (<code>LSSerializer.domConfig</code>'s
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+ * parameter). This specification does in no way try to define all possible
  * errors and warnings that can occur while serializing a DOM node, but some
  * common error and warning cases are defined. The types (
  * <code>DOMError.type</code>) of errors and warnings defined by this
@@ -189,8 +198,9 @@
  * <dt>
  * <code>"unbound-prefix-in-entity-reference" [fatal]</code> </dt>
  * <dd> Raised if the
- * configuration parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-namespaces'>
- * namespaces</a>" is set to <code>true</code> and an entity whose replacement text
+ * configuration parameter
+ * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-namespaces'>namespaces</a>"
+ * is set to <code>true</code> and an entity whose replacement text
  * contains unbound namespace prefixes is referenced in a location where
  * there are no bindings for the namespace prefixes. </dd>
  * <dt>
@@ -202,8 +212,9 @@
  * are expected to raise implementation specific errors and warnings for any
  * other error and warning cases such as IO errors (file not found,
  * permission denied,...) and so on.
- * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>Document Object Model (DOM) Level 3 Load
-and Save Specification</a>.
+ * <p>See also the
+ * <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407'>
+Document Object Model (DOM) Level 3 Load and Save Specification</a>.
  *
  * @since 1.5
  */
@@ -211,8 +222,10 @@
     /**
      *  The <code>DOMConfiguration</code> object used by the
      * <code>LSSerializer</code> when serializing a DOM node.
-     * <br> In addition to the parameters recognized by the <a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMConfiguration'>
-     * DOMConfiguration</a> interface defined in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+     * <br> In addition to the parameters recognized by the
+     * <a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration'>DOMConfiguration</a>
+     * interface defined in
+     * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
      * , the <code>DOMConfiguration</code> objects for
      * <code>LSSerializer</code> adds, or modifies, the following
      * parameters:
@@ -221,9 +234,11 @@
      * <dd>
      * <dl>
      * <dt><code>true</code></dt>
-     * <dd>[<em>optional</em>] Writes the document according to the rules specified in [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>].
-     * In addition to the behavior described in "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-canonical-form'>
-     * canonical-form</a>" [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+     * <dd>[<em>optional</em>] Writes the document according to the rules specified in
+     * [<a href='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'>Canonical XML</a>].
+     * In addition to the behavior described in
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-canonical-form'>canonical-form</a>"
+     * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
      * , setting this parameter to <code>true</code> will set the parameters
      * "format-pretty-print", "discard-default-content", and "xml-declaration
      * ", to <code>false</code>. Setting one of those parameters to
@@ -267,7 +282,8 @@
      * <dl>
      * <dt>
      * <code>true</code></dt>
-     * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is
+     * <dd>[<em>required</em>] (<em>default</em>) If, while verifying full normalization when
+     * [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] is
      * supported, a character is encountered for which the normalization
      * properties cannot be determined, then raise a
      * <code>"unknown-character-denormalization"</code> warning (instead of
@@ -281,18 +297,21 @@
      * <dt>
      * <code>"normalize-characters"</code></dt>
      * <dd> This parameter is equivalent to
-     * the one defined by <code>DOMConfiguration</code> in [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
+     * the one defined by <code>DOMConfiguration</code> in
+     * [<a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>DOM Level 3 Core</a>]
      * . Unlike in the Core, the default value for this parameter is
      * <code>true</code>. While DOM implementations are not required to
      * support <a href='http://www.w3.org/TR/2004/REC-xml11-20040204/#dt-fullnorm'>fully
-     * normalizing</a> the characters in the document according to appendix E of [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], this
+     * normalizing</a> the characters in the document according to appendix E of
+     * [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], this
      * parameter must be activated by default if supported. </dd>
      * <dt>
      * <code>"xml-declaration"</code></dt>
      * <dd>
      * <dl>
      * <dt><code>true</code></dt>
-     * <dd>[<em>required</em>] (<em>default</em>) If a <code>Document</code>, <code>Element</code>, or <code>Entity</code>
+     * <dd>[<em>required</em>] (<em>default</em>) If a <code>Document</code>,
+     * <code>Element</code>, or <code>Entity</code>
      *  node is serialized, the XML declaration, or text declaration, should
      * be included. The version (<code>Document.xmlVersion</code> if the
      * document is a Level 3 document and the version is non-null, otherwise
@@ -303,7 +322,8 @@
      * <code>false</code></dt>
      * <dd>[<em>required</em>] Do not serialize the XML and text declarations. Report a
      * <code>"xml-declaration-needed"</code> warning if this will cause
-     * problems (i.e. the serialized data is of an XML version other than [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], or an
+     * problems (i.e. the serialized data is of an XML version other than
+     * [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], or an
      * encoding would be needed to be able to re-parse the serialized data). </dd>
      * </dl></dd>
      * </dl>
@@ -314,8 +334,8 @@
      *  The end-of-line sequence of characters to be used in the XML being
      * written out. Any string is supported, but XML treats only a certain
      * set of characters sequence as end-of-line (See section 2.11,
-     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the
-     * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
+     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>],
+     * if the serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
      * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the
      * serialized content is XML 1.1). Using other character sequences than
      * the recommended ones can result in a document that is either not
@@ -335,8 +355,8 @@
      *  The end-of-line sequence of characters to be used in the XML being
      * written out. Any string is supported, but XML treats only a certain
      * set of characters sequence as end-of-line (See section 2.11,
-     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>], if the
-     * serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
+     * "End-of-Line Handling" in [<a href='http://www.w3.org/TR/2004/REC-xml-20040204'>XML 1.0</a>],
+     * if the serialized content is XML 1.0 or section 2.11, "End-of-Line Handling"
      * in [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>], if the
      * serialized content is XML 1.1). Using other character sequences than
      * the recommended ones can result in a document that is either not
@@ -360,8 +380,9 @@
      * serialization early.
      * <br> The filter is invoked after the operations requested by the
      * <code>DOMConfiguration</code> parameters have been applied. For
-     * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'>
-     * cdata-sections</a>" is set to <code>false</code>.
+     * example, CDATA sections won't be passed to the filter if
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-cdata-sections'>cdata-sections</a>"
+     * is set to <code>false</code>.
      */
     public LSSerializerFilter getFilter();
     /**
@@ -371,8 +392,9 @@
      * serialization early.
      * <br> The filter is invoked after the operations requested by the
      * <code>DOMConfiguration</code> parameters have been applied. For
-     * example, CDATA sections won't be passed to the filter if "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-cdata-sections'>
-     * cdata-sections</a>" is set to <code>false</code>.
+     * example, CDATA sections won't be passed to the filter if
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-cdata-sections'>cdata-sections</a>"
+     * is set to <code>false</code>.
      */
     public void setFilter(LSSerializerFilter filter);
 
@@ -414,8 +436,9 @@
      * @exception LSException
      *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
      *   serialize the node. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public boolean write(Node nodeArg,
                          LSOutput destination)
@@ -436,8 +459,9 @@
      * @exception LSException
      *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
      *   serialize the node. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public boolean writeToURI(Node nodeArg,
                               String uri)
@@ -458,8 +482,9 @@
      * @exception LSException
      *    SERIALIZE_ERR: Raised if the <code>LSSerializer</code> was unable to
      *   serialize the node. DOM applications should attach a
-     *   <code>DOMErrorHandler</code> using the parameter "<a href='http://www.w3.org/TR/DOM-Level-3-Core/core.html#parameter-error-handler'>
-     *   error-handler</a>" if they wish to get details on the error.
+     *   <code>DOMErrorHandler</code> using the parameter
+     * "<a href='https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#parameter-error-handler'>error-handler</a>"
+     * if they wish to get details on the error.
      */
     public String writeToString(Node nodeArg)
                                 throws DOMException, LSException;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Dec 13 10:56:50 2017 -0800
@@ -4238,9 +4238,6 @@
     public void visitTypeArray(JCArrayTypeTree tree) {
         Type etype = attribType(tree.elemtype, env);
         Type type = new ArrayType(etype, syms.arrayClass);
-        if (etype.isErroneous()) {
-            type = types.createErrorType(type);
-        }
         result = check(tree, type, KindSelector.TYP, resultInfo);
     }
 
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Secmod.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Secmod.java	Wed Dec 13 10:56:50 2017 -0800
@@ -196,13 +196,23 @@
         }
 
         if (configDir != null) {
-            File configBase = new File(configDir);
+            String configDirPath = null;
+            String sqlPrefix = "sql:/";
+            if (!configDir.startsWith(sqlPrefix)) {
+                configDirPath = configDir;
+            } else {
+                StringBuilder configDirPathSB = new StringBuilder(configDir);
+                configDirPath = configDirPathSB.substring(sqlPrefix.length());
+            }
+            File configBase = new File(configDirPath);
             if (configBase.isDirectory() == false ) {
-                throw new IOException("configDir must be a directory: " + configDir);
+                throw new IOException("configDir must be a directory: " + configDirPath);
             }
-            File secmodFile = new File(configBase, "secmod.db");
-            if (secmodFile.isFile() == false) {
-                throw new FileNotFoundException(secmodFile.getPath());
+            if (!configDir.startsWith(sqlPrefix)) {
+                File secmodFile = new File(configBase, "secmod.db");
+                if (secmodFile.isFile() == false) {
+                    throw new FileNotFoundException(secmodFile.getPath());
+                }
             }
         }
 
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java	Wed Dec 13 10:56:50 2017 -0800
@@ -111,6 +111,15 @@
      */
     SET,
     /**
+     * Removes the value from a namespace defined on an object. Call sites with this
+     * operation should have a signature of
+     * <code>(receiver,&nbsp;name)&rarr;void</code> or
+     * <code>(receiver)&rarr;void</code> when used with {@link NamedOperation},
+     * with all parameters being of any type (either primitive
+     * or reference). This operation must always be used as part of a {@link NamespaceOperation}.
+     */
+    REMOVE,
+    /**
      * Call a callable object. Call sites with this operation should have a
      * signature of <code>(callable,&nbsp;receiver,&nbsp;arguments...)&rarr;value</code>,
      * with all parameters and return type being of any type (either primitive or
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java	Wed Dec 13 10:56:50 2017 -0800
@@ -107,7 +107,8 @@
 
 /**
  * A class that provides linking capabilities for a single POJO class. Normally not used directly, but managed by
- * {@link BeansLinker}.
+ * {@link BeansLinker}. Most of the functionality is provided by the {@link AbstractJavaLinker} superclass; this
+ * class adds length and element operations for arrays and collections.
  */
 class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicLinker {
     BeanLinker(final Class<?> clazz) {
@@ -147,6 +148,8 @@
                     return getElementGetter(req.popNamespace());
                 } else if (op == StandardOperation.SET) {
                     return getElementSetter(req.popNamespace());
+                } else if (op == StandardOperation.REMOVE) {
+                    return getElementRemover(req.popNamespace());
                 }
             }
         }
@@ -228,7 +231,7 @@
         // dealing with an array, or a list or map, but hey...
         // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
         // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
-        if(declaredType.isArray()) {
+        if(declaredType.isArray() && arrayMethod != null) {
             return new GuardedInvocationComponentAndCollectionType(
                     createInternalFilteredGuardedInvocationComponent(arrayMethod.apply(declaredType), linkerServices),
                     CollectionType.ARRAY);
@@ -240,7 +243,7 @@
             return new GuardedInvocationComponentAndCollectionType(
                     createInternalFilteredGuardedInvocationComponent(mapMethod, linkerServices),
                     CollectionType.MAP);
-        } else if(clazz.isArray()) {
+        } else if(clazz.isArray() && arrayMethod != null) {
             return new GuardedInvocationComponentAndCollectionType(
                     getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(arrayMethod.apply(clazz)), callSiteType),
                     CollectionType.ARRAY);
@@ -450,7 +453,7 @@
     }
 
     @SuppressWarnings("unused")
-    private static void noOpSetter() {
+    private static void noOp() {
     }
 
     private static final MethodHandle SET_LIST_ELEMENT = Lookup.PUBLIC.findVirtual(List.class, "set",
@@ -459,12 +462,14 @@
     private static final MethodHandle PUT_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "put",
             MethodType.methodType(Object.class, Object.class, Object.class));
 
-    private static final MethodHandle NO_OP_SETTER_2;
-    private static final MethodHandle NO_OP_SETTER_3;
+    private static final MethodHandle NO_OP_1;
+    private static final MethodHandle NO_OP_2;
+    private static final MethodHandle NO_OP_3;
     static {
-        final MethodHandle noOpSetter = Lookup.findOwnStatic(MethodHandles.lookup(), "noOpSetter", void.class);
-        NO_OP_SETTER_2 = dropObjectArguments(noOpSetter, 2);
-        NO_OP_SETTER_3 = dropObjectArguments(noOpSetter, 3);
+        final MethodHandle noOp = Lookup.findOwnStatic(MethodHandles.lookup(), "noOp", void.class);
+        NO_OP_1 = dropObjectArguments(noOp, 1);
+        NO_OP_2 = dropObjectArguments(noOp, 2);
+        NO_OP_3 = dropObjectArguments(noOp, 3);
     }
 
     private GuardedInvocationComponent getElementSetter(final ComponentLinkRequest req) throws Exception {
@@ -503,7 +508,39 @@
             return gic.replaceInvocation(binder.bind(invocation));
         }
 
-        return guardComponentWithRangeCheck(gicact, callSiteType, nextComponent, binder, isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3);
+        return guardComponentWithRangeCheck(gicact, callSiteType, nextComponent, binder, isFixedKey ? NO_OP_2 : NO_OP_3);
+    }
+
+    private static final MethodHandle REMOVE_LIST_ELEMENT = Lookup.PUBLIC.findVirtual(List.class, "remove",
+            MethodType.methodType(Object.class, int.class));
+
+    private static final MethodHandle REMOVE_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "remove",
+            MethodType.methodType(Object.class, Object.class));
+
+    private GuardedInvocationComponent getElementRemover(final ComponentLinkRequest req) throws Exception {
+        final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
+        final Object name = req.name;
+        final boolean isFixedKey = name != null;
+        assertParameterCount(callSiteDescriptor, isFixedKey ? 1 : 2);
+        final LinkerServices linkerServices = req.linkerServices;
+        final MethodType callSiteType = callSiteDescriptor.getMethodType();
+        final GuardedInvocationComponent nextComponent = getNextComponent(req);
+
+        final GuardedInvocationComponentAndCollectionType gicact = guardedInvocationComponentAndCollectionType(
+                callSiteType, linkerServices, null, REMOVE_LIST_ELEMENT, REMOVE_MAP_ELEMENT);
+
+        if (gicact == null) {
+            // Can't remove elements for objects that are neither lists, nor maps.
+            return nextComponent;
+        }
+
+        final Object typedName = getTypedName(name, gicact.collectionType == CollectionType.MAP, linkerServices);
+        if (typedName == INVALID_NAME) {
+            return nextComponent;
+        }
+
+        return guardComponentWithRangeCheck(gicact, callSiteType, nextComponent,
+                new Binder(linkerServices, callSiteType, typedName), isFixedKey ? NO_OP_1: NO_OP_2);
     }
 
     private static final MethodHandle GET_COLLECTION_LENGTH = Lookup.PUBLIC.findVirtual(Collection.class, "size",
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java	Wed Dec 13 10:56:50 2017 -0800
@@ -113,6 +113,8 @@
  * <li> expose elements of native Java arrays, {@link java.util.List} and {@link java.util.Map} objects as
  * {@link StandardOperation#GET} and {@link StandardOperation#SET} operations in the
  * {@link StandardNamespace#ELEMENT} namespace;</li>
+ * <li> expose removal of elements of {@link java.util.List} and {@link java.util.Map} objects as
+ * {@link StandardOperation#REMOVE} operation in the {@link StandardNamespace#ELEMENT} namespace;</li>
  * <li>expose a virtual property named {@code length} on Java arrays, {@link java.util.Collection} and
  * {@link java.util.Map} objects;</li>
  * <li>expose {@link StandardOperation#NEW} on instances of {@link StaticClass}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Wed Dec 13 10:56:50 2017 -0800
@@ -128,6 +128,9 @@
 
   /** Returns List<MonitorInfo> */
   public List<MonitorInfo> getMonitors() {
+    if (getScope() == null) {
+      return new ArrayList<>();
+    }
     List monitors = getScope().getMonitors();
     if (monitors == null) {
       return new ArrayList<>();
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2ClientImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2ClientImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -36,6 +36,8 @@
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CompletableFuture;
+
+import jdk.incubator.http.internal.common.Log;
 import jdk.incubator.http.internal.common.MinimalFuture;
 import jdk.incubator.http.internal.common.Utils;
 import jdk.incubator.http.internal.frame.SettingsFrame;
@@ -78,10 +80,6 @@
         }
     }
 
-//    boolean haveConnectionFor(URI uri, InetSocketAddress proxy) {
-//        return connections.containsKey(Http2Connection.keyFor(uri,proxy));
-//    }
-
     /**
      * If a https request then async waits until a connection is opened.
      * Returns null if the request is 'http' as a different (upgrade)
@@ -188,18 +186,64 @@
 
     private static final int K = 1024;
 
+    private static int getParameter(String property, int min, int max, int defaultValue) {
+        int value =  Utils.getIntegerNetProperty(property, defaultValue);
+        // use default value if misconfigured
+        if (value < min || value > max) {
+            Log.logError("Property value for {0}={1} not in [{2}..{3}]: " +
+                    "using default={4}", property, value, min, max, defaultValue);
+            value = defaultValue;
+        }
+        return value;
+    }
+
+    // used for the connection window, to have a connection window size
+    // bigger than the initial stream window size.
+    int getConnectionWindowSize(SettingsFrame clientSettings) {
+        // Maximum size is 2^31-1. Don't allow window size to be less
+        // than the stream window size. HTTP/2 specify a default of 64 * K -1,
+        // but we use 2^26 by default for better performance.
+        int streamWindow = clientSettings.getParameter(INITIAL_WINDOW_SIZE);
+
+        // The default is the max between the stream window size
+        // and the connection window size.
+        int defaultValue = Math.min(Integer.MAX_VALUE,
+                Math.max(streamWindow, K*K*32));
+
+        return getParameter(
+                "jdk.httpclient.connectionWindowSize",
+                streamWindow, Integer.MAX_VALUE, defaultValue);
+    }
+
     SettingsFrame getClientSettings() {
         SettingsFrame frame = new SettingsFrame();
-        frame.setParameter(HEADER_TABLE_SIZE, Utils.getIntegerNetProperty(
-                "jdk.httpclient.hpack.maxheadertablesize", 16 * K));
-        frame.setParameter(ENABLE_PUSH, Utils.getIntegerNetProperty(
-            "jdk.httpclient.enablepush", 1));
-        frame.setParameter(MAX_CONCURRENT_STREAMS, Utils.getIntegerNetProperty(
-            "jdk.httpclient.maxstreams", 16));
-        frame.setParameter(INITIAL_WINDOW_SIZE, Utils.getIntegerNetProperty(
-            "jdk.httpclient.windowsize", 64 * K - 1));
-        frame.setParameter(MAX_FRAME_SIZE, Utils.getIntegerNetProperty(
-            "jdk.httpclient.maxframesize", 16 * K));
+        // default defined for HTTP/2 is 4 K, we use 16 K.
+        frame.setParameter(HEADER_TABLE_SIZE, getParameter(
+                "jdk.httpclient.hpack.maxheadertablesize",
+                0, Integer.MAX_VALUE, 16 * K));
+        // O: does not accept push streams. 1: accepts push streams.
+        frame.setParameter(ENABLE_PUSH, getParameter(
+                "jdk.httpclient.enablepush",
+                0, 1, 1));
+        // HTTP/2 recommends to set the number of concurrent streams
+        // no lower than 100. We use 100. 0 means no stream would be
+        // accepted. That would render the client to be non functional,
+        // so we won't let 0 be configured for our Http2ClientImpl.
+        frame.setParameter(MAX_CONCURRENT_STREAMS, getParameter(
+                "jdk.httpclient.maxstreams",
+                1, Integer.MAX_VALUE, 100));
+        // Maximum size is 2^31-1. Don't allow window size to be less
+        // than the minimum frame size as this is likely to be a
+        // configuration error. HTTP/2 specify a default of 64 * K -1,
+        // but we use 16 M  for better performance.
+        frame.setParameter(INITIAL_WINDOW_SIZE, getParameter(
+                "jdk.httpclient.windowsize",
+                16 * K, Integer.MAX_VALUE, 16*K*K));
+        // HTTP/2 specify a minimum size of 16 K, a maximum size of 2^24-1,
+        // and a default of 16 K. We use 16 K as default.
+        frame.setParameter(MAX_FRAME_SIZE, getParameter(
+                "jdk.httpclient.maxframesize",
+                16 * K, 16 * K * K -1, 16 * K));
         return frame;
     }
 }
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java	Wed Dec 13 10:56:50 2017 -0800
@@ -228,7 +228,7 @@
     private final WindowController windowController = new WindowController();
     private final FramesController framesController = new FramesController();
     private final Http2TubeSubscriber subscriber = new Http2TubeSubscriber();
-    final WindowUpdateSender windowUpdater;
+    final ConnectionWindowUpdateSender windowUpdater;
     private volatile Throwable cause;
     private volatile Supplier<ByteBuffer> initial;
 
@@ -247,7 +247,8 @@
         this.nextstreamid = nextstreamid;
         this.key = key;
         this.clientSettings = this.client2.getClientSettings();
-        this.framesDecoder = new FramesDecoder(this::processFrame, clientSettings.getParameter(SettingsFrame.MAX_FRAME_SIZE));
+        this.framesDecoder = new FramesDecoder(this::processFrame,
+                clientSettings.getParameter(SettingsFrame.MAX_FRAME_SIZE));
         // serverSettings will be updated by server
         this.serverSettings = SettingsFrame.getDefaultSettings();
         this.hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
@@ -255,7 +256,8 @@
         debugHpack.log(Level.DEBUG, () -> "For the record:" + super.toString());
         debugHpack.log(Level.DEBUG, "Decoder created: %s", hpackIn);
         debugHpack.log(Level.DEBUG, "Encoder created: %s", hpackOut);
-        this.windowUpdater = new ConnectionWindowUpdateSender(this, client().getReceiveBufferSize());
+        this.windowUpdater = new ConnectionWindowUpdateSender(this,
+                client2.getConnectionWindowSize(clientSettings));
     }
 
     /**
@@ -774,7 +776,8 @@
         Log.logTrace("{0}: start sending connection preface to {1}",
                      connection.channel().getLocalAddress(),
                      connection.address());
-        SettingsFrame sf = client2.getClientSettings();
+        SettingsFrame sf = new SettingsFrame(clientSettings);
+        int initialWindowSize = sf.getParameter(INITIAL_WINDOW_SIZE);
         ByteBuffer buf = framesEncoder.encodeConnectionPreface(PREFACE_BYTES, sf);
         Log.logFrames(sf, "OUT");
         // send preface bytes and SettingsFrame together
@@ -788,8 +791,10 @@
 
         // send a Window update for the receive buffer we are using
         // minus the initial 64 K specified in protocol
-        final int len = client2.client().getReceiveBufferSize() - (64 * 1024 - 1);
-        windowUpdater.sendWindowUpdate(len);
+        final int len = windowUpdater.initialWindowSize - initialWindowSize;
+        if (len > 0) {
+            windowUpdater.sendWindowUpdate(len);
+        }
         // there will be an ACK to the windows update - which should
         // cause any pending data stored before the preface was sent to be
         // flushed (see PrefaceController).
@@ -1202,9 +1207,11 @@
 
     static final class ConnectionWindowUpdateSender extends WindowUpdateSender {
 
+        final int initialWindowSize;
         public ConnectionWindowUpdateSender(Http2Connection connection,
                                             int initialWindowSize) {
             super(connection, initialWindowSize);
+            this.initialWindowSize = initialWindowSize;
         }
 
         @Override
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientImpl.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientImpl.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1038,7 +1038,7 @@
     // used for the connection window
     int getReceiveBufferSize() {
         return Utils.getIntegerNetProperty(
-                "jdk.httpclient.connectionWindowSize", 256 * 1024
+                "jdk.httpclient.receiveBufferSize", 2 * 1024 * 1024
         );
     }
 }
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainHttpConnection.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainHttpConnection.java	Wed Dec 13 10:56:50 2017 -0800
@@ -143,7 +143,9 @@
             this.chan = SocketChannel.open();
             chan.configureBlocking(false);
             int bufsize = client.getReceiveBufferSize();
-            chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize);
+            if (!trySetReceiveBufferSize(bufsize)) {
+                trySetReceiveBufferSize(256*1024);
+            }
             chan.setOption(StandardSocketOptions.TCP_NODELAY, true);
             // wrap the connected channel in a Tube for async reading and writing
             tube = new SocketTube(client(), chan, Utils::getBuffer);
@@ -152,6 +154,18 @@
         }
     }
 
+    private boolean trySetReceiveBufferSize(int bufsize) {
+        try {
+            chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize);
+            return true;
+        } catch(IOException x) {
+            debug.log(Level.DEBUG,
+                    "Failed to set receive buffer size to %d on %s",
+                    bufsize, chan);
+        }
+        return false;
+    }
+
     @Override
     HttpPublisher publisher() { return writePublisher; }
 
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowUpdateSender.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowUpdateSender.java	Wed Dec 13 10:56:50 2017 -0800
@@ -59,6 +59,8 @@
         //   or
         // - remaining window size reached max frame size.
         limit = Math.min(v0, v1);
+        debug.log(Level.DEBUG, "maxFrameSize=%d, initWindowSize=%d, limit=%d",
+                maxFrameSize, initWindowSize, limit);
     }
 
     abstract int getStreamId();
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/SettingsFrame.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/SettingsFrame.java	Wed Dec 13 10:56:50 2017 -0800
@@ -100,6 +100,11 @@
         this(0);
     }
 
+    public SettingsFrame(SettingsFrame other) {
+        super(0, other.flags);
+        parameters = Arrays.copyOf(other.parameters, MAX_PARAM);
+    }
+
     @Override
     public int type() {
         return TYPE;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Wed Dec 13 10:56:50 2017 -0800
@@ -117,8 +117,10 @@
             SourceToHTMLConverter.convertRoot(configuration,
                 docEnv, DocPaths.SOURCE_OUTPUT);
         }
-
-        if (configuration.topFile.isEmpty()) {
+        // Modules with no documented classes may be specified on the
+        // command line to specify a service provider, allow these.
+        if (configuration.getSpecifiedModuleElements().isEmpty() &&
+                configuration.topFile.isEmpty()) {
             messages.error("doclet.No_Non_Deprecated_Classes_To_Document");
             return;
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Wed Dec 13 10:56:50 2017 -0800
@@ -193,7 +193,11 @@
      * @throws DocletException if there is a problem while generating the documentation
      */
     private void startGeneration(DocletEnvironment docEnv) throws DocletException {
-        if (configuration.getIncludedTypeElements().isEmpty()) {
+
+        // Modules with no documented classes may be specified on the
+        // command line to specify a service provider, allow these.
+        if (configuration.getSpecifiedModuleElements().isEmpty() &&
+                configuration.getIncludedTypeElements().isEmpty()) {
             messages.error("doclet.No_Public_Classes_To_Document");
             return;
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java	Wed Dec 13 10:56:50 2017 -0800
@@ -489,6 +489,10 @@
                         continue;
                     }
 
+                    // Skip static methods in interfaces they are not inherited
+                    if (utils.isInterface(inheritedClass) && utils.isStatic(inheritedMember))
+                        continue;
+
                     // If applicable, filter those overridden methods that
                     // should not be documented in the summary/detail sections,
                     // and instead document them in the footnote. Care must be taken
@@ -496,9 +500,8 @@
                     // but comments for these are synthesized on the output.
                     ExecutableElement inheritedMethod = (ExecutableElement)inheritedMember;
                     if (enclosedSuperMethods.stream()
-                            .anyMatch(e -> utils.executableMembersEqual(inheritedMethod, e)
-                                    && (!utils.isSimpleOverride(e)
-                                    || visibleMemberMap.getPropertyElement(e) != null))) {
+                            .anyMatch(e -> utils.executableMembersEqual(inheritedMethod, e) &&
+                                    (!utils.isSimpleOverride(e) || visibleMemberMap.getPropertyElement(e) != null))) {
                         inheritedMembers.add(inheritedMember);
                     }
                 }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,14 @@
 package com.sun.tools.jdeps;
 
 import java.io.PrintWriter;
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleFinder;
-import java.lang.module.ModuleReference;
+import java.util.ArrayDeque;
 import java.util.Collections;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
-import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -161,7 +157,7 @@
      * Returns all nodes reachable from the given set of roots.
      */
     public Set<T> dfs(Set<T> roots) {
-        Deque<T> deque = new LinkedList<>(roots);
+        Deque<T> deque = new ArrayDeque<>(roots);
         Set<T> visited = new HashSet<>();
         while (!deque.isEmpty()) {
             T u = deque.pop();
@@ -197,7 +193,7 @@
         if (includeAdjacent && isAdjacent(u, v)) {
             return true;
         }
-        Deque<T> stack = new LinkedList<>();
+        Deque<T> stack = new ArrayDeque<>();
         Set<T> visited = new HashSet<>();
         stack.push(u);
         while (!stack.isEmpty()) {
@@ -292,12 +288,10 @@
      * Topological sort
      */
     static class TopoSorter<T> {
-        final Deque<T> result = new LinkedList<>();
-        final Deque<T> nodes;
+        final Deque<T> result = new ArrayDeque<>();
         final Graph<T> graph;
         TopoSorter(Graph<T> graph) {
             this.graph = graph;
-            this.nodes = new LinkedList<>(graph.nodes);
             sort();
         }
 
@@ -310,17 +304,16 @@
         }
 
         private void sort() {
-            Deque<T> visited = new LinkedList<>();
-            Deque<T> done = new LinkedList<>();
-            T node;
-            while ((node = nodes.poll()) != null) {
+            Set<T> visited = new HashSet<>();
+            Set<T> done = new HashSet<>();
+            for (T node : graph.nodes()) {
                 if (!visited.contains(node)) {
                     visit(node, visited, done);
                 }
             }
         }
 
-        private void visit(T node, Deque<T> visited, Deque<T> done) {
+        private void visit(T node, Set<T> visited, Set<T> done) {
             if (visited.contains(node)) {
                 if (!done.contains(node)) {
                     throw new IllegalArgumentException("Cyclic detected: " +
@@ -330,7 +323,7 @@
             }
             visited.add(node);
             graph.edges().get(node).stream()
-                .forEach(x -> visit(x, visited, done));
+                 .forEach(x -> visit(x, visited, done));
             done.add(node);
             result.addLast(node);
         }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java	Wed Dec 13 10:56:50 2017 -0800
@@ -38,8 +38,6 @@
 import java.io.UncheckedIOException;
 import java.lang.module.Configuration;
 import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Exports;
-import java.lang.module.ModuleDescriptor.Opens;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
@@ -71,6 +69,7 @@
     public static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
     public static final String ALL_DEFAULT = "ALL-DEFAULT";
     public static final String ALL_SYSTEM = "ALL-SYSTEM";
+
     public static final String MODULE_INFO = "module-info.class";
 
     private final SystemModuleFinder system;
@@ -91,8 +90,7 @@
                                Set<String> roots,
                                List<Path> classpaths,
                                List<Archive> initialArchives,
-                               boolean allDefaultModules,
-                               boolean allSystemModules,
+                               Set<String> tokens,
                                Runtime.Version version)
         throws IOException
     {
@@ -104,16 +102,13 @@
 
         // build root set for resolution
         Set<String> mods = new HashSet<>(roots);
-
-        // add all system modules to the root set for unnamed module or set explicitly
-        boolean unnamed = !initialArchives.isEmpty() || !classpaths.isEmpty();
-        if (allSystemModules || (unnamed && !allDefaultModules)) {
+        if (tokens.contains(ALL_SYSTEM)) {
             systemModulePath.findAll().stream()
                 .map(mref -> mref.descriptor().name())
                 .forEach(mods::add);
         }
 
-        if (allDefaultModules) {
+        if (tokens.contains(ALL_DEFAULT)) {
             mods.addAll(systemModulePath.defaultSystemRoots());
         }
 
@@ -200,10 +195,10 @@
         return m!= null ? Optional.of(m.descriptor()) : Optional.empty();
     }
 
-    boolean isValidToken(String name) {
+    public static boolean isToken(String name) {
         return ALL_MODULE_PATH.equals(name) ||
-                ALL_DEFAULT.equals(name) ||
-                ALL_SYSTEM.equals(name);
+               ALL_DEFAULT.equals(name) ||
+               ALL_SYSTEM.equals(name);
     }
 
     /**
@@ -482,13 +477,10 @@
         final List<Archive> initialArchives = new ArrayList<>();
         final List<Path> paths = new ArrayList<>();
         final List<Path> classPaths = new ArrayList<>();
+        final Set<String> tokens = new HashSet<>();
 
         ModuleFinder upgradeModulePath;
         ModuleFinder appModulePath;
-        boolean addAllApplicationModules;
-        boolean addAllDefaultModules;
-        boolean addAllSystemModules;
-        boolean allModules;
         Runtime.Version version;
 
         public Builder() {
@@ -513,34 +505,15 @@
 
         public Builder addmods(Set<String> addmods) {
             for (String mn : addmods) {
-                switch (mn) {
-                    case ALL_MODULE_PATH:
-                        this.addAllApplicationModules = true;
-                        break;
-                    case ALL_DEFAULT:
-                        this.addAllDefaultModules = true;
-                        break;
-                    case ALL_SYSTEM:
-                        this.addAllSystemModules = true;
-                        break;
-                    default:
-                        this.rootModules.add(mn);
+                if (isToken(mn)) {
+                    tokens.add(mn);
+                } else {
+                    rootModules.add(mn);
                 }
             }
             return this;
         }
 
-        /*
-         * This method is for --check option to find all target modules specified
-         * in qualified exports.
-         *
-         * Include all system modules and modules found on modulepath
-         */
-        public Builder allModules() {
-            this.allModules = true;
-            return this;
-        }
-
         public Builder multiRelease(Runtime.Version version) {
             this.version = version;
             return this;
@@ -579,7 +552,9 @@
                         .forEach(rootModules::add);
             }
 
-            if ((addAllApplicationModules || allModules) && appModulePath != null) {
+            // add all modules to the root set for unnamed module or set explicitly
+            boolean unnamed = !initialArchives.isEmpty() || !classPaths.isEmpty();
+            if ((unnamed || tokens.contains(ALL_MODULE_PATH)) && appModulePath != null) {
                 appModulePath.findAll().stream()
                     .map(mref -> mref.descriptor().name())
                     .forEach(rootModules::add);
@@ -587,7 +562,7 @@
 
             // no archive is specified for analysis
             // add all system modules as root if --add-modules ALL-SYSTEM is specified
-            if (addAllSystemModules && rootModules.isEmpty() &&
+            if (tokens.contains(ALL_SYSTEM) && rootModules.isEmpty() &&
                     initialArchives.isEmpty() && classPaths.isEmpty()) {
                 systemModulePath.findAll()
                     .stream()
@@ -595,13 +570,16 @@
                     .forEach(rootModules::add);
             }
 
+            if (unnamed && !tokens.contains(ALL_DEFAULT)) {
+                tokens.add(ALL_SYSTEM);
+            }
+
             return new JdepsConfiguration(systemModulePath,
                                           finder,
                                           rootModules,
                                           classPaths,
                                           initialArchives,
-                                          addAllDefaultModules,
-                                          allModules,
+                                          tokens,
                                           version);
         }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -540,7 +540,7 @@
     }
 
     boolean run() throws IOException {
-        try (JdepsConfiguration config = buildConfig(command.allModules())) {
+        try (JdepsConfiguration config = buildConfig()) {
             if (!options.nowarning) {
                 // detect split packages
                 config.splitPackages().entrySet()
@@ -553,7 +553,7 @@
 
             // check if any module specified in --add-modules, --require, and -m is missing
             options.addmods.stream()
-                .filter(mn -> !config.isValidToken(mn))
+                .filter(mn -> !JdepsConfiguration.isToken(mn))
                 .forEach(mn -> config.findModule(mn).orElseThrow(() ->
                     new UncheckedBadArgs(new BadArgs("err.module.not.found", mn))));
 
@@ -561,18 +561,14 @@
         }
     }
 
-    private JdepsConfiguration buildConfig(boolean allModules) throws IOException {
+    private JdepsConfiguration buildConfig() throws IOException {
         JdepsConfiguration.Builder builder =
             new JdepsConfiguration.Builder(options.systemModulePath);
 
         builder.upgradeModulePath(options.upgradeModulePath)
                .appModulePath(options.modulePath)
-               .addmods(options.addmods);
-
-        if (allModules) {
-            // check all system modules in the image
-            builder.allModules();
-        }
+               .addmods(options.addmods)
+               .addmods(command.addModules());
 
         if (options.classpath != null)
             builder.addClassPath(options.classpath);
@@ -655,8 +651,8 @@
          * only.  The method should be overridden when this command should
          * analyze all modules instead.
          */
-        boolean allModules() {
-            return false;
+        Set<String> addModules() {
+            return Set.of();
         }
 
         @Override
@@ -871,8 +867,8 @@
          * analyzed to find all modules that depend on the modules specified in the
          * --require option directly and indirectly
          */
-        public boolean allModules() {
-            return options.requires.size() > 0;
+        Set<String> addModules() {
+            return options.requires.size() > 0 ? Set.of("ALL-SYSTEM") : Set.of();
         }
     }
 
@@ -975,8 +971,8 @@
         /*
          * Returns true to analyze all modules
          */
-        public boolean allModules() {
-            return true;
+        Set<String> addModules() {
+            return Set.of("ALL-SYSTEM", "ALL-MODULE-PATH");
         }
     }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Profile.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Profile.java	Wed Dec 13 10:56:50 2017 -0800
@@ -32,7 +32,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -138,7 +137,7 @@
     // for debugging
     public static void main(String[] args) throws IOException {
         // initialize Profiles
-        new JdepsConfiguration.Builder().allModules().build();
+        new JdepsConfiguration.Builder().addmods(Set.of("ALL-SYSTEM")).build();
 
         // find platform modules
         if (Profile.getProfileCount() == 0) {
--- a/src/jdk.jdi/share/native/libdt_shmem/SharedMemoryConnection.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdi/share/native/libdt_shmem/SharedMemoryConnection.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -111,7 +111,7 @@
     jint tmpInt;
 
     total_length = str->type.cmd.len;
-    data_length = total_length - 11;
+    data_length = total_length - JDWP_HEADER_SIZE;
 
     /* total packet length is header + data */
     array = (*env)->NewByteArray(env, total_length);
@@ -142,7 +142,7 @@
     /* finally the data */
 
     if (data_length > 0) {
-        (*env)->SetByteArrayRegion(env, array, 11,
+        (*env)->SetByteArrayRegion(env, array, JDWP_HEADER_SIZE,
                                    data_length, str->type.cmd.data);
         if ((*env)->ExceptionOccurred(env)) {
             return NULL;
@@ -168,7 +168,7 @@
 {
     jsize total_length, data_length;
     jbyte *data;
-    unsigned char pktHeader[11]; /* sizeof length + id + flags + cmdSet + cmd */
+    unsigned char pktHeader[JDWP_HEADER_SIZE];
 
     /*
      * Get the packet header
--- a/src/jdk.jdi/share/native/libdt_shmem/shmemBack.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdi/share/native/libdt_shmem/shmemBack.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -270,7 +270,7 @@
     if (packet == NULL) {
         RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");
     }
-    if (packet->type.cmd.len < 11) {
+    if (packet->type.cmd.len < JDWP_HEADER_SIZE) {
         RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length");
     }
     if (connection == NULL) {
--- a/src/jdk.jdi/share/native/libdt_shmem/shmemBase.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdi/share/native/libdt_shmem/shmemBase.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1049,7 +1049,7 @@
         CHECK_ERROR(sendBytes(connection, &packet->type.cmd.cmd, sizeof(jbyte)));
     }
 
-    data_length = packet->type.cmd.len - 11;
+    data_length = packet->type.cmd.len - JDWP_HEADER_SIZE;
     SHMEM_GUARANTEE(data_length >= 0);
     CHECK_ERROR(sendBytes(connection, &data_length, sizeof(jint)));
 
@@ -1125,10 +1125,10 @@
     if (data_length < 0) {
         return SYS_ERR;
     } else if (data_length == 0) {
-        packet->type.cmd.len = 11;
+        packet->type.cmd.len = JDWP_HEADER_SIZE;
         packet->type.cmd.data = NULL;
     } else {
-        packet->type.cmd.len = data_length + 11;
+        packet->type.cmd.len = data_length + JDWP_HEADER_SIZE;
         packet->type.cmd.data = (*callback->alloc)(data_length);
         if (packet->type.cmd.data == NULL) {
             return SYS_ERR;
--- a/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h	Wed Dec 13 10:56:50 2017 -0800
@@ -96,6 +96,8 @@
  * See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html
  */
 
+#define JDWP_HEADER_SIZE 11
+
 enum {
     /*
      * If additional flags are added that apply to jdwpCmdPacket,
--- a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Wed Dec 13 10:56:50 2017 -0800
@@ -70,7 +70,6 @@
             RETURN_IO_ERROR("recv error"); \
         }
 
-#define HEADER_SIZE     11
 #define MAX_DATA_SIZE 1000
 
 static jint recv_fully(int, char *, int);
@@ -790,7 +789,7 @@
     /*
      * room for header and up to MAX_DATA_SIZE data bytes
      */
-    char header[HEADER_SIZE + MAX_DATA_SIZE];
+    char header[JDWP_HEADER_SIZE + MAX_DATA_SIZE];
     jbyte *data;
 
     /* packet can't be null */
@@ -799,7 +798,7 @@
     }
 
     len = packet->type.cmd.len;         /* includes header */
-    data_len = len - HEADER_SIZE;
+    data_len = len - JDWP_HEADER_SIZE;
 
     /* bad packet */
     if (data_len < 0) {
@@ -825,15 +824,15 @@
     data = packet->type.cmd.data;
     /* Do one send for short packets, two for longer ones */
     if (data_len <= MAX_DATA_SIZE) {
-        memcpy(header + HEADER_SIZE, data, data_len);
-        if (send_fully(socketFD, (char *)&header, HEADER_SIZE + data_len) !=
-            HEADER_SIZE + data_len) {
+        memcpy(header + JDWP_HEADER_SIZE, data, data_len);
+        if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + data_len) !=
+            JDWP_HEADER_SIZE + data_len) {
             RETURN_IO_ERROR("send failed");
         }
     } else {
-        memcpy(header + HEADER_SIZE, data, MAX_DATA_SIZE);
-        if (send_fully(socketFD, (char *)&header, HEADER_SIZE + MAX_DATA_SIZE) !=
-            HEADER_SIZE + MAX_DATA_SIZE) {
+        memcpy(header + JDWP_HEADER_SIZE, data, MAX_DATA_SIZE);
+        if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + MAX_DATA_SIZE) !=
+            JDWP_HEADER_SIZE + MAX_DATA_SIZE) {
             RETURN_IO_ERROR("send failed");
         }
         /* Send the remaining data bytes right out of the data area. */
--- a/src/jdk.jdwp.agent/share/native/libjdwp/inStream.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/inStream.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
 {
     stream->packet = packet;
     stream->error = JDWP_ERROR(NONE);
-    stream->left = packet.type.cmd.len;
+    stream->left = packet.type.cmd.len - JDWP_HEADER_SIZE;
     stream->current = packet.type.cmd.data;
     stream->refs = bagCreateBag(sizeof(jobject), INITIAL_REF_ALLOC);
     if (stream->refs == NULL) {
@@ -411,12 +411,6 @@
     return string;
 }
 
-jboolean
-inStream_endOfInput(PacketInputStream *stream)
-{
-    return (stream->left > 0);
-}
-
 jdwpError
 inStream_error(PacketInputStream *stream)
 {
@@ -424,7 +418,8 @@
 }
 
 void
-inStream_clearError(PacketInputStream *stream) {
+inStream_clearError(PacketInputStream *stream)
+{
     stream->error = JDWP_ERROR(NONE);
 }
 
--- a/src/jdk.jdwp.agent/share/native/libjdwp/inStream.h	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/inStream.h	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,6 @@
 
 jdwpError inStream_skipBytes(PacketInputStream *stream, jint count);
 
-jboolean inStream_endOfInput(PacketInputStream *stream);
 jdwpError inStream_error(PacketInputStream *stream);
 void inStream_clearError(PacketInputStream *stream);
 void inStream_destroy(PacketInputStream *stream);
--- a/src/jdk.jdwp.agent/share/native/libjdwp/outStream.c	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/outStream.c	Wed Dec 13 10:56:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -418,7 +418,7 @@
      * packet.
      */
     if (stream->firstSegment.next == NULL) {
-        stream->packet.type.cmd.len = 11 + stream->firstSegment.length;
+        stream->packet.type.cmd.len = JDWP_HEADER_SIZE + stream->firstSegment.length;
         stream->packet.type.cmd.data = stream->firstSegment.data;
         rc = transport_sendPacket(&stream->packet);
         return rc;
@@ -447,7 +447,7 @@
         segment = segment->next;
     }
 
-    stream->packet.type.cmd.len = 11 + len;
+    stream->packet.type.cmd.len = JDWP_HEADER_SIZE + len;
     stream->packet.type.cmd.data = data;
     rc = transport_sendPacket(&stream->packet);
     stream->packet.type.cmd.data = NULL;
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Dec 13 14:41:27 2017 +0000
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Dec 13 10:56:50 2017 -0800
@@ -43,6 +43,7 @@
 import java.nio.charset.Charset;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.text.MessageFormat;
@@ -387,7 +388,7 @@
         private Collection<String> validPaths(Collection<String> vals, String context, boolean isModulePath) {
             Stream<String> result = vals.stream()
                     .map(s -> Arrays.stream(s.split(File.pathSeparator))
-                        .map(sp -> toPathResolvingUserHome(sp))
+                        .flatMap(sp -> toPathImpl(sp, context))
                         .filter(p -> checkValidPathEntry(p, context, isModulePath))
                         .map(p -> p.toString())
                         .collect(Collectors.joining(File.pathSeparator)));
@@ -427,6 +428,16 @@
             return false;
         }
 
+        private Stream<Path> toPathImpl(String path, String context) {
+            try {
+                return Stream.of(toPathResolvingUserHome(path));
+            } catch (InvalidPathException ex) {
+                msg("jshell.err.file.not.found", context, path);
+                failed = true;
+                return Stream.empty();
+            }
+        }
+
         Options parse(OptionSet options) {
             addOptions(OptionKind.CLASS_PATH,
                     validPaths(options.valuesOf(argClassPath), "--class-path", false));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.localedata/share/classes/sun/util/cldr/resources/common/bcp47/timezone.xml	Wed Dec 13 10:56:50 2017 -0800
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE ldmlBCP47 SYSTEM "../../common/dtd/ldmlBCP47.dtd">
+<!--
+Copyright © 1991-2013 Unicode, Inc.
+CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
+For terms of use, see http://www.unicode.org/copyright.html
+-->
+
+<ldmlBCP47>
+    <version number="$Revision: 12146 $"/>
+    <keyword>
+        <key name="tz" description="Time zone key" alias="timezone">
+            <type name="adalv" description="Andorra" alias="Europe/Andorra"/>
+            <type name="aedxb" description="Dubai, United Arab Emirates" alias="Asia/Dubai"/>
+            <type name="afkbl" description="Kabul, Afghanistan" alias="Asia/Kabul"/>
+            <type name="aganu" description="Antigua" alias="America/Antigua"/>
+            <type name="aiaxa" description="Anguilla" alias="America/Anguilla"/>
+            <type name="altia" description="Tirane, Albania" alias="Europe/Tirane"/>
+            <type name="amevn" description="Yerevan, Armenia" alias="Asia/Yerevan"/>
+            <type name="ancur" description="Curaçao" alias="America/Curacao"/>
+            <type name="aolad" description="Luanda, Angola" alias="Africa/Luanda"/>
+            <type name="aqams" description="Amundsen-Scott Station, South Pole" deprecated="true" preferred="nzakl"/>
+            <type name="aqcas" description="Casey Station, Bailey Peninsula" alias="Antarctica/Casey"/>
+            <type name="aqdav" description="Davis Station, Vestfold Hills" alias="Antarctica/Davis"/>
+            <type name="aqddu" description="Dumont d'Urville Station, Terre Adélie" alias="Antarctica/DumontDUrville"/>
+            <type name="aqmaw" description="Mawson Station, Holme Bay" alias="Antarctica/Mawson"/>
+            <type name="aqmcm" description="McMurdo Station, Ross Island" alias="Antarctica/McMurdo"/>
+            <type name="aqplm" description="Palmer Station, Anvers Island" alias="Antarctica/Palmer"/>
+            <type name="aqrot" description="Rothera Station, Adelaide Island" alias="Antarctica/Rothera"/>
+            <type name="aqsyw" description="Syowa Station, East Ongul Island" alias="Antarctica/Syowa"/>
+            <type name="aqtrl" description="Troll Station, Queen Maud Land" alias="Antarctica/Troll" since="26"/>
+            <type name="aqvos" description="Vostok Station, Lake Vostok" alias="Antarctica/Vostok"/>
+            <type name="arbue" description="Buenos Aires, Argentina" alias="America/Buenos_Aires America/Argentina/Buenos_Aires"/>
+            <type name="arcor" description="Córdoba, Argentina" alias="America/Cordoba America/Argentina/Cordoba America/Rosario"/>
+            <type name="arctc" description="Catamarca, Argentina" alias="America/Catamarca America/Argentina/Catamarca America/Argentina/ComodRivadavia"/>
+            <type name="arirj" description="La Rioja, Argentina" alias="America/Argentina/La_Rioja"/>
+            <type name="arjuj" description="Jujuy, Argentina" alias="America/Jujuy America/Argentina/Jujuy"/>
+            <type name="arluq" description="San Luis, Argentina" alias="America/Argentina/San_Luis"/>
+            <type name="armdz" description="Mendoza, Argentina" alias="America/Mendoza America/Argentina/Mendoza"/>
+            <type name="arrgl" description="Río Gallegos, Argentina" alias="America/Argentina/Rio_Gallegos"/>
+            <type name="arsla" description="Salta, Argentina" alias="America/Argentina/Salta"/>
+            <type name="artuc" description="Tucumán, Argentina" alias="America/Argentina/Tucuman"/>
+            <type name="aruaq" description="San Juan, Argentina" alias="America/Argentina/San_Juan"/>
+            <type name="arush" description="Ushuaia, Argentina" alias="America/Argentina/Ushuaia"/>
+            <type name="asppg" description="Pago Pago, American Samoa" alias="Pacific/Pago_Pago Pacific/Samoa US/Samoa"/>
+            <type name="atvie" description="Vienna, Austria" alias="Europe/Vienna"/>
+            <type name="auadl" description="Adelaide, Australia" alias="Australia/Adelaide Australia/South"/>
+            <type name="aubhq" description="Broken Hill, Australia" alias="Australia/Broken_Hill Australia/Yancowinna"/>
+            <type name="aubne" description="Brisbane, Australia" alias="Australia/Brisbane Australia/Queensland"/>
+            <type name="audrw" description="Darwin, Australia" alias="Australia/Darwin Australia/North"/>
+            <type name="aueuc" description="Eucla, Australia" alias="Australia/Eucla"/>
+            <type name="auhba" description="Hobart, Australia" alias="Australia/Hobart Australia/Tasmania"/>
+            <type name="aukns" description="Currie, Australia" alias="Australia/Currie"/>
+            <type name="auldc" description="Lindeman Island, Australia" alias="Australia/Lindeman"/>
+            <type name="auldh" description="Lord Howe Island, Australia" alias="Australia/Lord_Howe Australia/LHI"/>
+            <type name="aumel" description="Melbourne, Australia" alias="Australia/Melbourne Australia/Victoria"/>
+            <type name="aumqi" description="Macquarie Island Station, Macquarie Island" alias="Antarctica/Macquarie" since="1.8.1"/>
+            <type name="auper" description="Perth, Australia" alias="Australia/Perth Australia/West"/>
+            <type name="ausyd" description="Sydney, Australia" alias="Australia/Sydney Australia/ACT Australia/Canberra Australia/NSW"/>
+            <type name="awaua" description="Aruba" alias="America/Aruba"/>
+            <type name="azbak" description="Baku, Azerbaijan" alias="Asia/Baku"/>
+            <type name="basjj" description="Sarajevo, Bosnia and Herzegovina" alias="Europe/Sarajevo"/>
+            <type name="bbbgi" description="Barbados" alias="America/Barbados"/>