Merge "Use LinuxFileSystemProvider on Fuchsia."
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 3d36a19..6a9f5b5 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -158,12 +158,6 @@
     static_libs: ["android_icu4j_resources_lib"],
     java_version: "1.9",
 
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-        "tz_version",
-    ],
-
     installable: false,
 }
 
@@ -218,12 +212,6 @@
 
     notice: "ojluni/NOTICE",
 
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-        "tz_version",
-    ],
-
 }
 
 // Contains parts of core library not associated with OpenJDK. Contains not
@@ -254,9 +242,16 @@
     },
 
     required: [
+        // Device files put in /system.
         "tzdata",
-        "tzlookup.xml",
         "tz_version",
+        // Files used to simulate the /system and runtime APEX dir
+        // structure on host.
+        "tzdata_host",
+        "tzdata_host_runtime_apex",
+        "tzlookup.xml_host_runtime_apex",
+        "tz_version_host",
+        "tz_version_host_runtime_apex",
     ],
 }
 
@@ -297,11 +292,6 @@
     },
     java_version: "1.9",
     notice: "ojluni/NOTICE",
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-        "tz_version",
-    ],
 }
 
 java_library {
@@ -316,11 +306,6 @@
         enabled: false,
     },
     notice: "ojluni/NOTICE",
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-        "tz_version",
-    ],
 }
 
 
@@ -440,6 +425,9 @@
 java_library {
     name: "filesystemstest",
     compile_dex: true,
+    dex_preopt: {
+        enabled: false,
+    },
     srcs: ["luni/src/test/filesystems/src/**/*.java"],
     java_resource_dirs: ["luni/src/test/filesystems/resources"],
     no_framework_libs: true,
@@ -453,6 +441,9 @@
 java_library {
     name: "parameter-metadata-test",
     compile_dex: true,
+    dex_preopt: {
+        enabled: false,
+    },
     srcs: ["luni/src/test/parameter_metadata/src/**/*.java"],
     no_framework_libs: true,
     javacflags: ["-parameters"],
diff --git a/NativeCode.bp b/NativeCode.bp
index 8dfbe4f..64d6cdf 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -67,6 +67,16 @@
     static_libs: [
         "libziparchive",
     ],
+    target: {
+        android: {
+            cflags: [
+                // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
+                // See external/icu/android_icu4c/include/uconfig_local.h
+                // for more information.
+                "-DANDROID_LINK_SHARED_ICU4C",
+            ],
+        },
+    },
 }
 
 cc_defaults {
@@ -108,6 +118,14 @@
                 "-D__GLIBC__",
             ],
         },
+        android: {
+            cflags: [
+                // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
+                // See external/icu/android_icu4c/include/uconfig_local.h
+                // for more information.
+                "-DANDROID_LINK_SHARED_ICU4C",
+            ],
+        },
     },
 
     notice: "ojluni/NOTICE",
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index a5f1c67..e3e36aa 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1823,11 +1823,5 @@
   result: EXEC_FAILED,
   bug: 62408076,
   name: "libcore.java.lang.reflect.annotations.AnnotatedElementParameterTest#testImplicitConstructorParameters_singleAnnotation"
-},
-{
-  description: "Awaiting fix from libcore team",
-  result: EXEC_FAILED,
-  bug: 122240208,
-  name: "libcore.libcore.icu.DateIntervalFormatTest#testEndAtMidnight"
 }
 ]
diff --git a/luni/src/main/java/libcore/net/InetAddressUtils.java b/luni/src/main/java/libcore/net/InetAddressUtils.java
index 6b8a31f..9da4a70 100644
--- a/luni/src/main/java/libcore/net/InetAddressUtils.java
+++ b/luni/src/main/java/libcore/net/InetAddressUtils.java
@@ -18,6 +18,7 @@
 import android.system.GaiException;
 import android.system.StructAddrinfo;
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import libcore.io.Libcore;
 
@@ -90,4 +91,16 @@
         }
         return addresses[0];
     }
+
+    /**
+     * Like {@link #parseNumericAddressNoThrow(String)}}, but strips optional []
+     * around a numeric IPv6 address.
+     */
+    public static InetAddress parseNumericAddressNoThrowStripOptionalBrackets(String address) {
+        // Accept IPv6 addresses (only) in square brackets for compatibility.
+        if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
+            address = address.substring(1, address.length() - 1);
+        }
+        return InetAddressUtils.parseNumericAddressNoThrow(address);
+    }
 }
diff --git a/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java b/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
index eb92459..e1bc391 100644
--- a/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
+++ b/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
@@ -67,7 +67,11 @@
     }
 
     public static String getSystemTimeZoneFile(String fileName) {
-        return System.getenv(ANDROID_ROOT_ENV) + "/usr/share/zoneinfo/" + fileName;
+        return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/share/zoneinfo/" + fileName);
+    }
+
+    public static String getSystemIcuFile(String fileName) {
+        return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu/" + fileName);
     }
 
     public static String generateIcuDataPath() {
@@ -75,7 +79,8 @@
 
         // ICU should first look in ANDROID_DATA. This is used for (optional) time zone data
         // delivered by APK (https://source.android.com/devices/tech/config/timezone-rules)
-        String dataIcuDataPath = getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu");
+        String dataIcuDataPath =
+                getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu/");
         if (dataIcuDataPath != null) {
             paths.add(dataIcuDataPath);
         }
@@ -88,7 +93,7 @@
         }
 
         // ICU should always look in ANDROID_ROOT as this is where most of the data can be found.
-        String systemIcuDataPath = getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu");
+        String systemIcuDataPath = getSystemIcuFile("");
         if (systemIcuDataPath != null) {
             paths.add(systemIcuDataPath);
         }
diff --git a/luni/src/main/java/libcore/util/DebugInfo.java b/luni/src/main/java/libcore/util/DebugInfo.java
index b6b4581..78baa71 100644
--- a/luni/src/main/java/libcore/util/DebugInfo.java
+++ b/luni/src/main/java/libcore/util/DebugInfo.java
@@ -61,6 +61,16 @@
         return entries;
     }
 
+    /** Returns the first debug entry with the given key, or {@code null} if it does not exist. */
+    public DebugEntry getDebugEntry(String key) {
+        for (DebugEntry entry : getDebugEntries()) {
+            if (key.equals(entry.getKey())) {
+                return entry;
+            }
+        }
+        return null;
+    }
+
     /**
      * A generic key/value for a single piece of debug information.
      *
diff --git a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
index 5c8e831..e9f0380 100644
--- a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
+++ b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
@@ -19,6 +19,8 @@
 import dalvik.system.VMRuntime;
 import sun.misc.Cleaner;
 
+import java.lang.ref.Reference;
+
 /**
  * A NativeAllocationRegistry is used to associate native allocations with
  * Java objects and register them with the runtime.
@@ -154,6 +156,8 @@
         } // Other exceptions are impossible.
         // Enable the cleaner only after we can no longer throw anything, including OOME.
         thunk.setNativePtr(nativePtr);
+        // Ensure that cleaner doesn't get invoked before we enable it.
+        Reference.reachabilityFence(referent);
         return result;
     }
 
@@ -204,6 +208,7 @@
         }
         registerNativeAllocation(this.size);
         thunk.setNativePtr(nativePtr);
+        Reference.reachabilityFence(referent);
         return result;
     }
 
diff --git a/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java b/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
index 9377d4e..2ea10a0 100644
--- a/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
+++ b/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
@@ -35,9 +35,10 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import libcore.io.Streams;
+
 import dalvik.system.PathClassLoader;
 import junitparams.JUnitParamsRunner;
-import sun.misc.IOUtils;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -178,11 +179,13 @@
      * MockFileSystemProvider and MockFileSystem classes.
      * @throws Exception
      */
-    ClassLoader createClassLoaderForTestFileSystems() throws Exception {
-        File jarFile = new File(filesSetup.getTestDir().toString(), "filesystemstset.jar");
-        InputStream jis = getClass().getResource("/filesystemstest.jar").openStream();
-        OutputStream jos = new FileOutputStream(jarFile);
-        jos.write(IOUtils.readFully(jis, -1, true));
+    ClassLoader createClassLoaderForTestFileSystems() throws IOException {
+        File jarFile = new File(filesSetup.getTestDir(), "filesystemstest.jar");
+        try (InputStream in = getClass().getResource("/filesystemstest.jar").openStream();
+             OutputStream out = new FileOutputStream(jarFile))
+        {
+            Streams.copy(in, out);
+        }
 
         return new PathClassLoader(jarFile.getAbsolutePath(), getClass().getClassLoader());
     }
diff --git a/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
index d8a087c..55af0e2 100644
--- a/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
@@ -20,6 +20,10 @@
 import android.icu.util.TimeZone;
 import android.icu.util.ULocale;
 
+import java.util.function.BiFunction;
+
+import static android.icu.util.TimeZone.GMT_ZONE;
+import static android.icu.util.ULocale.ENGLISH;
 import static libcore.icu.DateIntervalFormat.formatDateRange;
 import static libcore.icu.DateUtilsBridge.*;
 
@@ -433,40 +437,45 @@
   }
 
   // http://b/68847519
-  public void testEndAtMidnight() {
-    ULocale locale = new ULocale("en");
-    TimeZone timeZone = TimeZone.getTimeZone("UTC");
-    int dateTimeFlags = FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR;
+  public void testEndAtMidnight_dateAndTime() {
+    BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange(
+            ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR);
     // If we're showing times and the end-point is midnight the following day, we want the
     // behaviour of suppressing the date for the end...
-    assertEquals("February 27, 04:00 – 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 04:00 – 00:00", fmt.apply(1172548800000L, 1172620800000L));
     // ...unless the start-point is also midnight, in which case we need dates to disambiguate.
-    assertEquals("February 27, 00:00 – February 28, 00:00",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00",
+            fmt.apply(1172534400000L, 1172620800000L));
     // We want to show the date if the end-point is a millisecond after midnight the following
     // day, or if it is exactly midnight the day after that.
-    assertEquals("February 27, 04:00 – February 28, 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519776000001L, dateTimeFlags));
-    assertEquals("February 27, 04:00 – March 1, 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519862400000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 04:00 – February 28, 2007, 00:00",
+            fmt.apply(1172548800000L, 1172620800001L));
+    assertEquals("February 27, 2007, 04:00 – March 1, 2007, 00:00",
+            fmt.apply(1172548800000L, 1172707200000L));
     // We want to show the date if the start-point is anything less than a minute after midnight,
     // since that gets displayed as midnight...
-    assertEquals("February 27, 00:00 – February 28, 00:00",
-        formatDateRange(locale, timeZone, 1519689659999L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00",
+            fmt.apply(1172534459999L, 1172620800000L));
     // ...but not if it is exactly one minute after midnight.
-    assertEquals("February 27, 00:01 – 00:00",
-        formatDateRange(locale, timeZone, 1519689660000L, 1519776000000L, dateTimeFlags));
-    int dateOnlyFlags = FORMAT_SHOW_DATE;
+    assertEquals("February 27, 2007, 00:01 – 00:00", fmt.apply(1172534460000L, 1172620800000L));
+  }
+
+  // http://b/68847519
+  public void testEndAtMidnight_dateOnly() {
+    BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange(
+            ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE);
     // If we're only showing dates and the end-point is midnight of any day, we want the
-    // behaviour of showing an end date one earlier. So if the end-point is March 2, 00:00, show
-    // March 1 instead (whether the start-point is midnight or not).
-    assertEquals("February 27 – March 1",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519948800000L, dateOnlyFlags));
-    assertEquals("February 27 – March 1",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519948800000L, dateOnlyFlags));
+    // behaviour of showing an end date one earlier. So if the end-point is March 2, 2007 00:00,
+    // show March 1, 2007 instead (whether the start-point is midnight or not).
+    assertEquals("February 27 – March 1, 2007", fmt.apply(1172534400000L, 1172793600000L));
+    assertEquals("February 27 – March 1, 2007", fmt.apply(1172548800000L, 1172793600000L));
     // We want to show the true date if the end-point is a millisecond after midnight.
-    assertEquals("February 27 – March 2",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519948800001L, dateOnlyFlags));
+    assertEquals("February 27 – March 2, 2007", fmt.apply(1172534400000L, 1172793600001L));
+
+    // 2006-02-27 00:00:00.000 GMT - 2007-03-02 00:00:00.000 GMT
+    assertEquals("February 27, 2006 – March 1, 2007", fmt.apply(1140998400000L, 1172793600000L));
+
+    // Spans a leap year's Feb 29th.
+    assertEquals("February 27 – March 1, 2004", fmt.apply(1077840000000L, 1078185600000L));
   }
 }
diff --git a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
index 8881a10..67dcad8 100644
--- a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
@@ -19,8 +19,11 @@
 import org.junit.Test;
 
 import android.icu.text.TimeZoneNames;
+import android.icu.util.VersionInfo;
 
+import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
@@ -30,9 +33,16 @@
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 import libcore.icu.ICU;
+import libcore.timezone.TimeZoneDataFiles;
 import libcore.timezone.TimeZoneFinder;
+import libcore.timezone.TzDataSetVersion;
 import libcore.timezone.ZoneInfoDB;
+import libcore.util.CoreLibraryDebug;
+import libcore.util.DebugInfo;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -184,6 +194,85 @@
     }
 
     /**
+     * A test for confirming debug information matches file system state on device.
+     * It can also be used to confirm that device and host environments satisfy file system
+     * expectations.
+     */
+    @Test
+    public void testTimeZoneDebugInfo() {
+        DebugInfo debugInfo = CoreLibraryDebug.getDebugInfo();
+
+        // Devices are expected to have a time zone module which overrides or extends the data in
+        // the runtime module depending on the file. It's not actually mandatory for all Android
+        // devices right now although it may be required for some subset of Android devices. It
+        // isn't present on host ART.
+        String tzModuleStatus = getDebugStringValue(debugInfo,
+                "core_library.timezone.source.tzdata_module_status");
+        String apexRootDir = TimeZoneDataFiles.getTimeZoneModuleFile("");
+        List<String> dataModuleFiles =
+                createModuleTzFileNames(TimeZoneDataFiles::getTimeZoneModuleFile);
+        String icuOverlayFile = TimeZoneDataFiles.getTimeZoneModuleFile("icu/icu_tzdata.dat");
+        if (fileExists(apexRootDir)) {
+            assertEquals("OK", tzModuleStatus);
+            dataModuleFiles.forEach(TimeZoneIntegrationTest::assertFileExists);
+            assertFileExists(icuOverlayFile);
+        } else {
+            assertEquals("NOT_FOUND", tzModuleStatus);
+            dataModuleFiles.forEach(TimeZoneIntegrationTest::assertFileDoesNotExist);
+            assertFileDoesNotExist(icuOverlayFile);
+        }
+
+        // Every device should have a runtime module copy of time zone data since we expect every
+        // device to have a runtime module. This is the base copy of time zone data that can be
+        // updated when we update the runtime module. Host ART should match device.
+        assertEquals("OK", getDebugStringValue(debugInfo,
+                "core_library.timezone.source.runtime_module_status"));
+        assertFileExists(TimeZoneDataFiles.getRuntimeModuleFile(""));
+        List<String> runtimeModuleFiles =
+                createModuleTzFileNames(TimeZoneDataFiles::getRuntimeModuleFile);
+        runtimeModuleFiles.forEach(TimeZoneIntegrationTest::assertFileExists);
+
+        String icuDatFileName = "icudt" + VersionInfo.ICU_VERSION.getMajor() + "l.dat";
+        // TODO Make the ICU .dat file exist.
+//        assertFileDoesNotExist(TimeZoneDataFiles.getRuntimeModuleFile("icu/" + icuDatFileName));
+
+        // Devices currently have a subset of the time zone files in /system. These are going away
+        // but we test them while they exist. Host ART should match device.
+        assertEquals("OK", getDebugStringValue(debugInfo,
+                "core_library.timezone.source.system_status"));
+        assertFileExists(TimeZoneDataFiles.getSystemTimeZoneFile("tz_version"));
+        assertFileExists(TimeZoneDataFiles.getSystemTimeZoneFile("tzdata"));
+        assertFileExists(TimeZoneDataFiles.getSystemIcuFile(icuDatFileName));
+        // The following files once existed in /system but have been removed as part of APEX work.
+        assertFileDoesNotExist(TimeZoneDataFiles.getSystemTimeZoneFile("tzlookup.xml"));
+    }
+
+    private static List<String> createModuleTzFileNames(
+            Function<String, String> pathCreationFunction) {
+        List<String> relativePaths = Arrays.asList(
+                "tz/" + TzDataSetVersion.DEFAULT_FILE_NAME,
+                "tz/tzdata",
+                "tz/tzlookup.xml");
+        return relativePaths.stream().map(pathCreationFunction).collect(Collectors.toList());
+    }
+
+    private static boolean fileExists(String fileName) {
+        return new File(fileName).exists();
+    }
+
+    private static void assertFileDoesNotExist(String fileName) {
+        assertFalse(fileName + " must not exist", fileExists(fileName));
+    }
+
+    private static void assertFileExists(String fileName) {
+        assertTrue(fileName + " must exist", fileExists(fileName));
+    }
+
+    private String getDebugStringValue(DebugInfo debugInfo, String key) {
+        return debugInfo.getDebugEntry(key).getStringValue();
+    }
+
+    /**
      * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
      * ICU's IDs may be a superset.
      */
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
index 48b4ba2..29cfb2a 100644
--- a/mmodules/core_platform_api/Android.bp
+++ b/mmodules/core_platform_api/Android.bp
@@ -53,9 +53,7 @@
 
     no_standard_libs: true,
     system_modules: "none",
-    openjdk9: {
-        javacflags: ["--patch-module=java.base=."],
-    },
+    patch_module: "java.base",
 }
 
 // Used when compiling higher-level code against core.platform.api.stubs.
diff --git a/ojluni/src/main/java/java/net/Inet6AddressImpl.java b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 9b0b714..6b22f8c 100644
--- a/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -94,7 +94,7 @@
         }
 
         // Is it a numeric address?
-        InetAddress result = InetAddressUtils.parseNumericAddressNoThrow(host);
+        InetAddress result = InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(host);
         if (result != null) {
             return new InetAddress[] { result };
         }
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index c71c818..9685ffa 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -1615,18 +1615,7 @@
      */
     @Deprecated
     public static boolean isNumeric(String address) {
-        return parseNumericAddressStripOptionalBrackets(address) != null;
-    }
-
-    private static InetAddress parseNumericAddressStripOptionalBrackets(String address) {
-        if (address == null || address.isEmpty()) {
-            return Inet6Address.LOOPBACK;
-        }
-        // Accept IPv6 addresses (only) in square brackets for compatibility.
-        if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
-            address = address.substring(1, address.length() - 1);
-        }
-        return InetAddressUtils.parseNumericAddressNoThrow(address);
+        return _parseNumericAddress(address) != null;
     }
 
     /**
@@ -1640,13 +1629,20 @@
      */
     @Deprecated
     public static InetAddress parseNumericAddress(String numericAddress) {
-        InetAddress result = parseNumericAddressStripOptionalBrackets(numericAddress);
+        InetAddress result = _parseNumericAddress(numericAddress);
         if (result == null) {
             throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
         }
         return result;
     }
 
+    private static InetAddress _parseNumericAddress(String numericAddress) {
+        if (numericAddress == null || numericAddress.isEmpty()) {
+            return Inet6Address.LOOPBACK;
+        }
+        return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
+    }
+
     /**
      * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
      * cache, nor any caching DNS servers between you and the canonical server.
diff --git a/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java b/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
index 1009bda..0c6de1d 100644
--- a/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
+++ b/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
@@ -59,10 +59,16 @@
         this.cleaner = Cleaner.create(this, new Deallocator(address));
     }
 
+    // Android-note: releaseNativeBuffer() ensures that its argument is strongly reachable.
     void release() {
         NativeBuffers.releaseNativeBuffer(this);
     }
 
+    // BEGIN Android-note: Lifecycle contract of NativeBuffer.address() relative to release().
+    // We require that:
+    // 1) NativeBuffer is ALWAYS explicitly release()ed before being dropped, and
+    // 2) The result of address() is only used before release() is called.
+    // END Android-note: Lifecycle contract of NativeBuffer.address() relative to release().
     long address() {
         return address;
     }
diff --git a/ojluni/src/main/native/MappedByteBuffer.c b/ojluni/src/main/native/MappedByteBuffer.c
index a5b0b04..72e840a 100644
--- a/ojluni/src/main/native/MappedByteBuffer.c
+++ b/ojluni/src/main/native/MappedByteBuffer.c
@@ -40,6 +40,11 @@
 Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address,
                                          jlong len, jint numPages)
 {
+// BEGIN Android-added: Fuchsia holds all pages in memory. http://b/119503290
+#if defined(__Fuchsia__)
+    return JNI_TRUE;
+#else
+// END Android-added: Fuchsia holds all pages in memory. http://b/119503290
     jboolean loaded = JNI_TRUE;
     int result = 0;
     int i = 0;
@@ -70,6 +75,8 @@
     }
     free(vec);
     return loaded;
+// Android-added: Fuchsia holds all pages in memory. http://b/119503290
+#endif
 }