Merge "[automerger skipped] Merge "Merge "Allow some slop on socket time values" into oreo-cts-dev am: 5bb4ad5d54" into oreo-mr1-cts-dev am: fed6186c74  -s ours" into pie-cts-dev
am: d731f01fe6  -s ours

Change-Id: Id0e8690ac47a935f0096d8decffc3986ffe23d90
diff --git a/Android.bp b/Android.bp
index c47c096..e57045f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3,19 +3,15 @@
     "NativeCode.bp",
 ]
 
-python_binary_host {
-    name: "gen-annotated-java-files-bp",
-    main: "annotations/generate_annotated_java_files.py",
-    srcs: [
-        "annotations/generate_annotated_java_files.py",
+genrule {
+    name: "notices-for-framework-stubs",
+    tool_files: [
+        "NOTICE",
+        "ojluni/NOTICE",
     ],
-    version: {
-        py2: {
-            enabled: true,
-            embedded_launcher: true,
-        },
-        py3: {
-            enabled: false,
-        },
-    },
+    cmd: "cp -f $(location NOTICE) $(genDir)/NOTICES/libcore-NOTICE && cp -f $(location ojluni/NOTICE) $(genDir)/NOTICES/ojluni-NOTICE",
+    out: [
+        "NOTICES/libcore-NOTICE",
+        "NOTICES/ojluni-NOTICE",
+    ],
 }
diff --git a/AndroidTest-core-tests.xml b/AndroidTest-core-tests.xml
new file mode 100644
index 0000000..8d8f7ae
--- /dev/null
+++ b/AndroidTest-core-tests.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- This test config is placed here for use by atest to enable it to determine
+     which tests to run for core-tests.jar (only). It assumes that the majority
+     of tests for libcore are in the CtsLibcoreTestCases module and therefore
+     does not help for tests where that is not the case.
+
+     This file is effectively a copy of the real CtsLibcoreTestCases
+     AndroidTest.xml file and should track the content of that file.
+
+     TODO: b/114773808 to remove this copied config and execute core-tests.jar
+     directly.
+-->
+<configuration description="Config for Libcore test cases">
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
+        <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/ctslibcore" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <!-- this has just the instrumentation which acts as the tests we want to run -->
+        <option name="test-file-name" value="CtsLibcoreTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.testtype.LibcoreTest" >
+        <option name="package" value="android.libcore.cts" />
+        <option name="instrumentation-arg" key="filter"
+                value="com.android.cts.core.runner.ExpectationBasedFilter" />
+        <option name="core-expectation" value="/knownfailures.txt" />
+        <option name="runtime-hint" value="45m"/>
+        <!-- 20x default timeout of 600sec -->
+        <option name="shell-timeout" value="12000000"/>
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/AndroidTest.xml b/AndroidTest.xml
deleted file mode 100644
index 78ed943..0000000
--- a/AndroidTest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for libjavacore-benchmarks">
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="libjavacore-benchmarks->/data/benchmarktest/libjavacore-benchmarks" />
-    </target_preparer>
-    <option name="test-suite-tag" value="apct" />
-    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
-        <option name="native-benchmark-device-path" value="/data/benchmarktest" />
-        <option name="benchmark-module-name" value="libjavacore-benchmarks" />
-    </test>
-</configuration>
diff --git a/Docs.mk b/Docs.mk
index 28abc8b..d448537 100644
--- a/Docs.mk
+++ b/Docs.mk
@@ -18,17 +18,6 @@
    )
 _icu_files := $(addprefix external/icu/, $(_icu_files))
 
-
-# Get list of targets annotated with annotations from jaif file
-# Remove un-annotated original source file and replace them with annotated targets
-#
-ojluni_annotate_src := $(patsubst libcore/ojluni/src/main/java/%,%, $(annotated_ojluni_files))
-ojluni_annotate_output := $(patsubst %,$(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/annotated/%, $(ojluni_annotate_src))
-_libcore_files := $(filter-out $(patsubst %, libcore/ojluni/src/main/java/%, $(ojluni_annotate_src)), $(_libcore_files))
-_libcore_generated_files := $(ojluni_annotate_output)
-ojluni_annotate_src:=
-ojluni_annotate_output:=
-
 # List of libcore-related javadoc source files
 #
 # NOTE: Because libcore-related source spans modules (not just libcore!), files names here are
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 378aca2..e88f8ea 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -16,26 +16,27 @@
 // Definitions for building the Java library and associated tests.
 //
 
-// libcore is divided into modules.
+// libcore has some sub-directories that follow a common structure:
+// e.g. dalvik, dom, harmony-tests, json, jsr166-tests, luni, libart, ojluni,
+// support, xml, xmlpull.
 //
-// The structure of each module is:
+// The structure of these is generally:
 //
 //   src/
 //       main/               # To be shipped on every device.
 //            java/          # Java source for library code.
-//            native/        # C++ source for library code.
+//            native/        # C/C++ source for library code.
 //            resources/     # Support files.
 //       test/               # Built only on demand, for testing.
 //            java/          # Java source for tests.
-//            native/        # C++ source for tests (rare).
+//            native/        # C/C++ source for tests (rare).
 //            resources/     # Support files.
 //
-// All subdirectories are optional
+// All subdirectories are optional.
 
 build = [
     "openjdk_java_files.bp",
     "non_openjdk_java_files.bp",
-    "annotated_java_files.bp",
 ]
 
 // The Java files and their associated resources.
@@ -44,6 +45,49 @@
     "ojluni/src/main/resources/",
 ]
 
+// The source files that go into core-oj.
+filegroup {
+    name: "core_oj_java_files",
+    srcs: [":openjdk_java_files"],
+}
+
+// OpenJDK source is not annotated with @hide so we need a separate
+// filegroup for just the parts that contribute to the API.
+filegroup {
+    name: "core_oj_api_files",
+    srcs: [":openjdk_javadoc_files"],
+}
+
+// The source files that go into core-libart.
+filegroup {
+    name: "core_libart_java_files",
+    srcs: [
+        ":non_openjdk_java_files",
+        ":android_icu4j_src_files",
+    ],
+}
+
+// Some parts of libart are not annotated with @hide so we need a separate
+// filegroup for just the parts that contribute to the API.
+filegroup {
+    name: "core_libart_api_files",
+    srcs: [
+        ":non_openjdk_javadoc_files",
+        ":android_icu4j_src_files",
+    ],
+}
+
+// The set of files in core that have been marked up with @hide and API-related
+// annotations.
+filegroup {
+    name: "core_api_files",
+    srcs: [
+        ":core_oj_api_files",
+        ":core_libart_api_files",
+        ":core_simple_java_files",
+    ],
+}
+
 java_defaults {
     name: "libcore_java_defaults",
     javacflags: [
@@ -51,10 +95,10 @@
         //"-Xlint:-serial,-deprecation,-unchecked",
     ],
     dxflags: ["--core-library"],
-    no_standard_libs: true,
     errorprone: {
         javacflags: [
             "-Xep:MissingOverride:OFF",  // Ignore missing @Override.
+            "-Xep:ConstantOverflow:WARN",  // Known constant overflow in SplittableRandom
         ],
     },
 }
@@ -68,15 +112,19 @@
     defaults: ["libcore_java_defaults"],
 
     srcs: [
-        ":openjdk_java_files",
-        ":non_openjdk_java_files",
-        ":android_icu4j_src_files",
+        ":core_oj_java_files",
+        ":core_libart_java_files",
+        ":core_simple_java_files",
         ":openjdk_lambda_stub_files",
     ],
+
+    no_standard_libs: true,
+    system_modules: "none",
     openjdk9: {
         srcs: ["luni/src/module/java/module-info.java"],
         javacflags: ["--patch-module=java.base=."],
     },
+
     java_resource_dirs: core_resource_dirs,
     java_resources: [":android_icu4j_resources"],
 
@@ -85,8 +133,6 @@
         "tzlookup.xml",
     ],
 
-    system_modules: "none",
-
     installable: false,
 }
 
@@ -98,15 +144,19 @@
 java_library {
     name: "core-oj",
     defaults: ["libcore_java_defaults"],
+    installable: true,
     hostdex: true,
 
-    srcs: [":openjdk_java_files"],
+    srcs: [":core_oj_java_files"],
     java_resource_dirs: core_resource_dirs,
+
+    no_standard_libs: true,
     libs: ["core-all"],
     system_modules: "core-all-system-modules",
     openjdk9: {
         javacflags: ["--patch-module=java.base=."],
     },
+
     jacoco: {
         exclude_filter: [
             "java.lang.Class",
@@ -137,19 +187,19 @@
 java_library {
     name: "core-libart",
     defaults: ["libcore_java_defaults"],
+    installable: true,
     hostdex: true,
 
-    srcs: [
-        ":non_openjdk_java_files",
-        ":android_icu4j_src_files",
-    ],
+    srcs: [":core_libart_java_files"],
     java_resources: [":android_icu4j_resources"],
 
+    no_standard_libs: true,
     libs: ["core-all"],
     system_modules: "core-all-system-modules",
     openjdk9: {
         javacflags: ["--patch-module=java.base=."],
     },
+
     jacoco: {
         exclude_filter: [
             "java.lang.DexCache",
@@ -168,6 +218,7 @@
 // but these will not be stripped. See b/24535627.
 java_library {
     name: "core-oj-testdex",
+    installable: true,
     static_libs: ["core-oj"],
     no_standard_libs: true,
     libs: ["core-all"],
@@ -185,6 +236,7 @@
 
 java_library {
     name: "core-libart-testdex",
+    installable: true,
     static_libs: ["core-libart"],
     no_standard_libs: true,
     libs: ["core-all"],
@@ -211,6 +263,7 @@
         ":openjdk_lambda_duplicate_stub_files",
     ],
 
+    no_standard_libs: true,
     libs: ["core-all"],
     system_modules: "core-all-system-modules",
     openjdk9: {
@@ -223,12 +276,16 @@
     include_srcs: true,
 }
 
+// The libraries that make up core.
 java_system_modules {
     name: "core-system-modules",
     libs: [
         "core-oj",
         "core-libart",
-        "core-lambda-stubs",
+        "core-simple",
+        // This one is not on device but it's needed when javac compiles code
+        // containing lambdas.
+        "core-lambda-stubs"
     ],
 }
 
@@ -261,7 +318,7 @@
 }
 
 // Make the jsr166-tests library.
-java_library_static {
+java_test {
     name: "jsr166-tests",
     srcs: ["jsr166-tests/src/test/java/**/*.java"],
     no_framework_libs: true,
@@ -270,52 +327,197 @@
     ],
 }
 
-genrule {
-    name: "gen-ojluni-jaif-annotated-srcs",
-    tools: [
-        "gen-annotated-java-files-bp",
-        "soong_zip",
-    ],
-    tool_files: [
-        ":insert-annotations-to-source",
-        "annotations/ojluni.jaif",
-    ],
+// Build a library just containing files from luni/src/test/filesystems for use in tests.
+java_library {
+    name: "filesystemstest",
+    compile_dex: true,
+    srcs: ["luni/src/test/filesystems/src/**/*.java"],
+    java_resource_dirs: ["luni/src/test/filesystems/resources"],
+    no_framework_libs: true,
+    errorprone: {
+        javacflags: ["-Xep:MissingOverride:OFF"],
+    },
+}
+
+// Build a library just containing files from luni/src/test/parameter_metadata for use in tests.
+java_library {
+    name: "parameter-metadata-test",
+    compile_dex: true,
+    srcs: ["luni/src/test/parameter_metadata/src/**/*.java"],
+    no_framework_libs: true,
+    javacflags: ["-parameters"],
+    errorprone: {
+        javacflags: ["-Xep:MissingOverride:OFF"],
+    },
+}
+
+// Make the core-tests library.
+java_test {
+    name: "core-tests",
+    defaults: ["libcore_java_defaults"],
+    hostdex: true,
+    no_framework_libs: true,
     srcs: [
-        ":annotated_ojluni_files",
+        "dalvik/src/test/java/**/*.java",
+        "dalvik/test-rules/src/test/java/**/*.java",
+        "dom/src/test/java/**/*.java",
+        "harmony-tests/src/test/java/**/*.java",
+        "json/src/test/java/**/*.java",
+        "luni/src/test/java/**/*.java",
+        "xml/src/test/java/**/*.java",
     ],
-    cmd: "($(location gen-annotated-java-files-bp) $(location annotations/ojluni.jaif) > $(genDir)/annotated_java_files.bp.tmp) && " +
-         "(diff -u `pwd`/libcore/annotated_java_files.bp $(genDir)/annotated_java_files.bp.tmp || " +
-         "(echo -e \"********************\" >&2; " +
-         " echo -e \"annotated_java_files.bp needs regenerating. Please run:\" >&2; " +
-         " echo -e \"libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp\" >&2; " +
-         " echo -e \"********************\" >&2; exit 1) ) && " +
-         "(rm $(genDir)/annotated_java_files.bp.tmp) && " +
-         "(external/annotation-tools/annotation-file-utilities/scripts/insert-annotations-to-source -d $(genDir) $(location annotations/ojluni.jaif) $(in)) && " +
-         "($(location soong_zip) -o $(out) -C $(genDir) -D $(genDir))",
-    out: [
-        "ojluni_jaif_annotated_srcs.srcjar",
+    exclude_srcs: [
+        "luni/src/test/java/libcore/java/util/zip/Zip64Test.java",
+        "luni/src/test/java/libcore/java/util/zip/Zip64FileTest.java",
+    ],
+
+    java_resource_dirs: [
+        "*/src/test/java",
+        "*/src/test/resources",
+    ],
+    exclude_java_resource_dirs: [
+        "ojluni/src/test/java",
+        "ojluni/src/test/resources",
+    ],
+
+    java_resources: [
+        ":filesystemstest",
+        ":parameter-metadata-test",
+    ],
+
+    libs: [
+        "okhttp",
+        "bouncycastle",
+    ],
+    static_libs: [
+        "archive-patcher",
+        "core-test-rules",
+        "core-tests-support",
+        "junit-params",
+        "mockftpserver",
+        "mockito-target",
+        "mockwebserver",
+        "nist-pkix-tests",
+        "slf4j-jdk14",
+        "sqlite-jdbc",
+        "tzdata-testing",
+    ],
+
+    errorprone: {
+        javacflags: [
+            "-Xep:TryFailThrowable:ERROR",
+            "-Xep:ComparisonOutOfRange:ERROR",
+        ],
+    },
+
+    test_config: "AndroidTest-core-tests.xml",
+}
+
+// Make the core-ojtests library.
+java_test {
+    name: "core-ojtests",
+    defaults: ["libcore_java_defaults"],
+    hostdex: true,
+    no_framework_libs: true,
+
+    srcs: [
+        "ojluni/src/test/java/**/*.java",
+    ],
+    java_resource_dirs: [
+        "ojluni/src/test/java",
+        "ojluni/src/test/resources",
+    ],
+    libs: [
+        "okhttp",
+        "bouncycastle",
+    ],
+    static_libs: ["testng"],
+
+    // ojluni/src/test/java/util/stream/{bootlib,boottest}
+    // contains tests that are in packages from java.base;
+    // By default, OpenJDK 9's javac will only compile such
+    // code if it's declared to also be in java.base at
+    // compile time.
+    //
+    // For now, we use --patch-module to put all sources
+    // and dependencies from this make target into java.base;
+    // other source directories in this make target are in
+    // packages not from java.base; if this becomes a problem
+    // in future, this could be addressed eg. by splitting
+    // boot{lib,test} out into a separate make target,
+    // deleting those tests or moving them to a different
+    // package.
+    patch_module: "java.base",
+}
+
+// Make the core-ojtests-public library. Excludes any private API tests.
+java_test {
+    name: "core-ojtests-public",
+    defaults: ["libcore_java_defaults"],
+    no_framework_libs: true,
+    srcs: [
+        "ojluni/src/test/java/**/*.java",
+    ],
+    // Filter out the following:
+    // 1.) DeserializeMethodTest and SerializedLambdaTest, because they depends on stub classes
+    //     and won't actually run, and
+    // 2.) util/stream/boot*. Those directories contain classes in the package java.util.stream;
+    //     excluding them means we don't need patch_module: "java.base"
+    exclude_srcs: [
+        "**/DeserializeMethodTest.java",
+        "**/SerializedLambdaTest.java",
+        "ojluni/src/test/java/util/stream/boot*/**/*",
+    ],
+    java_resource_dirs: [
+        "ojluni/src/test/java",
+        "ojluni/src/test/resources",
+        // Include source code as part of JAR
+        "ojluni/src/test/dist",
+    ],
+    libs: [
+        "bouncycastle",
+        "okhttp",
+        "testng",
     ],
 }
 
-droiddoc {
-    name: "core-docs",
+// Make the annotated stubs in ojluni/annotations available to metalava:
+droiddoc_exported_dir {
+    name: "ojluni-annotated-sdk-stubs",
+    path: "ojluni/annotations/sdk",
+}
+
+// A file containing the list of tags that are "known" to us from the OpenJdk
+// source code and so should not cause an error or warning.
+filegroup {
+    name: "known-oj-tags",
     srcs: [
-        ":openjdk_javadoc_files",
-        ":non_openjdk_javadoc_files",
-        ":android_icu4j_src_files_for_docs",
-        ":gen-ojluni-jaif-annotated-srcs",
-    ],
-    exclude_srcs: [
-        ":annotated_ojluni_files",
-    ],
-    custom_template: "droiddoc-templates-sdk",
-    hdf: [
-        "android.whichdoc offline",
-    ],
-    knowntags: [
         "known_oj_tags.txt",
     ],
-    proofread_file: "core-docs-proofread.txt",
-    todo_file: "core-docs-todo.html",
-    args: "-offlinemode -title \"libcore\"",
+}
+
+// Stubs for the parts of the public SDK API provided by the core libraries.
+droidstubs {
+    name: "core-current-stubs-gen",
+    srcs: [":core_api_files"],
+    installable: false,
+    no_framework_libs: true,
+    args: " --exclude-annotations",
+}
+
+// A library containing the parts of the public SDK API provided by the core libraries.
+// Don't use this directly, use "sdk_version: core_current".
+java_library {
+    name: "core.current.stubs",
+    srcs: [":core-current-stubs-gen"],
+    errorprone: {
+        javacflags: [
+            "-Xep:MissingOverride:OFF",
+        ],
+    },
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+    no_standard_libs: true,
+    system_modules: "none",
 }
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 81fb460..f5f9f70 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -13,399 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#
-# Definitions for building the Java library and associated tests.
-#
-
-#
-# Common definitions for host and target.
-#
-
-# libcore is divided into modules.
-#
-# The structure of each module is:
-#
-#   src/
-#       main/               # To be shipped on every device.
-#            java/          # Java source for library code.
-#            native/        # C++ source for library code.
-#            resources/     # Support files.
-#       test/               # Built only on demand, for testing.
-#            java/          # Java source for tests.
-#            native/        # C++ source for tests (rare).
-#            resources/     # Support files.
-#
-# All subdirectories are optional (hence the "2> /dev/null"s below).
-
-define all-test-java-files-under
-$(foreach dir,$(1),$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && (find $(dir)/src/test/java -name "*.java" 2> /dev/null) | grep -v -f java_tests_blacklist)))
-endef
-
-define all-core-resource-dirs
-$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/{java,resources} 2> /dev/null)
-endef
-
-# The Java files and their associated resources.
-core_resource_dirs := \
-  luni/src/main/java \
-  ojluni/src/main/resources/
-test_resource_dirs := $(filter-out ojluni/%,$(call all-core-resource-dirs,test))
-test_src_files := $(call all-test-java-files-under,dalvik dalvik/test-rules dom harmony-tests json luni xml)
-ojtest_src_files := $(call all-test-java-files-under,ojluni)
-ojtest_resource_dirs := $(filter ojluni/%,$(call all-core-resource-dirs,test))
-
-ifeq ($(EMMA_INSTRUMENT),true)
-ifneq ($(EMMA_INSTRUMENT_STATIC),true)
-    nojcore_src_files += $(call all-java-files-under, ../external/emma/core ../external/emma/pregenerated)
-    core_resource_dirs += ../external/emma/core/res ../external/emma/pregenerated/res
-endif
-endif
-
-local_javac_flags=-encoding UTF-8
-#local_javac_flags+=-Xlint:all -Xlint:-serial,-deprecation,-unchecked
-local_javac_flags+=-Xmaxwarns 9999999
-
-# For user / userdebug builds, strip the local variable table and the local variable
-# type table. This has no bearing on stack traces, but will leave less information
-# available via JDWP.
-#
-# TODO: Should this be conditioned on a PRODUCT_ flag or should we just turn this
-# on for all builds. Also, name of the flag TBD.
-ifneq (,$(PRODUCT_MINIMIZE_JAVA_DEBUG_INFO))
-ifneq (,$(filter userdebug user,$(TARGET_BUILD_VARIANT)))
-local_javac_flags+= -g:source,lines
-local_jack_flags+= -D jack.dex.debug.vars=false -D jack.dex.debug.vars.synthetic=false
-endif
-endif
-
-#
-# ICU4J related rules.
-#
-# We compile android_icu4j along with core-libart because we're implementing parts of core-libart
-# in terms of android_icu4j.
-android_icu4j_root := ../external/icu/android_icu4j/
-android_icu4j_src_files := $(call all-java-files-under,$(android_icu4j_root)/src/main/java)
-android_icu4j_resource_dirs := $(android_icu4j_root)/resources
-
-#
-# Build jaif-annotated source files for ojluni target .
-#
-ojluni_annotate_dir := $(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/annotated
-ojluni_annotate_target := $(ojluni_annotate_dir)/timestamp
-ojluni_annotate_jaif := $(LOCAL_PATH)/annotations/ojluni.jaif
-ojluni_annotate_input := $(annotated_ojluni_files)
-ojluni_annotate_output := $(patsubst $(LOCAL_PATH)/ojluni/src/main/java/%, $(ojluni_annotate_dir)/%, $(ojluni_annotate_input))
-
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_TARGET := $(ojluni_annotate_target)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_DIR := $(ojluni_annotate_dir)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_JAIF := $(ojluni_annotate_jaif)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_INPUT := $(ojluni_annotate_input)
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_GENERATE_CMD := $(LOCAL_PATH)/annotations/generate_annotated_java_files.py
-$(ojluni_annotate_target): PRIVATE_ANNOTATE_GENERATE_OUTPUT := $(LOCAL_PATH)/annotated_java_files.bp
-$(ojluni_annotate_target): PRIVATE_INSERT_ANNOTATIONS_TO_SOURCE := external/annotation-tools/annotation-file-utilities/scripts/insert-annotations-to-source
-
-# Diff output of _ojluni_annotate_generate_cmd with what we have, and if generate annotated source.
-$(ojluni_annotate_target):  $(ojluni_annotate_input) $(ojluni_annotate_jaif)
-	rm -rf $(PRIVATE_ANNOTATE_DIR)
-	mkdir -p $(PRIVATE_ANNOTATE_DIR)
-	$(PRIVATE_ANNOTATE_GENERATE_CMD) $(PRIVATE_ANNOTATE_JAIF) > $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp
-	diff -u $(PRIVATE_ANNOTATE_GENERATE_OUTPUT) $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp || \
-	(echo -e "********************" >&2; \
-	 echo -e "annotated_java_files.bp needs regenerating. Please run:" >&2; \
-	 echo -e "libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp" >&2; \
-	 echo -e "********************" >&2; exit 1)
-	rm $(PRIVATE_ANNOTATE_DIR)/annotated_java_files.bp.tmp
-	$(PRIVATE_INSERT_ANNOTATIONS_TO_SOURCE) -d $(PRIVATE_ANNOTATE_DIR) $(PRIVATE_ANNOTATE_JAIF) $(PRIVATE_ANNOTATE_INPUT)
-	touch $@
-$(ojluni_annotate_target): .KATI_IMPLICIT_OUTPUTS := $(ojluni_annotate_output)
-
-ojluni_annotate_dir:=
-ojluni_annotate_target:=
-ojluni_annotate_jaif:=
-ojluni_annotate_input:=
-ojluni_annotate_output:=
-
-#
-# Build for the target (device).
-#
-ifeq ($(LIBCORE_SKIP_TESTS),)
-# Build a library just containing files from luni/src/test/filesystems for use in tests.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, luni/src/test/filesystems/src)
-LOCAL_JAVA_RESOURCE_DIRS := luni/src/test/filesystems/resources
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := filesystemstest
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_DEX_PREOPT := false
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_JAVA_LIBRARY)
-
-filesystemstest_jar := $(intermediates)/$(LOCAL_MODULE).jar
-$(filesystemstest_jar): $(LOCAL_BUILT_MODULE)
-	$(call copy-file-to-target)
-
-# Build a library just containing files from luni/src/test/parameter_metadata for use in tests.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, luni/src/test/parameter_metadata/src)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := parameter-metadata-test
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
-LOCAL_DEX_PREOPT := false
-LOCAL_JAVACFLAGS := -parameters
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_JAVA_LIBRARY)
-
-parameter_metadata_test_jar := $(intermediates)/$(LOCAL_MODULE).jar
-$(parameter_metadata_test_jar): $(LOCAL_BUILT_MODULE)
-	$(call copy-file-to-target)
-
-endif
-
-ifeq ($(LIBCORE_SKIP_TESTS),)
-# Make the core-tests library.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(test_src_files)
-LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-# Include individual dex.jar files (jars containing resources and a classes.dex) so that they
-# be loaded by tests using ClassLoaders but are not in the main classes.dex.
-LOCAL_JAVA_RESOURCE_FILES := $(filesystemstest_jar) $(parameter_metadata_test_jar)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	archive-patcher \
-	core-test-rules \
-	core-tests-support \
-	junit-params \
-	mockftpserver \
-	mockito-target \
-	mockwebserver \
-	nist-pkix-tests \
-	slf4j-jdk14 \
-	sqlite-jdbc \
-	tzdata-testing
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_JACK_FLAGS := $(local_jack_flags)
-LOCAL_ERROR_PRONE_FLAGS := \
-        -Xep:TryFailThrowable:ERROR \
-        -Xep:ComparisonOutOfRange:ERROR \
-        -Xep:MissingOverride:OFF
-LOCAL_MODULE := core-tests
-include $(BUILD_STATIC_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
-    include $(CLEAR_VARS)
-    LOCAL_JAVA_RESOURCE_DIRS := $(ojtest_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
-    LOCAL_STATIC_JAVA_LIBRARIES := testng
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_JACK_FLAGS := $(local_jack_flags)
-    LOCAL_DX_FLAGS := --core-library
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-ojtests
-    # jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
-    LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
-    LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-    include $(BUILD_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests-public library. Excludes any private API tests.
-ifeq ($(LIBCORE_SKIP_TESTS),)
-    include $(CLEAR_VARS)
-    # Filter out the following:
-    # 1.) DeserializeMethodTest and SerializedLambdaTest, because they depends on stub classes
-    #     and won't actually run, and
-    # 2.) util/stream/boot*. Those directories contain classes in the package java.util.stream;
-    #     excluding them means we don't need LOCAL_PATCH_MODULE := java.base
-    LOCAL_SRC_FILES := $(filter-out %/DeserializeMethodTest.java %/SerializedLambdaTest.java ojluni/src/test/java/util/stream/boot%,$(ojtest_src_files))
-    # Include source code as part of JAR
-    LOCAL_JAVA_RESOURCE_DIRS := ojluni/src/test/dist $(ojtest_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := \
-        bouncycastle \
-        core-libart \
-        core-oj \
-        okhttp \
-        testng
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_JACK_FLAGS := $(local_jack_flags)
-    LOCAL_DX_FLAGS := --core-library
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-ojtests-public
-    # jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
-    LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
-    LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-    include $(BUILD_JAVA_LIBRARY)
-endif
-
-#
-# Build for the host.
-#
-
-ifeq ($(HOST_OS),linux)
-
-# Make the core-tests-hostdex library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
-    include $(CLEAR_VARS)
-    LOCAL_SRC_FILES := $(test_src_files)
-    LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := \
-        bouncycastle-hostdex \
-        core-libart-hostdex \
-        core-oj-hostdex \
-        core-tests-support-hostdex \
-        junit-hostdex \
-        mockito-api-hostdex \
-        okhttp-hostdex
-    LOCAL_STATIC_JAVA_LIBRARIES := \
-        archive-patcher-hostdex \
-        core-test-rules-hostdex \
-        junit-params-hostdex \
-        mockftpserver-hostdex \
-        mockwebserver-host \
-        nist-pkix-tests-host \
-        slf4j-jdk14-hostdex \
-        sqlite-jdbc-host \
-        tzdata-testing-hostdex
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-tests-hostdex
-    LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-endif
-
-# Make the core-ojtests-hostdex library.
-ifeq ($(LIBCORE_SKIP_TESTS),)
-    include $(CLEAR_VARS)
-    LOCAL_SRC_FILES := $(ojtest_src_files)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := \
-        bouncycastle-hostdex \
-        core-libart-hostdex \
-        core-oj-hostdex \
-        okhttp-hostdex
-    LOCAL_STATIC_JAVA_LIBRARIES := testng-hostdex
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_DX_FLAGS := --core-library
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-ojtests-hostdex
-    # ojluni/src/test/java/util/stream/{bootlib,boottest}
-    # contains tests that are in packages from java.base;
-    # By default, OpenJDK 9's javac will only compile such
-    # code if it's declared to also be in java.base at
-    # compile time.
-    #
-    # For now, we use --patch-module to put all sources
-    # and dependencies from this make target into java.base;
-    # other source directories in this make target are in
-    # packages not from java.base; if this becomes a proble
-    # in future, this could be addressed eg. by splitting
-    # boot{lib,test} out into a separate make target,
-    # deleting those tests or moving them to a different
-    # package.
-    LOCAL_PATCH_MODULE := java.base
-    LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-endif
-
-endif # HOST_OS == linux
-
-#
-# Local droiddoc for faster libcore testing
-#
-#
-# Run with:
-#     mm -j32 libcore-docs
-#
-# Main output:
-#     ../out/target/common/docs/libcore/reference/packages.html
-#
-# All text for proofreading (or running tools over):
-#     ../out/target/common/docs/libcore-proofread.txt
-#
-# TODO list of missing javadoc, etc:
-#     ../out/target/common/docs/libcore-docs-todo.html
-#
-# Rerun:
-#     rm -rf ../out/target/common/docs/libcore-timestamp && mm -j32 libcore-docs
-#
-include $(CLEAR_VARS)
-
-# for shared defintion of libcore_to_document
-include $(LOCAL_PATH)/Docs.mk
-
-# The libcore_to_document paths are relative to $(TOPDIR). We are in libcore so we must prepend
-# ../ to make LOCAL_SRC_FILES relative to $(LOCAL_PATH).
-LOCAL_SRC_FILES := $(addprefix ../, $(libcore_to_document))
-LOCAL_INTERMEDIATE_SOURCES := \
-    $(patsubst $(TARGET_OUT_COMMON_INTERMEDIATES)/%,%,$(libcore_to_document_generated))
-LOCAL_ADDITIONAL_DEPENDENCIES := $(libcore_to_document_generated)
-# rerun doc generation without recompiling the java
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_MODULE_CLASS:=JAVA_LIBRARIES
-
-LOCAL_MODULE := libcore
-
-LOCAL_DROIDDOC_OPTIONS := \
- -offlinemode \
- -title "libcore" \
- -proofread $(OUT_DOCS)/$(LOCAL_MODULE)-proofread.txt \
- -todo ../$(LOCAL_MODULE)-docs-todo.html \
- -knowntags ./libcore/known_oj_tags.txt \
- -hdf android.whichdoc offline
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
-
-include $(BUILD_DROIDDOC)
-
-# For unbundled build we'll use the prebuilt jar from prebuilts/sdk.
-ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)))
-
-# Generate the stub source files for core.current.stubs
-# =====================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(addprefix ../, $(libcore_to_document))
-LOCAL_GENERATED_SOURCES := $(libcore_to_document_generated)
-
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-LOCAL_DROIDDOC_OPTIONS:= \
-    -stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/core.current.stubs_intermediates/src \
-    -nodocs \
-
-LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_MODULE := core-current-stubs-gen
-
-include $(BUILD_DROIDDOC)
-
-# Remember the target that will trigger the code generation.
-core_current_gen_stamp := $(full_target)
-
-# Build the core.current.stubs library
-# ====================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := core.current.stubs
-
-LOCAL_SOURCE_FILES_ALL_GENERATED := true
-
-# Make sure to run droiddoc first to generate the stub source files.
-LOCAL_ADDITIONAL_DEPENDENCIES := $(core_current_gen_stamp)
-core_current_gen_stamp :=
-
-# Because javac refuses to compile these stubs with --system=none, ( http://b/72206056#comment31 ),
-# just patch them into java.base at compile time.
-LOCAL_PATCH_MODULE := java.base
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
 # Archive a copy of the classes.jar in SDK build.
+full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,core.current.stubs,,COMMON)/classes.jar
 $(call dist-for-goals,sdk win_sdk,$(full_classes_jar):core.current.stubs.jar)
-
-endif  # not TARGET_BUILD_APPS not TARGET_BUILD_PDK=true
diff --git a/NativeCode.bp b/NativeCode.bp
index 3780e7d..840b19a 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -21,7 +21,6 @@
 cc_defaults {
     name: "core_native_default_flags",
     host_supported: true,
-    local_include_dirs: ["include"],
     cflags: [
         "-Wall",
         "-Wextra",
@@ -39,11 +38,11 @@
 cc_defaults {
     name: "core_native_default_libs",
     static_libs: [
-        "libbase",
         "libfdlibm",
     ],
 
     shared_libs: [
+        "libbase",
         "liblog",
         "libnativehelper",
     ],
@@ -61,6 +60,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libcrypto",
         "libexpat",
         "libicuuc",
@@ -70,7 +70,6 @@
     ],
     static_libs: [
         "libziparchive",
-        "libbase",
     ],
     target: {
         android: {
diff --git a/OWNERS b/OWNERS
index 91f818d..c6b3546 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,15 +4,15 @@
 # People who can approve changes for submission; don't send review emails to them
 # unless you know what you're doing.
 flooey@google.com
-jsauer@google.com
 narayan@google.com
 nfuller@google.com
 paulduffin@google.com
 peteg@google.com
-pszczepaniak@google.com
+prb@google.com
 tobiast@google.com
 vichang@google.com
 
 # Don't send these folks any review emails for this project.
 ngeoffray@google.com
 sehr@google.com
+vmarko@google.com
diff --git a/annotated_java_files.bp b/annotated_java_files.bp
deleted file mode 100644
index 77a2c6e..0000000
--- a/annotated_java_files.bp
+++ /dev/null
@@ -1,49 +0,0 @@
-// Do not edit; generated using libcore/annotations/generate_annotated_java_files.py
-filegroup {
-    name: "annotated_ojluni_files",
-    export_to_make_var: "annotated_ojluni_files",
-    srcs: [
-        "ojluni/src/main/java/java/io/PrintWriter.java",
-        "ojluni/src/main/java/java/lang/Appendable.java",
-        "ojluni/src/main/java/java/lang/Boolean.java",
-        "ojluni/src/main/java/java/lang/Byte.java",
-        "ojluni/src/main/java/java/lang/CharSequence.java",
-        "ojluni/src/main/java/java/lang/Character.java",
-        "ojluni/src/main/java/java/lang/Class.java",
-        "ojluni/src/main/java/java/lang/Double.java",
-        "ojluni/src/main/java/java/lang/Enum.java",
-        "ojluni/src/main/java/java/lang/Float.java",
-        "ojluni/src/main/java/java/lang/Integer.java",
-        "ojluni/src/main/java/java/lang/Iterable.java",
-        "ojluni/src/main/java/java/lang/Long.java",
-        "ojluni/src/main/java/java/lang/Object.java",
-        "ojluni/src/main/java/java/lang/String.java",
-        "ojluni/src/main/java/java/lang/StringBuffer.java",
-        "ojluni/src/main/java/java/lang/StringBuilder.java",
-        "ojluni/src/main/java/java/lang/System.java",
-        "ojluni/src/main/java/java/lang/Thread.java",
-        "ojluni/src/main/java/java/lang/ThreadLocal.java",
-        "ojluni/src/main/java/java/lang/reflect/AccessibleObject.java",
-        "ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java",
-        "ojluni/src/main/java/java/lang/reflect/Array.java",
-        "ojluni/src/main/java/java/lang/reflect/Constructor.java",
-        "ojluni/src/main/java/java/lang/reflect/Executable.java",
-        "ojluni/src/main/java/java/lang/reflect/Field.java",
-        "ojluni/src/main/java/java/lang/reflect/GenericArrayType.java",
-        "ojluni/src/main/java/java/lang/reflect/GenericDeclaration.java",
-        "ojluni/src/main/java/java/lang/reflect/Member.java",
-        "ojluni/src/main/java/java/lang/reflect/Method.java",
-        "ojluni/src/main/java/java/lang/reflect/Parameter.java",
-        "ojluni/src/main/java/java/lang/reflect/ParameterizedType.java",
-        "ojluni/src/main/java/java/lang/reflect/Proxy.java",
-        "ojluni/src/main/java/java/lang/reflect/Type.java",
-        "ojluni/src/main/java/java/lang/reflect/TypeVariable.java",
-        "ojluni/src/main/java/java/lang/reflect/WildcardType.java",
-        "ojluni/src/main/java/java/util/ArrayList.java",
-        "ojluni/src/main/java/java/util/HashMap.java",
-        "ojluni/src/main/java/java/util/Iterator.java",
-        "ojluni/src/main/java/java/util/List.java",
-        "ojluni/src/main/java/java/util/Map.java",
-        "ojluni/src/main/java/java/util/Set.java",
-    ],
-}
diff --git a/annotations/generate_annotated_java_files.py b/annotations/generate_annotated_java_files.py
deleted file mode 100755
index 2f12eea..0000000
--- a/annotations/generate_annotated_java_files.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-"""Generate annotated_java_files.bp from a jaif file."""
-import os
-
-PACKAGE_STRING = 'package '
-CLASS_STRING = 'class '
-SRC_PREFIX = 'ojluni/src/main/java/'
-
-BP_TEMPLATE = '''filegroup {
-    name: "annotated_ojluni_files",
-    export_to_make_var: "annotated_ojluni_files",
-    srcs: [
-%s
-    ],
-}'''
-
-srcs_list = set()
-current_package = None
-with open(os.sys.argv[1], 'r') as jaif_file:
-  for line in jaif_file:
-    if line.startswith(PACKAGE_STRING):
-      current_package = line[len(PACKAGE_STRING): line.find(':')]
-    if line.startswith(CLASS_STRING) and current_package is not None:
-      current_class = line[len(CLASS_STRING): line.find(':')]
-
-      # In case of nested classes, discard substring after nested class name separator
-      nested_class_separator_index = current_class.find('$')
-      if nested_class_separator_index != -1:
-        current_class = current_class[:nested_class_separator_index]
-
-      srcs_list.add(SRC_PREFIX + current_package.replace('.', '/') + '/' + current_class + '.java')
-
-print '// Do not edit; generated using libcore/annotations/generate_annotated_java_files.py'
-print BP_TEMPLATE % ('\n'.join(['        "' + src_entry + '",' for src_entry in sorted(srcs_list)]),)
-os.sys.exit(0)
diff --git a/annotations/ojluni.jaif b/annotations/ojluni.jaif
deleted file mode 100644
index a0bdabe..0000000
--- a/annotations/ojluni.jaif
+++ /dev/null
@@ -1,2862 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This file specifies additional annotations that are applied to libcore
-// code before generating android stubs and documentation. This data
-// is human-maintained and is based on jdk annotations shipped in Android
-// Studio.
-
-// If this file is changed, please update libcore/annotated_java_files.bp file by running:
-// libcore/annotations/generate_annotated_java_files.py libcore/annotations/ojluni.jaif > libcore/annotated_java_files.bp
-//
-// For arrray syntax, please see https://checkerframework.org/jsr308/specification/java-annotation-design.html#array-syntax
-// @Nullable String @NonNull[] <- Non-null array of nullable strings can be expressed as:
-//
-//    type: @libcore.util.NonNull
-//      inner-type 0, 0: @libcore.util.Nullable
-
-package libcore.util:
-annotation @NonNull: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
-    int from
-    int to
-annotation @Nullable: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
-    int from
-    int to
-annotation @NullFromTypeParam: @java.lang.annotation.Retention(value=SOURCE) @java.lang.annotation.Target(value={TYPE_USE})
-    int from
-    int to
-
-package java.io:
-class PrintWriter:
-
-    method <init>(Ljava/io/Writer;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/io/Writer;Z)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/io/OutputStream;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/io/OutputStream;Z)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/nio/charset/Charset;Ljava/io/File;)V:
-        return:
-
-    method <init>(Ljava/lang/String;Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/io/File;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method <init>(Ljava/io/File;Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-
-    method write([CII)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method write([C)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method write(Ljava/lang/String;II)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method write(Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method print([C)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method print(Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method print(Ljava/lang/Object;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method println(Ljava/lang/String;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method println(Ljava/lang/Object;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-
-    method printf(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-
-    method format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-
-    method format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-
-    method append(Ljava/lang/CharSequence;)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method append(Ljava/lang/CharSequence;II)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method append(C)Ljava/io/PrintWriter;:
-        return: @libcore.util.NonNull
-
-    method append(C)Ljava/io/Writer;:
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;II)Ljava/io/Writer;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method append(Ljava/lang/CharSequence;)Ljava/io/Writer;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method append(C)Ljava/lang/Appendable;:
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;II)Ljava/lang/Appendable;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method append(Ljava/lang/CharSequence;)Ljava/lang/Appendable;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-
-package java.lang:
-class Appendable:
-    method append(Ljava/lang/CharSequence;)Ljava/lang/Appendable;:
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Is expected to return self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;II)Ljava/lang/Appendable;:
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Is expected to return self
-        return: @libcore.util.NonNull
-
-    method append(C)Ljava/lang/Appendable;:
-        // Is expected to return self
-        return: @libcore.util.NonNull
-
-class Boolean:
-    method <init>(Ljava/lang/String;)V:
-        // In contrast to other type classes, doesn't NPE on null, but sets value to false
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method parseBoolean(Ljava/lang/String;)Z:
-        // In contrast to other type classes, doesn't NPE on null, but sets value to false
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method valueOf(Z)Ljava/lang/Boolean;:
-        // Always return value
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Boolean;:
-        // Null == false
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Always return value
-        return: @libcore.util.NonNull
-
-    method toString(Z)Ljava/lang/String;:
-        // Always return value
-        return: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always return value
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getBoolean(Ljava/lang/String;)Z:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method compareTo(Ljava/lang/Boolean;)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-class Byte:
-    method toString(B)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(B)Ljava/lang/Byte;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method parseByte(Ljava/lang/String;I)B:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseByte(Ljava/lang/String;)B:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;I)Ljava/lang/Byte;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Byte;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method decode(Ljava/lang/String;)Ljava/lang/Byte;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method compareTo(Ljava/lang/Byte;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toHexString(BZ)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-class Character:
-    method valueOf(C)Ljava/lang/Character;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toString(C)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method codePointAt(Ljava/lang/CharSequence;I)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointAt([CI)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointAt([CII)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointBefore(Ljava/lang/CharSequence;I)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointBefore([CI)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointBefore([CII)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toChars(I[CI)I:
-        // throws NPE
-        parameter #1:
-          type: @libcore.util.NonNull
-
-    method toChars(I)[C:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method codePointCount(Ljava/lang/CharSequence;II)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method codePointCount([CII)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method offsetByCodePoints(Ljava/lang/CharSequence;II)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method offsetByCodePoints([CIIII)I:
-        // throws NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method compareTo(Ljava/lang/Character;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method getName(I)Ljava/lang/String;:
-        // Null is a valid return value
-        return: @libcore.util.Nullable
-
-class Character$Subset:
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method hashCode()I:
-        return:
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-class Character$UnicodeBlock:
-    method of(C)Ljava/lang/Character$UnicodeBlock;:
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method of(I)Ljava/lang/Character$UnicodeBlock;:
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method forName(Ljava/lang/String;)Ljava/lang/Character$UnicodeBlock;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-class Character$UnicodeScript:
-    method of(I)Ljava/lang/Character$UnicodeScript;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method forName(Ljava/lang/String;)Ljava/lang/Character$UnicodeScript;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-class CharSequence:
-    // Always returns a string instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class Enum:
-    // Always returns an instance or throws
-    method valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;:
-        return: @libcore.util.NonNull
-
-class Iterable:
-    // Always returns an instance
-    method iterator()Ljava/util/Iterator;:
-        return: @libcore.util.NonNull
-
-class Integer:
-    method toString(II)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toUnsignedString(II)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toHexString(I)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toOctalString(I)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toBinaryString(I)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toString(I)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toUnsignedString(I)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-   method parseInt(Ljava/lang/String;I)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseInt(Ljava/lang/String;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseUnsignedInt(Ljava/lang/String;I)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseUnsignedInt(Ljava/lang/String;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;I)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(I)Ljava/lang/Integer;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getInteger(Ljava/lang/String;)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method getInteger(Ljava/lang/String;I)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method getInteger(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Can be null
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method decode(Ljava/lang/String;)Ljava/lang/Integer;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method compareTo(Ljava/lang/Integer;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-class Float:
-    method toString(F)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toHexString(F)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Float;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(F)Ljava/lang/Float;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method parseFloat(Ljava/lang/String;)F:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method compareTo(Ljava/lang/Float;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-class Double:
-    method toString(D)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toHexString(D)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Double;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(D)Ljava/lang/Double;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method parseDouble(Ljava/lang/String;)D:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method compareTo(Ljava/lang/Double;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-class Long:
-    method toString(JI)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toUnsignedString(JI)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toHexString(J)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toOctalString(J)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toBinaryString(J)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toString(J)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method toUnsignedString(J)Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method parseLong(Ljava/lang/String;I)J:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseLong(Ljava/lang/String;)J:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseUnsignedLong(Ljava/lang/String;I)J:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method parseUnsignedLong(Ljava/lang/String;)J:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;I)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(Ljava/lang/String;)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method valueOf(J)Ljava/lang/Long;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method decode(Ljava/lang/String;)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/String;)V:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Always returns an instance
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        // Can be null
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getLong(Ljava/lang/String;)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method getLong(Ljava/lang/String;J)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method getLong(Ljava/lang/String;Ljava/lang/Long;)Ljava/lang/Long;:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Can be null
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns null in case of failure
-        return: @libcore.util.Nullable
-
-    method compareTo(Ljava/lang/Long;)I:
-        // Throws NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-class String:
-    method <init>(Ljava/lang/String;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([C)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([CII)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([III)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BIII)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BI)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BIILjava/lang/String;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #3:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BIILjava/nio/charset/Charset;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #3:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BLjava/lang/String;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BLjava/nio/charset/Charset;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([BII)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>([B)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>(Ljava/lang/StringBuffer;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>(Ljava/lang/StringBuilder;)V:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return:
-    method <init>(II[C)V:
-        parameter #2:
-          type: @libcore.util.NonNull
-        return:
-    method getChars(II[CI)V:
-        parameter #2:
-          type: @libcore.util.NonNull
-        return:
-
-    // Always returns a string instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method getBytes(II[BI)V:
-        parameter #2:
-          type: @libcore.util.NonNull
-    // Empty array in worst case
-    method getBytes(Ljava/lang/String;)[B:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Empty array in worst case
-    method getBytes(Ljava/nio/charset/Charset;)[B:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Empty array in worst case (or throws)
-    method getBytes(Ljava/lang/String;)[B:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Empty array in worst case
-    method getBytes()[B:
-        return: @libcore.util.NonNull
-    method equals(Ljava/lang/Object;)Z:
-        parameter #0:
-          type: @libcore.util.Nullable
-    // Empty array in worst case
-    method toCharArray()[C:
-        return: @libcore.util.NonNull
-    // Empty char sequence in worst case
-    method subSequence(II)Ljava/lang/CharSequence;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method concat(Ljava/lang/String;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method copyValueOf([CII)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method copyValueOf([C)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method intern()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method replace(CC)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method substring(I)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method substring(II)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method toLowerCase(Ljava/util/Locale;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method toLowerCase()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method toUpperCase(Ljava/util/Locale;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method toUpperCase()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method trim()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(Z)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(C)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(I)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(J)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(F)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(D)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf(Ljava/lang/Object;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.Nullable
-        return:@libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf([C)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method valueOf([CII)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method split(Ljava/lang/String;I)[Ljava/lang/String;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-    // Always returns a string instance
-    method split(Ljava/lang/String;)[Ljava/lang/String;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-    // Always returns a string instance
-    method join(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-    // Always returns a string instance
-    method join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-            inner-type 3, 0, 2, 0: @libcore.util.Nullable
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    // Always returns a string instance
-    method replaceFirst(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-   method replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        return: @libcore.util.NonNull
-    method contentEquals(Ljava/lang/StringBuffer;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method contentEquals(Ljava/lang/CharSequence;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method equalsIgnoreCase(Ljava/lang/String;)Z:
-        parameter #0:
-          type: @libcore.util.Nullable
-    method compareTo(Ljava/lang/String;)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method compareToIgnoreCase(Ljava/lang/String;)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method regionMatches(ILjava/lang/String;II)Z:
-        parameter #1:
-          type: @libcore.util.NonNull
-    method regionMatches(ZILjava/lang/String;II)Z:
-        parameter #2:
-          type: @libcore.util.NonNull
-    method startsWith(Ljava/lang/String;I)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method startsWith(Ljava/lang/String;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method endsWith(Ljava/lang/String;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method indexOf(Ljava/lang/String;)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method indexOf(Ljava/lang/String;I)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method lastIndexOf(Ljava/lang/String;)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method lastIndexOf(Ljava/lang/String;I)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method matches(Ljava/lang/String;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method contains(Ljava/lang/CharSequence;)Z:
-        parameter #0:
-          type: @libcore.util.NonNull
-    method format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-        return: @libcore.util.NonNull
-    method format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;:
-        parameter #0:
-          type: @libcore.util.NonNull
-        parameter #1:
-          type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-        return: @libcore.util.NonNull
-
-class System:
-    // Ideally, in should be made NonNull - but it IS possible to make this final field
-    // a null using setIn(null). It makes sense to leave this field as a platform
-    // type for convenience reasons - no one sane should expect this to be null,
-    // but it's nice to have kotlin check it.
-    field in:
-
-    // Same as in "in" field
-    field out:
-
-    // Same as in "in" field
-    field err:
-
-
-    method setIn(Ljava/io/InputStream;)V:
-        // While it makes little sense, it's possible to set System.in to null.
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method setOut(Ljava/io/PrintStream;)V:
-        // While it makes little sense, it's possible to set System.out to null.
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method setErr(Ljava/io/PrintStream;)V:
-        // While it makes little sense, it's possible to set System.err to null.
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method console()Ljava/io/Console;:
-        // Always returns an instance
-        return: @libcore.util.Nullable
-
-    method inheritedChannel()Ljava/nio/channels/Channel;:
-        // Null if there's no inherited channel
-        return: @libcore.util.Nullable
-
-    method setSecurityManager(Ljava/lang/SecurityManager;)V:
-        // Null is a valid argument.
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getSecurityManager()Ljava/lang/SecurityManager;:
-        // Null is valid return value.
-        return: @libcore.util.Nullable
-
-    method arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V:
-        // NPE on null src
-        parameter #0:
-          type: @libcore.util.NonNull
-        // NPE on null dst
-        parameter #1:
-          type: @libcore.util.NonNull
-
-    method identityHashCode(Ljava/lang/Object;)I:
-        // Null is a valid argument.
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getProperties()Ljava/util/Properties;:
-        // There's always a properties object
-        return: @libcore.util.NonNull
-
-    method lineSeparator()Ljava/lang/String;:
-        // There's always a line separator string (empty in worst case)
-        return: @libcore.util.NonNull
-
-    method setProperties(Ljava/util/Properties;)V:
-        // Null is a valid argument (will reset to defaults)
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method getProperty(Ljava/lang/String;)Ljava/lang/String;:
-        // Property key can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method getProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
-        // Property key can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Property value can be null
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method setProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;:
-        // Property key can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Property value can be null
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method clearProperty(Ljava/lang/String;)Ljava/lang/String;:
-        // Property key can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method getenv(Ljava/lang/String;)Ljava/lang/String;:
-        // Name can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Null is valid return value
-        return: @libcore.util.Nullable
-
-    method getenv()Ljava/util/Map;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method load(Ljava/lang/String;)V:
-        // Filename can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method loadLibrary(Ljava/lang/String;)V:
-        // Libname can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method mapLibraryName(Ljava/lang/String;)Ljava/lang/String;:
-        // Libname can't be null
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Never null
-        return: @libcore.util.NonNull
-
-class StringBuffer:
-    method <init>(Ljava/lang/String;)V:
-        // NPE on null argument
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/CharSequence;)V:
-        // NPE on null argument
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method getChars(II[CI)V:
-        // NPE on null argument
-        parameter #2:
-          type: @libcore.util.NonNull
-
-    method append(Ljava/lang/Object;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/String;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/AbstractStringBuilder;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;II)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append([C)Ljava/lang/StringBuffer;:
-        // Null for char[] methods result in NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append([CII)Ljava/lang/StringBuffer;:
-        // Null for char[] methods result in NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Z)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(C)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(I)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method appendCodePoint(I)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(J)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(F)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(D)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method delete(II)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method deleteCharAt(I)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method replace(IILjava/lang/String;)Ljava/lang/StringBuffer;:
-        // NPE from null
-        parameter #2:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method substring(I)Ljava/lang/String;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method subSequence(II)Ljava/lang/CharSequence;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method substring(II)Ljava/lang/String;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method insert(I[CII)Ljava/lang/StringBuffer;:
-        // Null for char[] methods result in NPE
-        parameter #1:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/Object;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/String;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(I[C)Ljava/lang/StringBuffer;:
-        // Null for char[] methods result in NPE
-        parameter #1:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/CharSequence;II)Ljava/lang/StringBuffer;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IZ)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IC)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(II)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IJ)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IF)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ID)Ljava/lang/StringBuffer;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method indexOf(Ljava/lang/String;)I:
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method indexOf(Ljava/lang/String;I)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method lastIndexOf(Ljava/lang/String;)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method lastIndexOf(Ljava/lang/String;I)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method reverse()Ljava/lang/StringBuffer;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Never null
-        return: @libcore.util.NonNull
-
-class StringBuilder:
-
-    method <init>(Ljava/lang/String;)V:
-        // NPE on null argument
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method <init>(Ljava/lang/CharSequence;)V:
-        // NPE on null argument
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method append(Ljava/lang/Object;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/String;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Ljava/lang/CharSequence;II)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #0:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append([C)Ljava/lang/StringBuilder;:
-        // Null for char[] methods result in NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append([CII)Ljava/lang/StringBuilder;:
-        // Null for char[] methods result in NPE
-        parameter #0:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(Z)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(C)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(I)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(J)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(F)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method append(D)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method appendCodePoint(I)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method delete(II)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method deleteCharAt(I)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method replace(IILjava/lang/String;)Ljava/lang/StringBuilder;:
-        // NPE from null
-        parameter #2:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(I[CII)Ljava/lang/StringBuilder;:
-        // Null for char[] methods result in NPE
-        parameter #1:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/Object;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/String;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(I[C)Ljava/lang/StringBuilder;:
-        // Null for char[] methods result in NPE
-        parameter #1:
-          type: @libcore.util.NonNull
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/CharSequence;)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ILjava/lang/CharSequence;II)Ljava/lang/StringBuilder;:
-        // null -> "null"
-        parameter #1:
-          type: @libcore.util.Nullable
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IZ)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IC)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(II)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IJ)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(IF)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method insert(ID)Ljava/lang/StringBuilder;:
-        // Returns self
-        return: @libcore.util.NonNull
-
-    method indexOf(Ljava/lang/String;)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method indexOf(Ljava/lang/String;I)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method lastIndexOf(Ljava/lang/String;)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method lastIndexOf(Ljava/lang/String;I)I:
-        // NPE on null
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method reverse()Ljava/lang/StringBuilder;:
-        // Never null
-        return: @libcore.util.NonNull
-
-    method toString()Ljava/lang/String;:
-        // Never null
-        return: @libcore.util.NonNull
-
-class Thread:
-    // Always returns a string instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always return an instance
-    method currentThread()Ljava/lang/Thread;:
-        return: @libcore.util.NonNull
-
-// It would be nice to use @NullFromTypeParam in ThreadLocal
-// everywhere its <T> is used, buy sadly the code below makes it impossible:
-//
-// ThreadLocal<@NonNull Object> foo = new ThreadLocal<>();
-// assertNull(foo.get())
-//
-// Hence @Nullable T is used heavily
-class ThreadLocal:
-    method withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal;:
-        // NPE on null supplier
-        parameter #0:
-          type: @libcore.util.NonNull
-	// Always returns instance
-        return: @libcore.util.NonNull
-
-    method initialValue()Ljava/lang/Object;:
-        // Returns null by default
-        return: @libcore.util.Nullable
-
-    method get()Ljava/lang/Object;:
-        // May return null
-        return: @libcore.util.Nullable
-
-    method set(Ljava/lang/Object;)V:
-        // Depends on type param
-        parameter #0:
-          type: @libcore.util.NullFromTypeParam
-
-class Object:
-
-    method getClass()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class Class:
-
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method toGenericString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method forName(Ljava/lang/String;)Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.Nullable
-
-    method newInstance()Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-
-    method isInstance(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method isAssignableFrom(Ljava/lang/Class;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method getClassLoader()Ljava/lang/ClassLoader;:
-        return: @libcore.util.Nullable
-
-    method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0,3, 0: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getSuperclass()Ljava/lang/Class;:
-        return: @libcore.util.Nullable
-
-    method getGenericSuperclass()Ljava/lang/reflect/Type;:
-        return: @libcore.util.Nullable
-
-    method getPackage()Ljava/lang/Package;:
-        return: @libcore.util.Nullable
-
-    method getInterfaces()[Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getGenericInterfaces()[Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getComponentType()Ljava/lang/Class;:
-        return: @libcore.util.Nullable
-
-    method getSigners()[Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getEnclosingMethod()Ljava/lang/reflect/Method;:
-        return: @libcore.util.Nullable
-
-    method getEnclosingConstructor()Ljava/lang/reflect/Constructor;:
-        return: @libcore.util.Nullable
-
-    method getDeclaringClass()Ljava/lang/Class;:
-        return: @libcore.util.Nullable
-
-    method getEnclosingClass()Ljava/lang/Class;:
-        return: @libcore.util.Nullable
-
-    method getSimpleName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method getTypeName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-    method getCanonicalName()Ljava/lang/String;:
-        return: @libcore.util.Nullable
-
-    method getClasses()[Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getFields()[Ljava/lang/reflect/Field;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getMethods()[Ljava/lang/reflect/Method;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getConstructors()[Ljava/lang/reflect/Constructor;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getField(Ljava/lang/String;)Ljava/lang/reflect/Field;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.Nullable
-                inner-type 0, 0: @libcore.util.NonNull
-
-    method getConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-                inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredClasses()[Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredFields()[Ljava/lang/reflect/Field;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredMethods()[Ljava/lang/reflect/Method;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredConstructors()[Ljava/lang/reflect/Constructor;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredField(Ljava/lang/String;)Ljava/lang/reflect/Field;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-        parameter #1:
-            type: @libcore.util.Nullable
-                inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;:
-        return: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.Nullable
-                inner-type 0, 0: @libcore.util.NonNull
-
-    method getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getResource(Ljava/lang/String;)Ljava/net/URL;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getProtectionDomain()Ljava/security/ProtectionDomain;:
-        return: @libcore.util.Nullable
-
-    method getEnumConstants()[Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method cast(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method asSubclass(Ljava/lang/Class;)Ljava/lang/Class;:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method isAnnotationPresent(Ljava/lang/Class;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getAnnotationsByType(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getAnnotations()[Ljava/lang/annotation/Annotation;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method getDeclaredAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.NonNull
-
-    method isDeclaredAnnotationPresent(Ljava/lang/Class;)Z:
-        return:
-
-package java.lang.reflect:
-
-class AccessibleObject:
-    // Empty array in the worst case
-    method getAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-
-class AnnotatedElement:
-    // Empty array in the worst case
-    method getAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-
-class Array:
-    // Returns instance or throws
-    method newInstance(Ljava/lang/Class;I)Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-    // Returns instance or throws
-    method newInstance(Ljava/lang/Class;[I)Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-
-class Constructor:
-    // Always returns an instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method toGenericString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // There's always a declaring class
-    method getDeclaringClass()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameterTypes()[Ljava/lang/Class;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Returns instance or throws
-    method newInstance([Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-
-class Executable:
-    // There's always a declaring class
-    method getDeclaringClass()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameterTypes()[Ljava/lang/Class;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getGenericParameterTypes()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameters()[Ljava/lang/reflect/Parameter;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getExceptionTypes()[Ljava/lang/Class;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getGenericExceptionTypes()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Always returns an instance
-    method toGenericString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameterAnnotations()[[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-          inner-type 0, 0, 0, 0:  @libcore.util.NonNull
-
-class Field:
-    // Always returns an instance
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // There's always a type of a field
-    method getType()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method toGenericString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class GenericArrayType:
-    // There's always a type for array
-    method getGenericComponentType()Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-
-class GenericDeclaration:
-    // Empty array in the worst case
-    method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-
-class Member:
-    method getDeclaringClass()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class Method:
-    // There's always a declaring class
-    method getDeclaringClass()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getTypeParameters()[Ljava/lang/reflect/TypeVariable;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // There's always a return type (such as Void.class)
-    method getReturnType()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // There's always a return type (such as Void.class)
-    method getGenericReturnType()Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameterTypes()[Ljava/lang/Class;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getGenericParameterTypes()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getExceptionTypes()[Ljava/lang/Class;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getGenericExceptionTypes()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Always returns an instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method toGenericString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getParameterAnnotations()[[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-          inner-type 0, 0, 0, 0:  @libcore.util.NonNull
-
-
-class ParameterizedType:
-    // Empty array in the worst case
-    method getActualTypeArguments()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Always returns an instance
-    method getRawType()Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-
-class Parameter:
-    // Always returns an instance
-    method toString()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // There's always a declaring executable
-    method getDeclaringExecutable()Ljava/lang/reflect/Executable;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method getRealName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-    // There's always a type
-    method getParameterizedType()Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-    // There's always a type
-    method getType()Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Empty array in the worst case
-    method getDeclaredAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getAnnotations()[Ljava/lang/annotation/Annotation;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-
-class Proxy:
-    // Always returns an instance (or throws)
-    method getProxyClass(Ljava/lang/ClassLoader;[Ljava/lang/Class;)Ljava/lang/Class;:
-        return: @libcore.util.NonNull
-    // Always returns an instance (or throws)
-    method newProxyInstance(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-    // Always returns an instance (or throws)
-    method getInvocationHandler(Ljava/lang/Object;)Ljava/lang/reflect/InvocationHandler;:
-        return: @libcore.util.NonNull
-
-class Type:
-    // Always returns an instance
-    method getTypeName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class TypeVariable:
-    // Empty array in the worst case
-    method getBounds()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Always returns an instance
-    method getGenericDeclaration()Ljava/lang/reflect/GenericDeclaration;:
-        return: @libcore.util.NonNull
-    // Always returns an instance
-    method getName()Ljava/lang/String;:
-        return: @libcore.util.NonNull
-
-class WildcardType:
-    // Empty array in the worst case
-    method getUpperBounds()[Ljava/lang/reflect/Type;:
-        return: @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-    // Empty array in the worst case
-    method getLowerBounds()[Ljava/lang/reflect/Type;:
-        return:  @libcore.util.NonNull
-          inner-type 0, 0:  @libcore.util.NonNull
-
-package java.util:
-
-class ArrayList:
-
-    method <init>(Ljava/util/Collection;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method contains(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method indexOf(Ljava/lang/Object;)I:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method lastIndexOf(Ljava/lang/Object;)I:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method clone()Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-
-    method toArray()[Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-
-    method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-
-    method get(I)Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-
-    method set(ILjava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method add(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-
-    method add(ILjava/lang/Object;)V:
-        return:
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method remove(I)Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method addAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method addAll(ILjava/util/Collection;)Z:
-        return:
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method removeAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method retainAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method listIterator(I)Ljava/util/ListIterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method listIterator()Ljava/util/ListIterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method iterator()Ljava/util/Iterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method subList(II)Ljava/util/List;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method forEach(Ljava/util/function/Consumer;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method spliterator()Ljava/util/Spliterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method removeIf(Ljava/util/function/Predicate;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method replaceAll(Ljava/util/function/UnaryOperator;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method sort(Ljava/util/Comparator;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class HashMap:
-
-    method <init>(Ljava/util/Map;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
-    method get(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method containsKey(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method putAll(Ljava/util/Map;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method containsValue(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method keySet()Ljava/util/Set;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method values()Ljava/util/Collection;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method entrySet()Ljava/util/Set;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
-            inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
-
-    method getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.Nullable
-
-    method putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.Nullable
-
-    method replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.Nullable
-        parameter #2:
-            type: @libcore.util.NullFromTypeParam
-
-    method replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.Nullable
-
-    method computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NonNull
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-    method compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.Nullable
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-    method merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NonNull
-                inner-type 3, 1,2, 0: @libcore.util.NonNull
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-    method forEach(Ljava/util/function/BiConsumer;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
-    method replaceAll(Ljava/util/function/BiFunction;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 2,2, 0: @libcore.util.NullFromTypeParam
-
-    method clone()Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-
-class Iterator:
-
-    method next()Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-
-    method forEachRemaining(Ljava/util/function/Consumer;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class List:
-    method contains(Ljava/lang/Object;)Z:
-        // May be null
-        parameter #0:
-          type: @libcore.util.Nullable
-        return:
-
-    method iterator()Ljava/util/Iterator;:
-        // Javadoc doesn't mention possiblity of a null result
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method toArray()[Ljava/lang/Object;:
-        // Never returns null
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-
-    method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
-        // Javadoc mention NPE for param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-        // Never returns null
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-
-    method add(Ljava/lang/Object;)Z:
-        // Nullness depends on type parameter nullness
-        parameter #0:
-          type: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;)Z:
-        // param #0 has to allow nulls
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method containsAll(Ljava/util/Collection;)Z:
-        // Javadoc mention NPE for null param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method addAll(Ljava/util/Collection;)Z:
-        // Javadoc mention NPE for null param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-          // boolean addAll(Collection<? extends E> c);
-          // Nullness depends on type parameter nullness
-          inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
-    method addAll(ILjava/util/Collection;)Z:
-        // Javadoc mention NPE for null param #1
-        parameter #1:
-          type: @libcore.util.NonNull
-          // boolean addAll(int, Collection<? extends E> c);
-          inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
-    method removeAll(Ljava/util/Collection;)Z:
-        // Javadoc mention NPE for null param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method retainAll(Ljava/util/Collection;)Z:
-        // Javadoc mention NPE for null param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-
-    method replaceAll(Ljava/util/function/UnaryOperator;)V:
-        // Javadoc mention NPE for null param #0
-        parameter #0:
-          type: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method sort(Ljava/util/Comparator;)V:
-        // Javadoc mention null as valid param #0
-        parameter #0:
-          type: @libcore.util.Nullable
-          inner-type 3, 0, 2, 0: @libcore.util.NullFromTypeParam
-
-    method equals(Ljava/lang/Object;)Z:
-        // Null is valid argument #0
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method get(I)Ljava/lang/Object;:
-        // Nullness depends on type parameter nullness
-        // E get(int index);
-        return: @libcore.util.NullFromTypeParam
-
-    method set(ILjava/lang/Object;)Ljava/lang/Object;:
-        // Nullness depends on type parameter nullness
-        // E set(int index, E element);
-        parameter #1:
-          type: @libcore.util.NullFromTypeParam
-        return: @libcore.util.NullFromTypeParam
-
-    method add(ILjava/lang/Object;)V:
-        // Nullness depends on type parameter nullness
-        // void add(int index, E element);
-        parameter #1:
-          type: @libcore.util.NullFromTypeParam
-
-    method remove(I)Ljava/lang/Object;:
-        // Nullness depends on type parameter nullness
-        // E remove(int index);
-        return: @libcore.util.NullFromTypeParam
-
-    method indexOf(Ljava/lang/Object;)I:
-        // Null is valid argument
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method lastIndexOf(Ljava/lang/Object;)I:
-        // Null is valid argument
-        parameter #0:
-          type: @libcore.util.Nullable
-
-    method listIterator()Ljava/util/ListIterator;:
-        // Javadoc doesn't mention possiblity of a null result
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method listIterator(I)Ljava/util/ListIterator;:
-        // Javadoc doesn't mention possiblity of a null result
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method subList(II)Ljava/util/List;:
-         // Javadoc doesn't mention possiblity of a null result
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method spliterator()Ljava/util/Spliterator;:
-        // Javadoc doesn't mention possiblity of a null result
-        return: @libcore.util.NonNull
-
-class Map:
-
-    method containsKey(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method containsValue(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method get(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method putAll(Ljava/util/Map;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
-    method keySet()Ljava/util/Set;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method values()Ljava/util/Collection;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method entrySet()Ljava/util/Set;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
-            inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
-
-    method equals(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.Nullable
-
-    method forEach(Ljava/util/function/BiConsumer;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-
-    method replaceAll(Ljava/util/function/BiFunction;)V:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 2,2, 0: @libcore.util.NullFromTypeParam
-
-    method putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-        parameter #1:
-            type: @libcore.util.Nullable
-
-    method replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.Nullable
-        parameter #2:
-            type: @libcore.util.NullFromTypeParam
-
-    method replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NullFromTypeParam
-
-    method computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.Nullable
-
-    method computeIfPresent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.NonNull
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-    method compute(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-                inner-type 3, 1,2, 0: @libcore.util.Nullable
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-    method merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;:
-        return: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-        parameter #1:
-            type: @libcore.util.NonNull
-        parameter #2:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NonNull
-                inner-type 3, 1,2, 0: @libcore.util.NonNull
-                inner-type 3, 2,2, 0: @libcore.util.Nullable
-
-class Map$Entry:
-
-    method getKey()Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-
-    method getValue()Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-
-    method setValue(Ljava/lang/Object;)Ljava/lang/Object;:
-        return: @libcore.util.NullFromTypeParam
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-
-    method equals(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method comparingByKey()Ljava/util/Comparator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 1: @libcore.util.Nullable
-
-    method comparingByValue()Ljava/util/Comparator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.Nullable
-            inner-type 3, 0,3, 1: @libcore.util.NonNull
-
-    method comparingByKey(Ljava/util/Comparator;)Ljava/util/Comparator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.NullFromTypeParam
-            inner-type 3, 0,3, 1: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method comparingByValue(Ljava/util/Comparator;)Ljava/util/Comparator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NonNull
-            inner-type 3, 0,3, 0: @libcore.util.Nullable
-            inner-type 3, 0,3, 1: @libcore.util.NullFromTypeParam
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-class Set:
-
-    method contains(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method iterator()Ljava/util/Iterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
-
-    method toArray()[Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-
-    method toArray([Ljava/lang/Object;)[Ljava/lang/Object;:
-        return: @libcore.util.NonNull
-            inner-type 0, 0: @libcore.util.Nullable
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 0, 0: @libcore.util.Nullable
-
-    method add(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NullFromTypeParam
-
-    method remove(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method containsAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method addAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-                inner-type 3, 0,2, 0: @libcore.util.NullFromTypeParam
-
-    method retainAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method removeAll(Ljava/util/Collection;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.NonNull
-
-    method equals(Ljava/lang/Object;)Z:
-        return:
-        parameter #0:
-            type: @libcore.util.Nullable
-
-    method spliterator()Ljava/util/Spliterator;:
-        return: @libcore.util.NonNull
-            inner-type 3, 0: @libcore.util.NullFromTypeParam
diff --git a/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
index 1429062..c671da6 100644
--- a/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
+++ b/benchmarks/src/benchmarks/DeepArrayOpsBenchmark.java
@@ -16,24 +16,23 @@
 
 package benchmarks;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.util.Arrays;
 
 public class DeepArrayOpsBenchmark {
-    @Param({"1", "4", "16", "256", "2048"}) int arrayLength;
+    @Param({"0001", "0004", "0016", "0256", "2048"}) int arrayLength;
 
     private Object[] array;
     private Object[] array2;
 
-    private Object[] array3;
-    private Object[] array4;
-
-    protected void setUp() throws Exception {
-        array = new Object[arrayLength * 13];
-        array2 = new Object[arrayLength * 13];
-        for (int i = 0; i < arrayLength; i += 13) {
+    @BeforeExperiment public void setUp() throws Exception {
+        array = new Object[arrayLength * 14];
+        array2 = new Object[arrayLength * 14];
+        for (int i = 0; i < arrayLength; i += 14) {
             array[i] = new IntWrapper(i);
             array2[i] = new IntWrapper(i);
 
@@ -74,16 +73,19 @@
             // Subarray types is an interface.
             array[i + 12] = new16ElementArray(CharSequence.class, String.class);
             array2[i + 12] = new16ElementArray(CharSequence.class, String.class);
+
+            array[i + 13] = null;
+            array2[i + 13] = null;
         }
     }
 
-    public void timeDeepHashCode(int reps) {
+    @Benchmark public void deepHashCode(int reps) {
         for (int i = 0; i < reps; ++i) {
             Arrays.deepHashCode(array);
         }
     }
 
-    public void timeEquals(int reps) {
+    @Benchmark public void deepEquals(int reps) {
         for (int i = 0; i < reps; ++i) {
             Arrays.deepEquals(array, array2);
         }
@@ -143,4 +145,3 @@
         }
     }
 }
-
diff --git a/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java b/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java
new file mode 100644
index 0000000..3a93285
--- /dev/null
+++ b/benchmarks/src/benchmarks/GetSystemPropertyBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks;
+
+import java.security.AccessController;
+
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Compares performance of accessing system properties via
+ * legacy security code
+ * {@code AccessController.doPrivileged(new GetPropertyAction(key[, default]))}
+ * vs. direct invocation of {@code System.getProperty(key[, default])}.
+ *
+ * As of 2018-07, libcore carries some patches to perform such short-circuiting,
+ * so it's interesting to know how much better it performs.
+ */
+public class GetSystemPropertyBenchmark {
+
+    public void timeSystem_getProperty_default(int reps) {
+        for (int i = 0; i < reps; i++) {
+            System.getProperty("user.language", "en");
+        }
+    }
+
+    public void timeSystem_getProperty(int reps) {
+        for (int i = 0; i < reps; i++) {
+            System.getProperty("user.region");
+        }
+    }
+
+    public void timeAccessController_getPropertyAction(int reps) {
+        for (int i = 0; i < reps; i++) {
+            AccessController.doPrivileged(
+                    new GetPropertyAction("user.language", "en"));
+        }
+    }
+
+    public void timeAccessController_getPropertyAction_default(int reps) {
+        for (int i = 0; i < reps; i++) {
+            AccessController.doPrivileged(
+                    new GetPropertyAction("user.region"));
+        }
+    }
+
+}
diff --git a/benchmarks/src/benchmarks/XmlParseBenchmark.java b/benchmarks/src/benchmarks/XmlParseBenchmark.java
index 69ab7a5..1029616 100644
--- a/benchmarks/src/benchmarks/XmlParseBenchmark.java
+++ b/benchmarks/src/benchmarks/XmlParseBenchmark.java
@@ -65,7 +65,8 @@
         DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
         documentBuilder = builderFactory.newDocumentBuilder();
 
-        kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlParser").getConstructor();
+        kxmlConstructor = (Constructor) Class.forName("com.android.org.kxml2.io.KXmlParser")
+                .getConstructor();
         expatConstructor = (Constructor) Class.forName("org.apache.harmony.xml.ExpatPullParser")
                 .getConstructor();
     }
diff --git a/benchmarks/src/benchmarks/XmlSerializeBenchmark.java b/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
index c542e87..a8c51b3 100644
--- a/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
+++ b/benchmarks/src/benchmarks/XmlSerializeBenchmark.java
@@ -81,7 +81,7 @@
     @SuppressWarnings("unchecked")
     @BeforeExperiment
     protected void setUp() throws Exception {
-        kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlSerializer")
+        kxmlConstructor = (Constructor) Class.forName("com.android.org.kxml2.io.KXmlSerializer")
                 .getConstructor();
         fastConstructor = (Constructor) Class.forName("com.android.internal.util.FastXmlSerializer")
                 .getConstructor();
diff --git a/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java b/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java
new file mode 100644
index 0000000..f302850
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.annotation.codegen;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates to the platform toolchain that there is an upcoming public SDK API change for a method.
+ * The API change will add a more specific return type in a subclass for an overridden method.
+ *
+ * <p>When this annotation is present, the toolchain is required to generate on-device bytecode for
+ * an overloaded implementation of the method which is marked as synthetic, returns the more
+ * specific type given in {@link CovariantReturnType#returnType()}, and which delegates to the
+ * method being annotated.
+ *
+ * <p>At some future point in time the public Android API can change so that the public API method
+ * returns the new type. Android platform developers can be sure that all releases after the API
+ * version specified in {@link CovariantReturnType#presentAfter()} have the new method signature on
+ * device and will therefore be compatible with code compiled against the newest public Android API
+ * stubs.
+ *
+ * <p>Once the actual method signature is updated to the new form and this annotation is removed
+ * there will be a synthetic overload for the method with the more general type provided (as normal)
+ * by the Java compiler ensuring compatibility with code compiled against the old stubs.
+ *
+ * <p>When adding this annotation to platform classes the developer should also add CTS tests to
+ * ensure the expected methods are present on all Android devices.
+ *
+ * <p>Notes on scope and limitations:
+ * <ul>
+ * <li>This annotation must have no effect on generated API stubs.</li>
+ * <li>This annotation does not allow the declared exceptions to be made more specific for the
+ * generated synthetic method. This could be added later.</li>
+ * <li>Any type parameters on the annotated method need not be copied.</li>
+ * <li>This annotation is <em>not</em> expected to be treated by the toolchain as inherited. All
+ * layers of platform class hierarchy must specify {@link CovariantReturnType} for all the overloads
+ * that have to be generated. The annotation is marked as repeatable for this reason.</li>
+ * </ul>
+ *
+ * @hide
+ */
+@Repeatable(CovariantReturnType.CovariantReturnTypes.class)
+@Retention(RetentionPolicy.CLASS)
+@Target({ ElementType.METHOD})
+public @interface CovariantReturnType {
+
+    /**
+     * The return type of the synthetic method to generate. Must be a subclass of the return type
+     * of the method being annotated.
+     */
+    Class<?> returnType();
+
+    /**
+     * The last Android API level not to have the generated synthetic method. The annotation can be
+     * removed and the actual return type updated when support for this API level is dropped.
+     */
+    int presentAfter();
+
+    /** @hide */
+    @Retention(RetentionPolicy.CLASS)
+    @Target({ElementType.METHOD})
+    @interface CovariantReturnTypes {
+        CovariantReturnType[] value();
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 6426bd8..b0ffecc 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -16,23 +16,20 @@
 
 package dalvik.system;
 
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.SocketException;
+import libcore.util.NonNull;
+
+import java.util.Objects;
 
 /**
- * Mechanism to let threads set restrictions on what code is allowed
- * to do in their thread.
- *
- * <p>This is meant for applications to prevent certain blocking
- * operations from running on their main event loop (or "UI") threads.
- *
- * <p>Note that this is all best-effort to catch most accidental mistakes
- * and isn't intended to be a perfect mechanism, nor provide any sort of
- * security.
+ * Interface that enables {@code StrictMode} to install callbacks to implement
+ * its policy detection and penalty behavior in {@code libcore} code.
+ * <p>
+ * The framework separately defines {@code StrictMode.ThreadPolicy} and
+ * {@code StrictMode.VmPolicy}, so we mirror that separation here; the former is
+ * designed for per-thread policies, and the latter for process-wide policies.
+ * <p>
+ * Note that this is all best-effort to catch most accidental mistakes and isn't
+ * intended to be a perfect mechanism, nor provide any sort of security.
  *
  * @hide
  */
@@ -41,14 +38,9 @@
     // TODO: refactor class name to something more generic, since its scope is
     // growing beyond just blocking/logging.
 
-    public static final int DISALLOW_DISK_WRITE = 0x01;
-    public static final int DISALLOW_DISK_READ = 0x02;
-    public static final int DISALLOW_NETWORK = 0x04;
-    public static final int PASS_RESTRICTIONS_VIA_RPC = 0x08;
-    public static final int PENALTY_LOG = 0x10;
-    public static final int PENALTY_DIALOG = 0x20;
-    public static final int PENALTY_DEATH = 0x40;
-
+    /**
+     * Per-thread interface used to implement {@code StrictMode.ThreadPolicy}.
+     */
     public interface Policy {
         /**
          * Called on disk writes.
@@ -71,6 +63,11 @@
         void onUnbufferedIO();
 
         /**
+         * Called on explicit GC request, i.e. Runtime.gc().
+         */
+        void onExplicitGc();
+
+        /**
          * Returns the policy bitmask, for shipping over Binder calls
          * to remote threads/processes and reinstantiating the policy
          * there.  The bits in the mask are from the DISALLOW_* and
@@ -79,6 +76,36 @@
         int getPolicyMask();
     }
 
+    /**
+     * Per-process interface used to implement {@code StrictMode.VmPolicy}.
+     */
+    public interface VmPolicy {
+        /**
+         * Called by core libraries code when the given path is accessed. This
+         * allows an implementation to alert developers to unexpected path
+         * access, such as trying to access encrypted files before the
+         * encryption key has been installed.
+         * <p>
+         * This only needs to be called once when a path is first accessed by
+         * the process; it doesn't need to be invoked for each subsequent
+         * read/write. (In contrast, we always need to call the per-thread
+         * policy for every read/write, since ownership of an open file can move
+         * between threads.)
+         * <p>
+         * Note that this is all best-effort to catch most accidental mistakes
+         * and isn't intended to be a perfect mechanism, nor provide any sort of
+         * security.
+         *
+         * @param path The path in the local file system that is being accessed
+         *            for reading or writing.
+         */
+        void onPathAccess(String path);
+    }
+
+    /**
+     * @deprecated no longer actively used, but kept intact for greylist.
+     */
+    @Deprecated
     public static class BlockGuardPolicyException extends RuntimeException {
         // bitmask of DISALLOW_*, PENALTY_*, etc flags
         private final int mPolicyState;
@@ -117,17 +144,29 @@
     }
 
     /**
-     * The default, permissive policy that doesn't prevent any operations.
+     * The default, permissive per-thread policy.
      */
     public static final Policy LAX_POLICY = new Policy() {
-            public void onWriteToDisk() {}
-            public void onReadFromDisk() {}
-            public void onNetwork() {}
-            public void onUnbufferedIO() {}
-            public int getPolicyMask() {
-                return 0;
-            }
-        };
+        @Override public String toString() { return "LAX_POLICY"; }
+        @Override public void onWriteToDisk() {}
+        @Override public void onReadFromDisk() {}
+        @Override public void onNetwork() {}
+        @Override public void onUnbufferedIO() {}
+        @Override public void onExplicitGc() {}
+
+        @Override
+        public int getPolicyMask() {
+            return 0;
+        }
+    };
+
+    /**
+     * The default, permissive per-process policy.
+     */
+    public static final VmPolicy LAX_VM_POLICY = new VmPolicy() {
+        @Override public String toString() { return "LAX_VM_POLICY"; }
+        @Override public void onPathAccess(String path) {}
+    };
 
     private static ThreadLocal<Policy> threadPolicy = new ThreadLocal<Policy>() {
         @Override protected Policy initialValue() {
@@ -135,27 +174,52 @@
         }
     };
 
+    private static volatile VmPolicy vmPolicy = LAX_VM_POLICY;
+
     /**
-     * Get the current thread's policy.
+     * Get the per-thread policy for the current thread.
      *
-     * @return the current thread's policy.  Never returns null.
-     *     Will return the LAX_POLICY instance if nothing else is set.
+     * @return the current thread's policy. Will return the {@link #LAX_POLICY}
+     *         instance if nothing else is set.
      */
-    public static Policy getThreadPolicy() {
+    public static @NonNull Policy getThreadPolicy() {
         return threadPolicy.get();
     }
 
     /**
-     * Sets the current thread's block guard policy.
+     * Sets the per-thread policy for the current thread.
+     * <p>
+     * This should only be called by {@code StrictMode}, since there can only be
+     * one policy active at any given time.
      *
-     * @param policy policy to set.  May not be null.  Use the public LAX_POLICY
-     *   if you want to unset the active policy.
+     * @param policy policy to set. Use the public {@link #LAX_POLICY} if you
+     *            want to unset the active policy.
      */
-    public static void setThreadPolicy(Policy policy) {
-        if (policy == null) {
-            throw new NullPointerException("policy == null");
-        }
-        threadPolicy.set(policy);
+    public static void setThreadPolicy(@NonNull Policy policy) {
+        threadPolicy.set(Objects.requireNonNull(policy));
+    }
+
+    /**
+     * Get the per-process policy for the current process.
+     *
+     * @return the current process's policy. Will return the
+     *         {@link #LAX_VM_POLICY} instance if nothing else is set.
+     */
+    public static @NonNull VmPolicy getVmPolicy() {
+        return vmPolicy;
+    }
+
+    /**
+     * Set the per-process policy for the current process.
+     * <p>
+     * This should only be called by {@code StrictMode}, since there can only be
+     * one policy active at any given time.
+     *
+     * @param policy policy to set. Use the public {@link #LAX_VM_POLICY} if you
+     *            want to unset the active policy.
+     */
+    public static void setVmPolicy(@NonNull VmPolicy policy) {
+        vmPolicy = Objects.requireNonNull(policy);
     }
 
     private BlockGuard() {}
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index afedba5..7c1987f 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -455,16 +455,6 @@
      */
     public static final int DEX2OAT_FOR_FILTER = 3;
 
-    /**
-     * dex2oat should be run to update the apk/jar because the existing code
-     * is not relocated to match the boot image.
-     *
-     * See {@link #getDexOptNeeded(String, String, String, boolean, boolean)}.
-     *
-     * @hide
-     */
-    public static final int DEX2OAT_FOR_RELOCATION = 4;
-
 
     /**
      * Calls {@link #getDexOptNeeded(String, String, String, String, String, boolean, boolean)}
diff --git a/dalvik/src/main/java/dalvik/system/RuntimeHooks.java b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
new file mode 100644
index 0000000..2bfa731
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.util.Objects;
+import java.util.TimeZone;
+import java.util.function.Supplier;
+
+/**
+ * Provides lifecycle methods and other hooks for an Android runtime "container" to call into the
+ * runtime and core libraries during initialization. For example, from
+ * {@link com.android.internal.os.RuntimeInit}.
+ *
+ * <p>Having a facade class helps to limit the container's knowledge of runtime and core libraries
+ * internal details. All methods assume the container initialization is single threaded.
+ *
+ * @hide
+ */
+public final class RuntimeHooks {
+
+    private static Supplier<String> zoneIdSupplier;
+
+    private RuntimeHooks() {
+        // No need to construct an instance. All methods are static.
+    }
+
+    /**
+     * Sets the {@link Supplier} that is used by {@link TimeZone} to retrieve the current time zone
+     * ID iff the cached default is {@code null}.
+     *
+     * <p>This method also clears the current {@link TimeZone} default ensuring that the supplier
+     * will be used next time {@link TimeZone#getDefault()} is called (unless
+     * {@link TimeZone#setDefault(TimeZone)} is called with a non-null value in the interim).
+     *
+     * <p>Once set the supplier cannot be changed.
+     */
+    public static void setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier) {
+        if (RuntimeHooks.zoneIdSupplier != null) {
+            throw new UnsupportedOperationException("zoneIdSupplier instance already set");
+        }
+        RuntimeHooks.zoneIdSupplier = Objects.requireNonNull(zoneIdSupplier);
+        TimeZone.setDefault(null);
+    }
+
+    /**
+     * Returns the {@link Supplier} that should be used to discover the time zone.
+     */
+    public static Supplier<String> getTimeZoneIdSupplier() {
+        return RuntimeHooks.zoneIdSupplier;
+    }
+
+    /**
+     * Sets an {@link Thread.UncaughtExceptionHandler} that will be called before any
+     * returned by {@link Thread#getUncaughtExceptionHandler()}. To allow the standard
+     * handlers to run, this handler should never terminate this process. Any
+     * throwables thrown by the handler will be ignored by
+     * {@link Thread#dispatchUncaughtException(Throwable)}.
+     */
+    public static void setUncaughtExceptionPreHandler(
+            Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
+        Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
index 61c1b95..bd19454 100644
--- a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
+++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
@@ -16,6 +16,10 @@
 
 package dalvik.system;
 
+import android.icu.impl.CacheValue;
+import android.icu.text.DecimalFormatSymbols;
+import android.icu.util.ULocale;
+
 import java.io.File;
 
 /**
@@ -34,6 +38,46 @@
     public static native void startZygoteNoThreadCreation();
 
     /**
+     * Called when the zygote begins preloading classes and data.
+     */
+    public static void onBeginPreload() {
+        // Pin ICU data in memory from this point that would normally be held by soft references.
+        // Without this, any references created immediately below or during class preloading
+        // would be collected when the Zygote GC runs in gcAndFinalize().
+        CacheValue.setStrength(CacheValue.Strength.STRONG);
+
+        // Explicitly exercise code to cache data apps are likely to need.
+        ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
+        for (ULocale uLocale : localesToPin) {
+            new DecimalFormatSymbols(uLocale);
+        }
+    }
+
+    /**
+     * Called when the zygote has completed preloading classes and data.
+     */
+    public static void onEndPreload() {
+        // All cache references created by ICU from this point will be soft.
+        CacheValue.setStrength(CacheValue.Strength.SOFT);
+    }
+
+    /**
+     * Runs several special GCs to try to clean up a few generations of
+     * softly- and final-reachable objects, along with any other garbage.
+     * This is only useful just before a fork().
+     */
+    public static void gcAndFinalize() {
+        final VMRuntime runtime = VMRuntime.getRuntime();
+
+        /* runFinalizationSync() lets finalizers be called in Zygote,
+         * which doesn't have a HeapWorker thread.
+         */
+        System.gc();
+        runtime.runFinalizationSync();
+        System.gc();
+    }
+
+    /**
      * Called by the zygote when startup is finished. It marks the point when it is
      * conceivable that threads would be started again, e.g., restarting daemons.
      */
@@ -41,8 +85,8 @@
 
     /**
      * Called by the zygote prior to every fork. Each call to {@code preFork}
-     * is followed by a matching call to {@link #postForkChild(int, String)} on the child
-     * process and {@link #postForkCommon()} on both the parent and the child
+     * is followed by a matching call to {@link #postForkChild(int, boolean, boolean, String)} on
+     * the child process and {@link #postForkCommon()} on both the parent and the child
      * process. {@code postForkCommon} is called after {@code postForkChild} in
      * the child process.
      */
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 1343edc..e3e36aa 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1526,15 +1526,6 @@
     "com.google.security.wycheproof.RsaEncryptionTest#testGetExceptionsOAEP"
   ]
 },
-/* TODO(flooey): Remove when referenced BoringSSL change is merged */
-{
-  description: "Test crashes due to BoringSSL bug fixed in 61dedd68",
-  bug: 36636626,
-  result: EXEC_FAILED,
-  names: [
-    "com.google.security.wycheproof.EcdhTest#testModifiedPublicSpec"
-  ]
-},
 {
   description: "Bullhead kernel does not block send when buffer is supposed to have saturated",
   bug: 36691333,
diff --git a/expectations/virtualdeviceknownfailures.txt b/expectations/virtualdeviceknownfailures.txt
index 300bfde..66b67e4 100644
--- a/expectations/virtualdeviceknownfailures.txt
+++ b/expectations/virtualdeviceknownfailures.txt
@@ -22,5 +22,13 @@
           "org.apache.harmony.tests.java.net.MulticastSocketTest#test_setLoopbackModeSendReceive_IPv4"
           ],
   bug: 35922755
+},
+{
+  description: "Kernels between 4.4 and 4.9 interpret the backlog parameter differently than we
+                expect, causing this test to fail, and our emulators currently use those kernel
+                versions.  See b/31960002 for a full discussion and references to the upstream
+                changes.",
+  name: "libcore.javax.net.ServerSocketFactoryTest#testCreateServerSocketWithPortNoBacklog",
+  bug: 73535217
 }
 ]
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
index f5d4163..477a8e2 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
@@ -99,7 +99,6 @@
         }
 
         thread.interrupt();
-        //process.destroy();
         try {
             Thread.sleep(100);
         } catch(InterruptedException ie) {
@@ -107,6 +106,9 @@
         }
 
         assertTrue(isThrown);
+        // Destroy process, otherwise it will run until 1000 seconds
+        // have elapsed but we don't need it again for this test.
+        process.destroy();
     }
 
     public void testPwd() throws IOException, InterruptedException {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
index cf6f89e..49444b4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessTest.java
@@ -131,6 +131,10 @@
       process.exitValue();
       fail();
     } catch(IllegalThreadStateException expected) {
+    } finally {
+      // Destroy process, otherwise it will run until 3000 seconds
+      // have elapsed but we don't need it again for this test.
+      process.destroy();
     }
   }
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
index 41ef93e..2e66416 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigDecimalTest.java
@@ -912,11 +912,9 @@
 				((notrailingzerotest.stripTrailingZeros()).scale() == 0)
 				);
 		
-                // BEGIN Android-changed: preserve RI compatibility, so BigDecimal.equals (which checks
-                // value *and* scale) continues to work. https://issues.apache.org/jira/browse/HARMONY-4623
-		/* Zero */
 		BigDecimal zerotest = new BigDecimal("0.0000");
-                assertEquals("stripTrailingZero failed for 0.0000", 4, zerotest.stripTrailingZeros().scale());
+                assertEquals("stripTrailingZero failed for 0.0000", 0,
+				zerotest.stripTrailingZeros().scale());
 	}	
 
 	public void testMathContextConstruction() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
index 337e7c4..b9ee1c6 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/math/BigIntegerTest.java
@@ -301,6 +301,7 @@
 	/**
 	 * @tests java.math.BigInteger#negate()
 	 */
+	@SuppressWarnings("ConstantOverflow")
 	public void test_negate() {
 		assertTrue("Single negation of zero did not result in zero", zero
 				.negate().equals(zero));
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
index db09af8..756c9c8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/ByteBufferTest.java
@@ -55,6 +55,32 @@
         super.tearDown();
     }
 
+    public void testAllocateDirect() {
+        try {
+            ByteBuffer.allocateDirect(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        checkAllocateDirect(0);
+        checkAllocateDirect(1);
+        checkAllocateDirect(2);
+        checkAllocateDirect(1 << 16);
+        checkAllocateDirect(123456);
+    }
+
+    private void checkAllocateDirect(int capacity) {
+        ByteBuffer b = ByteBuffer.allocateDirect(capacity);
+        assertEquals(capacity, b.capacity());
+        assertEquals(0, b.position());
+        assertEquals(capacity, b.limit());
+        assertContentEquals(b, new byte[capacity], 0, capacity);
+        try {
+            b.reset();
+            fail();
+        } catch (InvalidMarkException expected) {
+        }
+    }
+
     public void testArray() {
         if (buf.hasArray()) {
             byte array[] = buf.array();
@@ -2085,21 +2111,21 @@
         }
     }
 
-    private void assertContentEquals(ByteBuffer buf, byte array[],
+    private static void assertContentEquals(ByteBuffer buf, byte array[],
             int offset, int length) {
         for (int i = 0; i < length; i++) {
             assertEquals(buf.get(i), array[offset + i]);
         }
     }
 
-    private void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
+    private static void assertContentEquals(ByteBuffer buf, ByteBuffer other) {
         assertEquals(buf.capacity(), other.capacity());
         for (int i = 0; i < buf.capacity(); i++) {
             assertEquals(buf.get(i), other.get(i));
         }
     }
 
-    private void assertContentLikeTestData1(ByteBuffer buf,
+    private static void assertContentLikeTestData1(ByteBuffer buf,
             int startIndex, byte startValue, int length) {
         byte value = startValue;
         for (int i = 0; i < length; i++) {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
index 3c634f3..6ae5eb4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DoubleBufferTest.java
@@ -208,6 +208,17 @@
                 .compareTo(dbuffer3));
     }
 
+    public void testCompareTo_positiveAndNegativeZero() {
+        double negativeZero = Double.parseDouble("-0");
+        double positiveZero = Double.parseDouble("+0");
+        DoubleBuffer negativeZeroBuffer = DoubleBuffer.wrap(new double[] { negativeZero });
+        DoubleBuffer positiveZeroBuffer = DoubleBuffer.wrap(new double[] { positiveZero });
+        assertTrue(Double.compare(negativeZero, positiveZero) < 0); // sanity check
+
+        // Unlike Double.compare(), DoubleBuffer.compareTo() considers -0 == +0
+        assertEquals(0, negativeZeroBuffer.compareTo(positiveZeroBuffer));
+    }
+
     public void testDuplicate() {
         buf.clear();
         buf.mark();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
index 89ed576..c8c5da9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
@@ -378,87 +378,6 @@
         }
     }
 
-
-    /**
-     * java.util.jar.JarFile#getJarEntry(java.lang.String)
-     */
-    public void testGetJarEntry() throws Exception {
-        File file = Support_Resources.copyFile(resources, null, jarName);
-        JarFile jarFile = new JarFile(file);
-        assertEquals("Error in returned entry", 311, jarFile.getEntry(
-                entryName).getSize());
-        jarFile.close();
-
-        // tests for signed jars
-        // test all signed jars in the /Testres/Internal/SignedJars directory
-        String jarDirUrl = Support_Resources
-                .getResourceURL("/../internalres/signedjars");
-        Vector<String> signedJars = new Vector<String>();
-        try {
-            InputStream is = new URL(jarDirUrl + "/jarlist.txt").openStream();
-            while (is.available() > 0) {
-                StringBuilder linebuff = new StringBuilder(80); // Typical line
-                // length
-                done: while (true) {
-                    int nextByte = is.read();
-                    switch (nextByte) {
-                        case -1:
-                            break done;
-                        case (byte) '\r':
-                            if (linebuff.length() == 0) {
-                                // ignore
-                            }
-                            break done;
-                        case (byte) '\n':
-                            if (linebuff.length() == 0) {
-                                // ignore
-                            }
-                            break done;
-                        default:
-                            linebuff.append((char) nextByte);
-                    }
-                }
-                if (linebuff.length() == 0) {
-                    break;
-                }
-                String line = linebuff.toString();
-                signedJars.add(line);
-            }
-            is.close();
-        } catch (IOException e) {
-            // no list of jars found
-        }
-
-        for (int i = 0; i < signedJars.size(); i++) {
-            String jarName = signedJars.get(i);
-            try {
-                file = Support_Resources.getExternalLocalFile(jarDirUrl
-                        + "/" + jarName);
-                jarFile = new JarFile(file, true);
-                boolean foundCerts = false;
-                Enumeration<JarEntry> e = jarFile.entries();
-                while (e.hasMoreElements()) {
-                    JarEntry entry = e.nextElement();
-                    InputStream is = jarFile.getInputStream(entry);
-                    is.skip(100000);
-                    is.close();
-                    Certificate[] certs = entry.getCertificates();
-                    if (certs != null && certs.length > 0) {
-                        foundCerts = true;
-                        break;
-                    }
-                }
-                assertTrue(
-                        "No certificates found during signed jar test for jar \""
-                                + jarName + "\"", foundCerts);
-                jarFile.close();
-            } catch (IOException e) {
-                fail("Exception during signed jar test for jar \"" + jarName
-                        + "\": " + e.toString());
-            }
-        }
-    }
-
     /**
      * java.util.jar.JarFile#getManifest()
      */
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
index e84b356..57cc65f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -216,9 +216,6 @@
         }
     }
 
-    /*
-     * Regression test for HARMONY-997
-     */
     public void testReplacementBackSlash() {
         String str = "replace me";
         String replacedString = "me";
@@ -227,8 +224,29 @@
         Matcher mat = pat.matcher(str);
         try {
             mat.replaceAll(substitutionString);
-            fail("IndexOutOfBoundsException should be thrown");
-        } catch (IndexOutOfBoundsException e) {
+            fail("IllegalArgumentException should be thrown");
+        } catch (IllegalArgumentException e) {
         }
     }
+
+    public void testAppendReplacement_replacementEndsWithBackslash() {
+        Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+        matcher.find();
+        try {
+            matcher.appendReplacement(new StringBuffer(), "replacement\\");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testAppendReplacement_replacementEndsWithDollar() {
+        Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+        matcher.find();
+        try {
+            matcher.appendReplacement(new StringBuffer(), "replacement$");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
index 98508e1..276617b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
@@ -143,6 +143,24 @@
         assertEquals("zzzcatzzzdogzzz", mat.replaceFirst("cat"));
     }
 
+    public void testReplaceFirst_null_match() {
+        Matcher matcher = Pattern.compile("Hello").matcher("Hello, world!");
+        try {
+            matcher.replaceFirst(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testReplaceFirst_null_nomatch() {
+        Matcher matcher = Pattern.compile("not found").matcher("Hello, world!");
+        try {
+            matcher.replaceFirst(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
     public void testPattern() {
         for (String element : testPatterns) {
             Pattern test = Pattern.compile(element);
@@ -420,6 +438,38 @@
         }
     }
 
+    public void testEnd_groupIndexOutOfBounds() {
+        Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+        assertTrue(matcher.find());
+        try {
+            matcher.end(-1 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+            assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+        }
+
+        try {
+            matcher.end(2 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+            assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+        }
+    }
+
+    public void testStart_groupIndexOutOfBounds() {
+        Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+        assertTrue(matcher.find());
+        try {
+            matcher.start(-1 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+            assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+        }
+
+        try {
+            matcher.start(2 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+            assertFalse(expected instanceof ArrayIndexOutOfBoundsException);
+        }
+    }
+
     public void testEnhancedFind() {
         String input = "foob";
         String pattern = "a*b";
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
index c34cebe..f696dff8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,6 +27,7 @@
  */
 @SuppressWarnings("nls")
 public class ModeTest extends TestCase {
+
     public void testCase() throws PatternSyntaxException {
         Pattern p;
         Matcher m;
@@ -37,6 +38,7 @@
         assertEquals("dog", m.group(1));
         assertFalse(m.find());
 
+
         p = Pattern.compile("([a-z]+)[0-9]+", Pattern.CASE_INSENSITIVE);
         m = p.matcher("cAt123#doG345");
         assertTrue(m.find());
@@ -45,6 +47,7 @@
         assertEquals("doG", m.group(1));
         assertFalse(m.find());
 
+
         p = Pattern.compile("(?i)([a-z]+)[0-9]+");
         m = p.matcher("cAt123#doG345");
         assertTrue(m.find());
@@ -67,6 +70,7 @@
         m = p.matcher("barfoo");
         assertFalse(m.find());
 
+
         p = Pattern.compile("foo$");
         m = p.matcher("foobar");
         assertFalse(m.find());
@@ -76,6 +80,7 @@
         assertTrue(m.start() == 3 && m.end() == 6);
         assertFalse(m.find());
 
+
         p = Pattern.compile("^foo([0-9]*)", Pattern.MULTILINE);
         m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
         assertTrue(m.find());
@@ -84,6 +89,7 @@
         assertEquals("2", m.group(1));
         assertFalse(m.find());
 
+
         p = Pattern.compile("foo([0-9]*)$", Pattern.MULTILINE);
         m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
         assertTrue(m.find());
@@ -92,6 +98,7 @@
         assertEquals("4", m.group(1));
         assertFalse(m.find());
 
+
         p = Pattern.compile("(?m)^foo([0-9]*)");
         m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
         assertTrue(m.find());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
index 1eac3f3..2226df8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,15 +28,15 @@
     public void testSimpleReplace() throws PatternSyntaxException {
         String target, pattern, repl;
 
-        target = "foobarfobarfoofo1";
+        target = "foobarfobarfoofo1barfort";
         pattern = "fo[^o]";
         repl = "xxx";
 
         Pattern p = Pattern.compile(pattern);
         Matcher m = p.matcher(target);
 
-        assertEquals("foobarxxxarfoofo1", m.replaceFirst(repl));
-        assertEquals("foobarxxxarfooxxx", m.replaceAll(repl));
+        assertEquals("foobarxxxarfoofo1barfort", m.replaceFirst(repl));
+        assertEquals("foobarxxxarfooxxxbarxxxt", m.replaceAll(repl));
     }
 
     public void testCaptureReplace() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
index 5a5bc2b..4818106 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java
@@ -17,13 +17,16 @@
 
 package org.apache.harmony.tests.java.util.regex;
 
+import java.util.Arrays;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
 import junit.framework.TestCase;
+import java.util.regex.*;
 
 /**
  * TODO Type description
+ *
  */
 @SuppressWarnings("nls")
 public class SplitTest extends TestCase {
@@ -32,9 +35,52 @@
         Pattern p = Pattern.compile("/");
         String[] results = p.split("have/you/done/it/right");
         String[] expected = new String[] { "have", "you", "done", "it", "right" };
-        assertEquals(expected.length, results.length);
+        assertArraysEqual(expected, results);
+    }
+
+    @SuppressWarnings("InvalidPatternSyntax")
+    public void testEmptySplits() {
+        // Trailing empty matches are removed.
+        assertArraysEqual(new String[0], "hello".split("."));
+        assertArraysEqual(new String[] { "1", "2" }, "1:2:".split(":"));
+        // ...including when that results in an empty result.
+        assertArraysEqual(new String[0], ":".split(":"));
+        // ...but not when limit < 0.
+        assertArraysEqual(new String[] { "1", "2", "" }, "1:2:".split(":", -1));
+
+        // Leading empty matches are retained.
+        assertArraysEqual(new String[] { "", "", "o" }, "hello".split(".."));
+
+        // A separator that doesn't occur in the input gets you the input.
+        assertArraysEqual(new String[] { "hello" }, "hello".split("not-present-in-test"));
+        // ...including when the input is the empty string.
+        // (Perl returns an empty list instead.)
+        assertArraysEqual(new String[] { "" }, "".split("not-present-in-test"));
+        assertArraysEqual(new String[] { "" }, "".split("A?"));
+
+        // The limit argument controls the size of the result.
+        // If l == 0, the result is as long as needed, except trailing empty matches are dropped.
+        // If l < 0, the result is as long as needed, and trailing empty matches are retained.
+        // If l > 0, the result contains the first l matches, plus one string containing the remaining input.
+        // Examples without a trailing separator (and hence without a trailing empty match):
+        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 0));
+        assertArraysEqual(new String[] { "a,b,c" }, "a,b,c".split(",", 1));
+        assertArraysEqual(new String[] { "a", "b,c" }, "a,b,c".split(",", 2));
+        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 3));
+        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", Integer.MAX_VALUE));
+        // Examples with a trailing separator (and hence possibly with a trailing empty match):
+        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c,".split(",", 0));
+        assertArraysEqual(new String[] { "a,b,c," }, "a,b,c,".split(",", 1));
+        assertArraysEqual(new String[] { "a", "b,c," }, "a,b,c,".split(",", 2));
+        assertArraysEqual(new String[] { "a", "b", "c," }, "a,b,c,".split(",", 3));
+        assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", Integer.MAX_VALUE));
+        assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", -1));
+    }
+
+    private void assertArraysEqual(String[] expected, String[] actual) {
+        assertEquals(expected.length, actual.length);
         for (int i = 0; i < expected.length; i++) {
-            assertEquals(results[i], expected[i]);
+            assertEquals(Integer.toString(i), expected[i], actual[i]);
         }
     }
 
@@ -131,41 +177,23 @@
 
     public void testSplit2() {
         Pattern p = Pattern.compile("");
-        String s[];
-        s = p.split("a", -1);
-        assertEquals(3, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("", s[2]);
+        assertEquals(Arrays.asList("a", ""), Arrays.asList(p.split("a", -1)));
+        assertEquals(Arrays.asList(""), Arrays.asList(p.split("", -1)));
+        assertEquals(Arrays.asList("a", "b", "c", "d", ""), Arrays.asList(p.split("abcd", -1)));
 
-        s = p.split("", -1);
-        assertEquals(1, s.length);
-        assertEquals("", s[0]);
-
-        s = p.split("abcd", -1);
-        assertEquals(6, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("b", s[2]);
-        assertEquals("c", s[3]);
-        assertEquals("d", s[4]);
-        assertEquals("", s[5]);
+        // Regression test for Android
+        assertEquals("GOOG,23,500".split("|").length, 11);
     }
 
+
     public void testSplitSupplementaryWithEmptyString() {
-
         /*
-         * See http://www.unicode.org/reports/tr18/#Supplementary_Characters We
-         * have to treat text as code points not code units.
+         * See http://www.unicode.org/reports/tr18/#Supplementary_Characters
+         * We have to treat text as code points not code units.
          */
         Pattern p = Pattern.compile("");
-        String s[];
-        s = p.split("a\ud869\uded6b", -1);
-        assertEquals(5, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("\ud869\uded6", s[2]);
-        assertEquals("b", s[3]);
-        assertEquals("", s[4]);
+        String[] s = p.split("a\ud869\uded6b", -1);
+        assertEquals(Arrays.asList("a", "\ud869\uded6", "b", ""), Arrays.asList(s));
     }
+
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
index 6109762..58cdf52 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterInputStreamTest.java
@@ -488,8 +488,8 @@
     }
 
     // http://b/26462400
-    public void testInflaterInputStreamWithExternalInflater() throws Exception {
-        InputStream base = new ByteArrayInputStream(new byte[] { 'h', 'i'});
+    public void testInflaterInputStreamWithExternalInflater_3ArgConstructor() throws Exception {
+        InputStream base = new ByteArrayInputStream(new byte[]{'h', 'i'});
         Inflater inf = new Inflater();
 
         InflaterInputStream iis = new InflaterInputStream(base, inf, 512);
@@ -497,17 +497,21 @@
         try {
             inf.reset();
             fail();
-        } catch (IllegalStateException espected) {
+        } catch (NullPointerException expected) {
             // Expected because the inflater should've been closed when the stream was.
         }
+    }
 
-        inf = new Inflater();
-        iis = new InflaterInputStream(base, inf);
+    // http://b/26462400
+    public void testInflaterInputStreamWithExternalInflater_2ArgConstructor() throws Exception {
+        InputStream base = new ByteArrayInputStream(new byte[]{'h', 'i'});
+        Inflater inf = new Inflater();
+        InflaterInputStream iis = new InflaterInputStream(base, inf);
         iis.close();
         try {
             inf.reset();
             fail();
-        } catch (IllegalStateException espected) {
+        } catch (NullPointerException expected) {
             // Expected because the inflater should've been closed when the stream was.
         }
     }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
index a15a5cf..5276246 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/InflaterTest.java
@@ -53,11 +53,10 @@
         inflate.setInput(byteArray);
         inflate.end();
 
-        // Note that the RI throws an NPE here instead of an ISE (???).
         try {
             inflate.reset();
-            inflate.setInput(byteArray);
-        } catch (IllegalStateException expected) {
+        } catch (NullPointerException expected) {
+            // Expected
         }
 
         Inflater i = new Inflater();
@@ -424,11 +423,11 @@
         inflate.end();
         try {
             inflate.inflate(outPutInf, offSet, 1);
-            fail("IllegalStateException expected");
+            fail("NullPointerException expected");
         } catch (DataFormatException e) {
             fail("Invalid input to be decompressed");
-        } catch (IllegalStateException e) {
-            //expected
+        } catch (NullPointerException expected) {
+            // Expected
         }
     }
 
@@ -1002,9 +1001,9 @@
         infl1.end();
         try {
             infl1.setDictionary(dictionary2.getBytes());
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException ise) {
-            //expected
+            fail("NullPointerException expected");
+        } catch (NullPointerException expected) {
+            // Expected
         }
     }
 
@@ -1137,41 +1136,38 @@
 
         try {
             inflate.getAdler();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException expected) {
-            //expected
+            fail("NullPointerException expected");
+        } catch (NullPointerException expected) {
+            // Expected
         }
 
         try {
             inflate.getBytesRead();
             fail("NullPointerException expected");
-        } catch (IllegalStateException expected) {
         } catch (NullPointerException expected) {
-            //expected
+            // Expected
         }
 
         try {
             inflate.getBytesWritten();
             fail("NullPointerException expected");
         } catch (NullPointerException expected) {
-        } catch (IllegalStateException expected) {
-            //expected
+            // Expected
         }
 
 
         try {
             inflate.getTotalIn();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException ise) {
-            //expected
+            fail("NullPointerException expected");
+        } catch (NullPointerException expected) {
+            // Expected
         }
 
         try {
             inflate.getTotalOut();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException ise) {
-            //expected
+            fail("NullPointerException expected");
+        } catch (NullPointerException expected) {
+            // Expected
         }
-
     }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
index 49a15bb..e0b3eb2 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipInputStreamTest.java
@@ -234,7 +234,7 @@
         if (i != entrySize) {
             fail("ZipInputStream.available or ZipInputStream.skip does not " +
                     "working properly. Only skipped " + i +
-                    " bytes instead of " + entrySize);
+                    " bytes instead of " + entrySize + " for entry " + entry.getName());
         }
         assertEquals(0, zis1.skip(1));
         assertEquals(0, zis1.available());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
index f8d2847..930fa3f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLEngineTest.java
@@ -25,8 +25,10 @@
 import java.nio.channels.Pipe.SourceChannel;
 import java.security.KeyManagementException;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
@@ -62,7 +64,10 @@
         assertEquals(-1, e.getPeerPort());
         String[] suites = e.getSupportedCipherSuites();
         e.setEnabledCipherSuites(suites);
-        assertEquals(e.getEnabledCipherSuites().length, suites.length);
+        // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+        // shouldn't be enabled.
+        assertEquals(suites.length - StandardNames.CIPHER_SUITES_TLS13.size(),
+                e.getEnabledCipherSuites().length);
     }
 
     /**
@@ -99,7 +104,10 @@
         assertEquals(e.getPeerPort(), port);
         String[] suites = e.getSupportedCipherSuites();
         e.setEnabledCipherSuites(suites);
-        assertEquals(e.getEnabledCipherSuites().length, suites.length);
+        // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+        // shouldn't be enabled.
+        assertEquals(suites.length - StandardNames.CIPHER_SUITES_TLS13.size(),
+                e.getEnabledCipherSuites().length);
         e.setUseClientMode(true);
         assertTrue(e.getUseClientMode());
     }
@@ -176,8 +184,12 @@
         sse.setEnabledCipherSuites(st);
         String[] res = sse.getEnabledCipherSuites();
         assertNotNull("Null array was returned", res);
-        assertEquals("Incorrect array length", res.length, st.length);
-        assertTrue("Incorrect array was returned", Arrays.equals(res, st));
+        // By default, the engine only supports TLS 1.2, so the TLS 1.3 cipher suites
+        // shouldn't be enabled.
+        List<String> supported = new ArrayList<>(Arrays.asList(st));
+        supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
+        assertEquals("Incorrect array length", res.length, supported.size());
+        assertEquals("Incorrect array was returned", Arrays.asList(res), supported);
 
         try {
             sse.setEnabledCipherSuites(null);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
index 117a1a0..247b4e4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
@@ -16,6 +16,8 @@
 
 package org.apache.harmony.tests.javax.net.ssl;
 
+import java.util.ArrayList;
+import java.util.List;
 import junit.framework.TestCase;
 
 import java.io.ByteArrayInputStream;
@@ -31,6 +33,7 @@
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLServerSocket;
+import libcore.java.security.StandardNames;
 
 public class SSLServerSocketTest extends TestCase {
 
@@ -226,8 +229,12 @@
         sss.setEnabledCipherSuites(sss.getSupportedCipherSuites());
         String[] res = sss.getEnabledCipherSuites();
         assertNotNull("NULL result", res);
+        // By default, the socket only supports TLS 1.2, so the TLS 1.3 cipher suites
+        // shouldn't be enabled.
+        List<String> supported = new ArrayList<>(Arrays.asList(sss.getSupportedCipherSuites()));
+        supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
         assertEquals("not all supported cipher suites were enabled",
-                     Arrays.asList(sss.getSupportedCipherSuites()),
+                     supported,
                      Arrays.asList(res));
     }
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
index 5712a48..d30ae53a 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
@@ -23,8 +23,10 @@
 import java.net.UnknownHostException;
 import java.security.KeyStore;
 import java.security.SecureRandom;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
+import java.util.List;
 import javax.net.ssl.HandshakeCompletedEvent;
 import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.KeyManager;
@@ -371,8 +373,12 @@
         ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
         String[] res = ssl.getEnabledCipherSuites();
         assertNotNull("NULL result", res);
+        // By default, the socket only supports TLS 1.2, so the TLS 1.3 cipher suites
+        // shouldn't be enabled.
+        List<String> supported = new ArrayList<>(Arrays.asList(ssl.getSupportedCipherSuites()));
+        supported.removeAll(StandardNames.CIPHER_SUITES_TLS13);
         assertEquals("not all supported cipher suites were enabled",
-                     Arrays.asList(ssl.getSupportedCipherSuites()),
+                     supported,
                      Arrays.asList(res));
         ssl.close();
     }
diff --git a/java_tests_blacklist b/java_tests_blacklist
deleted file mode 100644
index fe3ddc2..0000000
--- a/java_tests_blacklist
+++ /dev/null
@@ -1,2 +0,0 @@
-luni/src/test/java/libcore/java/util/zip/Zip64Test.java
-luni/src/test/java/libcore/java/util/zip/Zip64FileTest.java
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
index c8d3856..818a3b2 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
@@ -30,56 +30,55 @@
     // }
 
     // for testing subclass access
-    // android-note: Removed because android doesn't restrict reflection access
-    // static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
-    //     public void checkPrivateAccess() {
-    //         try {
-    //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
-    //                 AtomicIntegerFieldUpdater.newUpdater
-    //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
-    //             shouldThrow();
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
+    static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
+        public void checkPrivateAccess() {
+            try {
+                AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+                    AtomicIntegerFieldUpdater.newUpdater
+                    (AtomicIntegerFieldUpdaterTest.class, "privateField");
+                shouldThrow();
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
 
-    //     public void checkCompareAndSetProtectedSub() {
-    //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
-    //             AtomicIntegerFieldUpdater.newUpdater
-    //             (AtomicIntegerFieldUpdaterTest.class, "protectedField");
-    //         this.protectedField = 1;
-    //         assertTrue(a.compareAndSet(this, 1, 2));
-    //         assertTrue(a.compareAndSet(this, 2, -4));
-    //         assertEquals(-4, a.get(this));
-    //         assertFalse(a.compareAndSet(this, -5, 7));
-    //         assertEquals(-4, a.get(this));
-    //         assertTrue(a.compareAndSet(this, -4, 7));
-    //         assertEquals(7, a.get(this));
-    //     }
-    // }
+        public void checkCompareAndSetProtectedSub() {
+            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+                AtomicIntegerFieldUpdater.newUpdater
+                (AtomicIntegerFieldUpdaterTest.class, "protectedField");
+            this.protectedField = 1;
+            assertTrue(a.compareAndSet(this, 1, 2));
+            assertTrue(a.compareAndSet(this, 2, -4));
+            assertEquals(-4, a.get(this));
+            assertFalse(a.compareAndSet(this, -5, 7));
+            assertEquals(-4, a.get(this));
+            assertTrue(a.compareAndSet(this, -4, 7));
+            assertEquals(7, a.get(this));
+        }
+    }
 
-    // static class UnrelatedClass {
-    //     public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
-    //         obj.x = 72;
-    //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
-    //             AtomicIntegerFieldUpdater.newUpdater
-    //             (AtomicIntegerFieldUpdaterTest.class, "x");
-    //         assertEquals(72, a.get(obj));
-    //         assertTrue(a.compareAndSet(obj, 72, 73));
-    //         assertEquals(73, a.get(obj));
-    //     }
+    static class UnrelatedClass {
+        public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
+            obj.x = 72;
+            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+                AtomicIntegerFieldUpdater.newUpdater
+                (AtomicIntegerFieldUpdaterTest.class, "x");
+            assertEquals(72, a.get(obj));
+            assertTrue(a.compareAndSet(obj, 72, 73));
+            assertEquals(73, a.get(obj));
+        }
 
-    //     public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
-    //         try {
-    //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
-    //                 AtomicIntegerFieldUpdater.newUpdater
-    //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
-    //             throw new AssertionError("should throw");
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
-    // }
+        public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
+            try {
+                AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+                    AtomicIntegerFieldUpdater.newUpdater
+                    (AtomicIntegerFieldUpdaterTest.class, "privateField");
+                throw new AssertionError("should throw");
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
+    }
 
     AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
         return AtomicIntegerFieldUpdater.newUpdater
@@ -121,22 +120,20 @@
     /**
      * construction using private field from subclass throws RuntimeException
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testPrivateFieldInSubclass() {
-    //     AtomicIntegerFieldUpdaterTestSubclass s =
-    //         new AtomicIntegerFieldUpdaterTestSubclass();
-    //     s.checkPrivateAccess();
-    // }
+    public void testPrivateFieldInSubclass() {
+        AtomicIntegerFieldUpdaterTestSubclass s =
+            new AtomicIntegerFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
 
     /**
      * construction from unrelated class; package access is allowed,
      * private access is not
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testUnrelatedClassAccess() {
-    //     new UnrelatedClass().checkPackageAccess(this);
-    //     new UnrelatedClass().checkPrivateAccess(this);
-    // }
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
 
     /**
      * get returns the last value set or assigned
@@ -203,12 +200,11 @@
      * compareAndSet succeeds in changing protected field value if
      * equal to expected else fails
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testCompareAndSetProtectedInSubclass() {
-    //     AtomicIntegerFieldUpdaterTestSubclass s =
-    //         new AtomicIntegerFieldUpdaterTestSubclass();
-    //     s.checkCompareAndSetProtectedSub();
-    // }
+    public void testCompareAndSetProtectedInSubclass() {
+        AtomicIntegerFieldUpdaterTestSubclass s =
+            new AtomicIntegerFieldUpdaterTestSubclass();
+        s.checkCompareAndSetProtectedSub();
+    }
 
     /**
      * compareAndSet in one thread enables another waiting for value
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
index d46280b..69b97bc 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
@@ -30,56 +30,55 @@
     // }
 
     // for testing subclass access
-    // android-note: Removed because android doesn't restrict reflection access
-    // static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest {
-    //     public void checkPrivateAccess() {
-    //         try {
-    //             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
-    //                 AtomicLongFieldUpdater.newUpdater
-    //                 (AtomicLongFieldUpdaterTest.class, "privateField");
-    //             shouldThrow();
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
+    static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest {
+        public void checkPrivateAccess() {
+            try {
+                AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+                    AtomicLongFieldUpdater.newUpdater
+                    (AtomicLongFieldUpdaterTest.class, "privateField");
+                shouldThrow();
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
 
-    //     public void checkCompareAndSetProtectedSub() {
-    //         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
-    //             AtomicLongFieldUpdater.newUpdater
-    //             (AtomicLongFieldUpdaterTest.class, "protectedField");
-    //         this.protectedField = 1;
-    //         assertTrue(a.compareAndSet(this, 1, 2));
-    //         assertTrue(a.compareAndSet(this, 2, -4));
-    //         assertEquals(-4, a.get(this));
-    //         assertFalse(a.compareAndSet(this, -5, 7));
-    //         assertEquals(-4, a.get(this));
-    //         assertTrue(a.compareAndSet(this, -4, 7));
-    //         assertEquals(7, a.get(this));
-    //     }
-    // }
+        public void checkCompareAndSetProtectedSub() {
+            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+                AtomicLongFieldUpdater.newUpdater
+                (AtomicLongFieldUpdaterTest.class, "protectedField");
+            this.protectedField = 1;
+            assertTrue(a.compareAndSet(this, 1, 2));
+            assertTrue(a.compareAndSet(this, 2, -4));
+            assertEquals(-4, a.get(this));
+            assertFalse(a.compareAndSet(this, -5, 7));
+            assertEquals(-4, a.get(this));
+            assertTrue(a.compareAndSet(this, -4, 7));
+            assertEquals(7, a.get(this));
+        }
+    }
 
-    // static class UnrelatedClass {
-    //     public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) {
-    //         obj.x = 72L;
-    //         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
-    //             AtomicLongFieldUpdater.newUpdater
-    //             (AtomicLongFieldUpdaterTest.class, "x");
-    //         assertEquals(72L, a.get(obj));
-    //         assertTrue(a.compareAndSet(obj, 72L, 73L));
-    //         assertEquals(73L, a.get(obj));
-    //     }
+    static class UnrelatedClass {
+        public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) {
+            obj.x = 72L;
+            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+                AtomicLongFieldUpdater.newUpdater
+                (AtomicLongFieldUpdaterTest.class, "x");
+            assertEquals(72L, a.get(obj));
+            assertTrue(a.compareAndSet(obj, 72L, 73L));
+            assertEquals(73L, a.get(obj));
+        }
 
-    //     public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) {
-    //         try {
-    //             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
-    //                 AtomicLongFieldUpdater.newUpdater
-    //                 (AtomicLongFieldUpdaterTest.class, "privateField");
-    //             throw new AssertionError("should throw");
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
-    // }
+        public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) {
+            try {
+                AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+                    AtomicLongFieldUpdater.newUpdater
+                    (AtomicLongFieldUpdaterTest.class, "privateField");
+                throw new AssertionError("should throw");
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
+    }
 
     AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) {
         return AtomicLongFieldUpdater.newUpdater
@@ -121,22 +120,20 @@
     /**
      * construction using private field from subclass throws RuntimeException
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testPrivateFieldInSubclass() {
-    //     AtomicLongFieldUpdaterTestSubclass s =
-    //         new AtomicLongFieldUpdaterTestSubclass();
-    //     s.checkPrivateAccess();
-    // }
+    public void testPrivateFieldInSubclass() {
+        AtomicLongFieldUpdaterTestSubclass s =
+            new AtomicLongFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
 
     /**
      * construction from unrelated class; package access is allowed,
      * private access is not
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testUnrelatedClassAccess() {
-    //     new UnrelatedClass().checkPackageAccess(this);
-    //     new UnrelatedClass().checkPrivateAccess(this);
-    // }
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
 
     /**
      * get returns the last value set or assigned
@@ -203,12 +200,11 @@
      * compareAndSet succeeds in changing protected field value if
      * equal to expected else fails
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testCompareAndSetProtectedInSubclass() {
-    //     AtomicLongFieldUpdaterTestSubclass s =
-    //         new AtomicLongFieldUpdaterTestSubclass();
-    //     s.checkCompareAndSetProtectedSub();
-    // }
+    public void testCompareAndSetProtectedInSubclass() {
+        AtomicLongFieldUpdaterTestSubclass s =
+            new AtomicLongFieldUpdaterTestSubclass();
+        s.checkCompareAndSetProtectedSub();
+    }
 
     /**
      * compareAndSet in one thread enables another waiting for value
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
index 9b2e9a9..a662e11 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
@@ -32,56 +32,55 @@
     // }
 
     // for testing subclass access
-    // android-note: Removed because android doesn't restrict reflection access
-    // static class AtomicReferenceFieldUpdaterTestSubclass extends AtomicReferenceFieldUpdaterTest {
-    //     public void checkPrivateAccess() {
-    //         try {
-    //             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
-    //                 AtomicReferenceFieldUpdater.newUpdater
-    //                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
-    //             shouldThrow();
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
+    static class AtomicReferenceFieldUpdaterTestSubclass extends AtomicReferenceFieldUpdaterTest {
+        public void checkPrivateAccess() {
+            try {
+                AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+                    AtomicReferenceFieldUpdater.newUpdater
+                    (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+                shouldThrow();
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
 
-    //     public void checkCompareAndSetProtectedSub() {
-    //         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
-    //             AtomicReferenceFieldUpdater.newUpdater
-    //             (AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
-    //         this.protectedField = one;
-    //         assertTrue(a.compareAndSet(this, one, two));
-    //         assertTrue(a.compareAndSet(this, two, m4));
-    //         assertSame(m4, a.get(this));
-    //         assertFalse(a.compareAndSet(this, m5, seven));
-    //         assertFalse(seven == a.get(this));
-    //         assertTrue(a.compareAndSet(this, m4, seven));
-    //         assertSame(seven, a.get(this));
-    //     }
-    // }
+        public void checkCompareAndSetProtectedSub() {
+            AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+                AtomicReferenceFieldUpdater.newUpdater
+                (AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
+            this.protectedField = one;
+            assertTrue(a.compareAndSet(this, one, two));
+            assertTrue(a.compareAndSet(this, two, m4));
+            assertSame(m4, a.get(this));
+            assertFalse(a.compareAndSet(this, m5, seven));
+            assertFalse(seven == a.get(this));
+            assertTrue(a.compareAndSet(this, m4, seven));
+            assertSame(seven, a.get(this));
+        }
+    }
 
-    // static class UnrelatedClass {
-    //     public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
-    //         obj.x = one;
-    //         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
-    //             AtomicReferenceFieldUpdater.newUpdater
-    //             (AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
-    //         assertSame(one, a.get(obj));
-    //         assertTrue(a.compareAndSet(obj, one, two));
-    //         assertSame(two, a.get(obj));
-    //     }
+    static class UnrelatedClass {
+        public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
+            obj.x = one;
+            AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+                AtomicReferenceFieldUpdater.newUpdater
+                (AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
+            assertSame(one, a.get(obj));
+            assertTrue(a.compareAndSet(obj, one, two));
+            assertSame(two, a.get(obj));
+        }
 
-    //     public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
-    //         try {
-    //             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
-    //                 AtomicReferenceFieldUpdater.newUpdater
-    //                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
-    //             throw new AssertionError("should throw");
-    //         } catch (RuntimeException success) {
-    //             assertNotNull(success.getCause());
-    //         }
-    //     }
-    // }
+        public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
+            try {
+                AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+                    AtomicReferenceFieldUpdater.newUpdater
+                    (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+                throw new AssertionError("should throw");
+            } catch (RuntimeException success) {
+                assertNotNull(success.getCause());
+            }
+        }
+    }
 
     static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
         return AtomicReferenceFieldUpdater.newUpdater
@@ -133,22 +132,20 @@
     /**
      * construction using private field from subclass throws RuntimeException
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testPrivateFieldInSubclass() {
-    //     AtomicReferenceFieldUpdaterTestSubclass s =
-    //         new AtomicReferenceFieldUpdaterTestSubclass();
-    //     s.checkPrivateAccess();
-    // }
+    public void testPrivateFieldInSubclass() {
+        AtomicReferenceFieldUpdaterTestSubclass s =
+            new AtomicReferenceFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
 
     /**
      * construction from unrelated class; package access is allowed,
      * private access is not
      */
-    // android-note: Removed because android doesn't restrict reflection access
-    // public void testUnrelatedClassAccess() {
-    //     new UnrelatedClass().checkPackageAccess(this);
-    //     new UnrelatedClass().checkPrivateAccess(this);
-    // }
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
 
     /**
      * get returns the last value set or assigned
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
index ca29579..3729bf3 100644
--- a/libart/src/main/java/dalvik/system/VMStack.java
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -30,15 +30,21 @@
      *
      * @return the requested class loader, or {@code null} if this is the
      *         bootstrap class loader.
+     * @deprecated Use {@code ClassLoader.getClassLoader(sun.reflect.Reflection.getCallerClass())}.
+     *         Note that that can return {@link BootClassLoader} on Android where the RI
+     *         would have returned null.
      */
     @FastNative
+    @Deprecated
     native public static ClassLoader getCallingClassLoader();
 
     /**
      * Returns the class of the caller's caller.
      *
      * @return the requested class, or {@code null}.
+     * @deprecated Use {@link sun.reflect.Reflection#getCallerClass()}.
      */
+    @Deprecated
     public static Class<?> getStackClass1() {
         return getStackClass2();
     }
diff --git a/libart/src/main/java/java/lang/StringFactory.java b/libart/src/main/java/java/lang/StringFactory.java
index 1866562..6ef664b 100644
--- a/libart/src/main/java/java/lang/StringFactory.java
+++ b/libart/src/main/java/java/lang/StringFactory.java
@@ -237,17 +237,10 @@
         } else {
             CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
             length = cb.length();
-            if (length > 0) {
-                // We could use cb.array() directly, but that would mean we'd have to trust
-                // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
-                // which would break String's immutability guarantee. It would also tend to
-                // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
-                // array. So we copy.
-                value = new char[length];
-                System.arraycopy(cb.array(), 0, value, 0, length);
-            } else {
-                value = EmptyArray.CHAR;
-            }
+            // The call to newStringFromChars below will copy length bytes out of value, so it does
+            // not matter that cb.array().length may be > cb.length() or that a Charset could keep a
+            // reference to the CharBuffer it returns and later mutate it.
+            value = cb.array();
         }
         return newStringFromChars(value, 0, length);
     }
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index 6301ff9..bc738b7 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -51,14 +51,16 @@
      */
     public static boolean access(String path, int mode) throws ErrnoException { return Libcore.os.access(path, mode); }
 
-    /** @hide */ public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
+    /** @hide */
+    public static InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return Libcore.os.android_getaddrinfo(node, hints, netId); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/bind.2.html">bind(2)</a>.
      */
     public static void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.bind(fd, address, port); }
 
-    /** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
+    /** @hide */
+    public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
@@ -99,7 +101,8 @@
      */
     public static void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.connect(fd, address, port); }
 
-    /** @hide */ public static void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.connect(fd, address); }
+    /** @hide */
+    public static void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.connect(fd, address); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/dup.2.html">dup(2)</a>.
@@ -136,9 +139,14 @@
      */
     public static void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException { Libcore.os.fchown(fd, uid, gid); }
 
-    /** @hide */ public static int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException, InterruptedIOException { return Libcore.os.fcntlFlock(fd, cmd, arg); }
-    /** @hide */ public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException { return Libcore.os.fcntlInt(fd, cmd, arg); }
-    /** @hide */ public static int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException { return Libcore.os.fcntlVoid(fd, cmd); }
+    /** @hide */
+    public static int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException, InterruptedIOException { return Libcore.os.fcntlFlock(fd, cmd, arg); }
+
+    /** @hide */
+    public static int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException { return Libcore.os.fcntlInt(fd, cmd, arg); }
+
+    /** @hide */
+    public static int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException { return Libcore.os.fcntlVoid(fd, cmd); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/fdatasync.2.html">fdatasync(2)</a>.
@@ -192,10 +200,12 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man3/getifaddrs.3.html">getifaddrs(3)</a>.
+     * @hide
      */
-    /** @hide */ public static StructIfaddrs[] getifaddrs() throws ErrnoException { return Libcore.os.getifaddrs(); }
+    public static StructIfaddrs[] getifaddrs() throws ErrnoException { return Libcore.os.getifaddrs(); }
 
-    /** @hide */ public static String getnameinfo(InetAddress address, int flags) throws GaiException { return Libcore.os.getnameinfo(address, flags); }
+    /** @hide */
+    public static String getnameinfo(InetAddress address, int flags) throws GaiException { return Libcore.os.getnameinfo(address, flags); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/getpeername.2.html">getpeername(2)</a>.
@@ -204,8 +214,9 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/getpgid.2.html">getpgid(2)</a>.
+     * @hide
      */
-    /** @hide */ public static int getpgid(int pid) throws ErrnoException { return Libcore.os.getpgid(pid); }
+    public static int getpgid(int pid) throws ErrnoException { return Libcore.os.getpgid(pid); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/getpid.2.html">getpid(2)</a>.
@@ -217,23 +228,37 @@
      */
     public static int getppid() { return Libcore.os.getppid(); }
 
-    /** @hide */ public static StructPasswd getpwnam(String name) throws ErrnoException { return Libcore.os.getpwnam(name); }
+    /** @hide */
+    public static StructPasswd getpwnam(String name) throws ErrnoException { return Libcore.os.getpwnam(name); }
 
-    /** @hide */ public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
+    /** @hide */
+    public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
 
-    /** @hide */ public static StructRlimit getrlimit(int resource) throws ErrnoException { return Libcore.os.getrlimit(resource); }
+    /** @hide */
+    public static StructRlimit getrlimit(int resource) throws ErrnoException { return Libcore.os.getrlimit(resource); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/getsockname.2.html">getsockname(2)</a>.
      */
     public static SocketAddress getsockname(FileDescriptor fd) throws ErrnoException { return Libcore.os.getsockname(fd); }
 
-    /** @hide */ public static int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptByte(fd, level, option); }
-    /** @hide */ public static InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInAddr(fd, level, option); }
-    /** @hide */ public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
-    /** @hide */ public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
-    /** @hide */ public static StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptTimeval(fd, level, option); }
-    /** @hide */ public static StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptUcred(fd, level, option); }
+    /** @hide */
+    public static int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptByte(fd, level, option); }
+
+    /** @hide */
+    public static InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInAddr(fd, level, option); }
+
+    /** @hide */
+    public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
+
+    /** @hide */
+    public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
+
+    /** @hide */
+    public static StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptTimeval(fd, level, option); }
+
+    /** @hide */
+    public static StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptUcred(fd, level, option); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/gettid.2.html">gettid(2)</a>.
@@ -265,10 +290,12 @@
      */
     public static InetAddress inet_pton(int family, String address) { return Libcore.os.inet_pton(family, address); }
 
-    /** @hide */ public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
+    /** @hide */
+    public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
 
 
-    /** @hide */ public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
+    /** @hide */
+    public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
         return Libcore.os.ioctlInt(fd, cmd, arg);
     }
 
@@ -362,7 +389,8 @@
      */
     public static FileDescriptor[] pipe() throws ErrnoException { return Libcore.os.pipe2(0); }
 
-    /** @hide */ public static FileDescriptor[] pipe2(int flags) throws ErrnoException { return Libcore.os.pipe2(flags); }
+    /** @hide */
+    public static FileDescriptor[] pipe2(int flags) throws ErrnoException { return Libcore.os.pipe2(flags); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/poll.2.html">poll(2)</a>.
@@ -420,8 +448,9 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man3/realpath.3.html">realpath(3)</a>.
+     * @hide
      */
-    /** @hide */ public static String realpath(String path) throws ErrnoException { return Libcore.os.realpath(path); }
+    public static String realpath(String path) throws ErrnoException { return Libcore.os.realpath(path); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/readv.2.html">readv(2)</a>.
@@ -472,8 +501,9 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
+     * @hide
      */
-    /** @hide */ public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
+    public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setegid.2.html">setegid(2)</a>.
@@ -497,36 +527,49 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setpgid.2.html">setpgid(2)</a>.
+     * @hide
      */
-    /** @hide */ public static void setpgid(int pid, int pgid) throws ErrnoException { Libcore.os.setpgid(pid, pgid); }
+    public static void setpgid(int pid, int pgid) throws ErrnoException { Libcore.os.setpgid(pid, pgid); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setregid.2.html">setregid(2)</a>.
+     * @hide
      */
-    /** @hide */ public static void setregid(int rgid, int egid) throws ErrnoException { Libcore.os.setregid(rgid, egid); }
+    public static void setregid(int rgid, int egid) throws ErrnoException { Libcore.os.setregid(rgid, egid); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setreuid.2.html">setreuid(2)</a>.
+     * @hide
      */
-    /** @hide */ public static void setreuid(int ruid, int euid) throws ErrnoException { Libcore.os.setreuid(ruid, euid); }
+    public static void setreuid(int ruid, int euid) throws ErrnoException { Libcore.os.setreuid(ruid, euid); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setsid.2.html">setsid(2)</a>.
      */
     public static int setsid() throws ErrnoException { return Libcore.os.setsid(); }
 
-    /** @hide */ public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
-    /** @hide */ public static void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { Libcore.os.setsockoptIfreq(fd, level, option, value); }
+    /** @hide */
+    public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
+
+    /** @hide */
+    public static void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { Libcore.os.setsockoptIfreq(fd, level, option, value); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">setsockopt(2)</a>.
      */
     public static void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptInt(fd, level, option, value); }
 
-    /** @hide */ public static void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptIpMreqn(fd, level, option, value); }
-    /** @hide */ public static void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { Libcore.os.setsockoptGroupReq(fd, level, option, value); }
-    /** @hide */ public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
-    /** @hide */ public static void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { Libcore.os.setsockoptTimeval(fd, level, option, value); }
+    /** @hide */
+    public static void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptIpMreqn(fd, level, option, value); }
+
+    /** @hide */
+    public static void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { Libcore.os.setsockoptGroupReq(fd, level, option, value); }
+
+    /** @hide */
+    public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
+
+    /** @hide */
+    public static void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { Libcore.os.setsockoptTimeval(fd, level, option, value); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setuid.2.html">setuid(2)</a>.
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1b8c2ff..7ede6a7 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -109,8 +109,10 @@
 
     public static final int AF_INET = placeholder();
     public static final int AF_INET6 = placeholder();
-    /** @hide */ public static final int AF_NETLINK = placeholder();
-    /** @hide */ public static final int AF_PACKET = placeholder();
+    /** @hide */
+    public static final int AF_NETLINK = placeholder();
+    /** @hide */
+    public static final int AF_PACKET = placeholder();
     public static final int AF_UNIX = placeholder();
     public static final int AF_UNSPEC = placeholder();
     public static final int AI_ADDRCONFIG = placeholder();
@@ -120,8 +122,10 @@
     public static final int AI_NUMERICSERV = placeholder();
     public static final int AI_PASSIVE = placeholder();
     public static final int AI_V4MAPPED = placeholder();
-    /** @hide */ public static final int ARPHRD_ETHER = placeholder();
-    /** @hide */ public static final int ARPHRD_LOOPBACK = placeholder();
+    /** @hide */
+    public static final int ARPHRD_ETHER = placeholder();
+    /** @hide */
+    public static final int ARPHRD_LOOPBACK = placeholder();
     public static final int CAP_AUDIT_CONTROL = placeholder();
     public static final int CAP_AUDIT_WRITE = placeholder();
     public static final int CAP_BLOCK_SUSPEND = placeholder();
@@ -221,7 +225,8 @@
     public static final int ENOLINK = placeholder();
     public static final int ENOMEM = placeholder();
     public static final int ENOMSG = placeholder();
-    /** @hide */ public static final int ENONET = placeholder();
+    /** @hide */
+    public static final int ENONET = placeholder();
     public static final int ENOPROTOOPT = placeholder();
     public static final int ENOSPC = placeholder();
     public static final int ENOSR = placeholder();
@@ -246,14 +251,19 @@
     public static final int ESPIPE = placeholder();
     public static final int ESRCH = placeholder();
     public static final int ESTALE = placeholder();
-    /** @hide */ public static final int ETH_P_ALL = placeholder();
-    /** @hide */ public static final int ETH_P_ARP = placeholder();
-    /** @hide */ public static final int ETH_P_IP = placeholder();
-    /** @hide */ public static final int ETH_P_IPV6 = placeholder();
+    /** @hide */
+    public static final int ETH_P_ALL = placeholder();
+    /** @hide */
+    public static final int ETH_P_ARP = placeholder();
+    /** @hide */
+    public static final int ETH_P_IP = placeholder();
+    /** @hide */
+    public static final int ETH_P_IPV6 = placeholder();
     public static final int ETIME = placeholder();
     public static final int ETIMEDOUT = placeholder();
     public static final int ETXTBSY = placeholder();
-    /** @hide */ public static final int EUSERS = placeholder();
+    /** @hide */
+    public static final int EUSERS = placeholder();
     // On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
     public static final int EXDEV = placeholder();
     public static final int EXIT_FAILURE = placeholder();
@@ -278,10 +288,14 @@
     public static final int F_SETOWN = placeholder();
     public static final int F_UNLCK = placeholder();
     public static final int F_WRLCK = placeholder();
-    /** @hide */ public static final int ICMP_ECHO = placeholder();
-    /** @hide */ public static final int ICMP_ECHOREPLY = placeholder();
-    /** @hide */ public static final int ICMP6_ECHO_REQUEST = placeholder();
-    /** @hide */ public static final int ICMP6_ECHO_REPLY = placeholder();
+    /** @hide */
+    public static final int ICMP_ECHO = placeholder();
+    /** @hide */
+    public static final int ICMP_ECHOREPLY = placeholder();
+    /** @hide */
+    public static final int ICMP6_ECHO_REQUEST = placeholder();
+    /** @hide */
+    public static final int ICMP6_ECHO_REPLY = placeholder();
     public static final int IFA_F_DADFAILED = placeholder();
     public static final int IFA_F_DEPRECATED = placeholder();
     public static final int IFA_F_HOMEADDRESS = placeholder();
@@ -327,16 +341,20 @@
     public static final int IPV6_TCLASS = placeholder();
     public static final int IPV6_UNICAST_HOPS = placeholder();
     public static final int IPV6_V6ONLY = placeholder();
-    /** @hide */ public static final int IP_MULTICAST_ALL = placeholder();
+    /** @hide */
+    public static final int IP_MULTICAST_ALL = placeholder();
     public static final int IP_MULTICAST_IF = placeholder();
     public static final int IP_MULTICAST_LOOP = placeholder();
     public static final int IP_MULTICAST_TTL = placeholder();
-    /** @hide */ public static final int IP_RECVTOS = placeholder();
+    /** @hide */
+    public static final int IP_RECVTOS = placeholder();
     public static final int IP_TOS = placeholder();
     public static final int IP_TTL = placeholder();
-    /** @hide */ public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
+    /** @hide */
+    public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
     public static final int MAP_FIXED = placeholder();
-    /** @hide */ public static final int MAP_POPULATE = placeholder();
+    /** @hide */
+    public static final int MAP_POPULATE = placeholder();
     public static final int MAP_PRIVATE = placeholder();
     public static final int MAP_SHARED = placeholder();
     public static final int MCAST_JOIN_GROUP = placeholder();
@@ -357,8 +375,15 @@
     public static final int MS_ASYNC = placeholder();
     public static final int MS_INVALIDATE = placeholder();
     public static final int MS_SYNC = placeholder();
-    /** @hide */ public static final int NETLINK_NETFILTER = placeholder();
-    /** @hide */ public static final int NETLINK_ROUTE = placeholder();
+    /** @hide */
+    public static final int NETLINK_NETFILTER = placeholder();
+    /** @hide */
+    public static final int NETLINK_ROUTE = placeholder();
+    /** 
+     * SELinux enforces that only system_server and netd may use this netlink socket type.
+     * @hide
+     */
+    public static final int NETLINK_INET_DIAG = placeholder();
     public static final int NI_DGRAM = placeholder();
     public static final int NI_NAMEREQD = placeholder();
     public static final int NI_NOFQDN = placeholder();
@@ -368,7 +393,8 @@
     public static final int O_APPEND = placeholder();
     public static final int O_CLOEXEC = placeholder();
     public static final int O_CREAT = placeholder();
-    /** @hide */ public static final int O_DIRECT = placeholder();
+    /** @hide */
+    public static final int O_DIRECT = placeholder();
     public static final int O_EXCL = placeholder();
     public static final int O_NOCTTY = placeholder();
     public static final int O_NOFOLLOW = placeholder();
@@ -389,8 +415,10 @@
     public static final int POLLRDNORM = placeholder();
     public static final int POLLWRBAND = placeholder();
     public static final int POLLWRNORM = placeholder();
-    /** @hide */ public static final int PR_CAP_AMBIENT = placeholder();
-    /** @hide */ public static final int PR_CAP_AMBIENT_RAISE = placeholder();
+    /** @hide */
+    public static final int PR_CAP_AMBIENT = placeholder();
+    /** @hide */
+    public static final int PR_CAP_AMBIENT_RAISE = placeholder();
     public static final int PR_GET_DUMPABLE = placeholder();
     public static final int PR_SET_DUMPABLE = placeholder();
     public static final int PR_SET_NO_NEW_PRIVS = placeholder();
@@ -399,25 +427,39 @@
     public static final int PROT_READ = placeholder();
     public static final int PROT_WRITE = placeholder();
     public static final int R_OK = placeholder();
-    /** @hide */ public static final int RLIMIT_NOFILE = placeholder();
+    /** @hide */
+    public static final int RLIMIT_NOFILE = placeholder();
     public static final int RT_SCOPE_HOST = placeholder();
     public static final int RT_SCOPE_LINK = placeholder();
     public static final int RT_SCOPE_NOWHERE = placeholder();
     public static final int RT_SCOPE_SITE = placeholder();
     public static final int RT_SCOPE_UNIVERSE = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV4_IFADDR = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV4_MROUTE = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV4_ROUTE = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV4_RULE = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV6_IFADDR = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV6_IFINFO = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV6_MROUTE = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV6_PREFIX = placeholder();
-    /** @hide */ public static final int RTMGRP_IPV6_ROUTE = placeholder();
-    /** @hide */ public static final int RTMGRP_LINK = placeholder();
-    /** @hide */ public static final int RTMGRP_NEIGH = placeholder();
-    /** @hide */ public static final int RTMGRP_NOTIFY = placeholder();
-    /** @hide */ public static final int RTMGRP_TC = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV4_IFADDR = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV4_MROUTE = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV4_ROUTE = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV4_RULE = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV6_IFADDR = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV6_IFINFO = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV6_MROUTE = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV6_PREFIX = placeholder();
+    /** @hide */
+    public static final int RTMGRP_IPV6_ROUTE = placeholder();
+    /** @hide */
+    public static final int RTMGRP_LINK = placeholder();
+    /** @hide */
+    public static final int RTMGRP_NEIGH = placeholder();
+    /** @hide */
+    public static final int RTMGRP_NOTIFY = placeholder();
+    /** @hide */
+    public static final int RTMGRP_TC = placeholder();
     public static final int SEEK_CUR = placeholder();
     public static final int SEEK_END = placeholder();
     public static final int SEEK_SET = placeholder();
@@ -469,7 +511,8 @@
     public static final int SO_BINDTODEVICE = placeholder();
     public static final int SO_BROADCAST = placeholder();
     public static final int SO_DEBUG = placeholder();
-    /** @hide */ public static final int SO_DOMAIN = placeholder();
+    /** @hide */
+    public static final int SO_DOMAIN = placeholder();
     public static final int SO_DONTROUTE = placeholder();
     public static final int SO_ERROR = placeholder();
     public static final int SO_KEEPALIVE = placeholder();
@@ -477,7 +520,8 @@
     public static final int SO_OOBINLINE = placeholder();
     public static final int SO_PASSCRED = placeholder();
     public static final int SO_PEERCRED = placeholder();
-    /** @hide */ public static final int SO_PROTOCOL = placeholder();
+    /** @hide */
+    public static final int SO_PROTOCOL = placeholder();
     public static final int SO_RCVBUF = placeholder();
     public static final int SO_RCVLOWAT = placeholder();
     public static final int SO_RCVTIMEO = placeholder();
@@ -486,9 +530,12 @@
     public static final int SO_SNDLOWAT = placeholder();
     public static final int SO_SNDTIMEO = placeholder();
     public static final int SO_TYPE = placeholder();
-    /** @hide */ public static final int SPLICE_F_MOVE = placeholder();
-    /** @hide */ public static final int SPLICE_F_NONBLOCK = placeholder();
-    /** @hide */ public static final int SPLICE_F_MORE = placeholder();
+    /** @hide */
+    public static final int SPLICE_F_MOVE = placeholder();
+    /** @hide */
+    public static final int SPLICE_F_NONBLOCK = placeholder();
+    /** @hide */
+    public static final int SPLICE_F_MORE = placeholder();
     public static final int STDERR_FILENO = placeholder();
     public static final int STDIN_FILENO = placeholder();
     public static final int STDOUT_FILENO = placeholder();
@@ -526,11 +573,16 @@
     public static final int S_IXUSR = placeholder();
     public static final int TCP_NODELAY = placeholder();
     public static final int TCP_USER_TIMEOUT = placeholder();
-    /** @hide */ public static final int TIOCOUTQ = placeholder();
-    /** @hide */ public static final int UDP_ENCAP = placeholder();
-    /** @hide */ public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
-    /** @hide */ public static final int UDP_ENCAP_ESPINUDP = placeholder();
-    /** @hide */ public static final int UNIX_PATH_MAX = placeholder();
+    /** @hide */
+    public static final int TIOCOUTQ = placeholder();
+    /** @hide */
+    public static final int UDP_ENCAP = placeholder();
+    /** @hide */
+    public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
+    /** @hide */
+    public static final int UDP_ENCAP_ESPINUDP = placeholder();
+    /** @hide */
+    public static final int UNIX_PATH_MAX = placeholder();
     public static final int WCONTINUED = placeholder();
     public static final int WEXITED = placeholder();
     public static final int WNOHANG = placeholder();
@@ -538,8 +590,10 @@
     public static final int WSTOPPED = placeholder();
     public static final int WUNTRACED = placeholder();
     public static final int W_OK = placeholder();
-    /** @hide */ public static final int XATTR_CREATE = placeholder();
-    /** @hide */ public static final int XATTR_REPLACE = placeholder();
+    /** @hide */
+    public static final int XATTR_CREATE = placeholder();
+    /** @hide */
+    public static final int XATTR_REPLACE = placeholder();
     public static final int X_OK = placeholder();
     public static final int _SC_2_CHAR_TERM = placeholder();
     public static final int _SC_2_C_BIND = placeholder();
diff --git a/luni/src/main/java/java/math/BigDecimal.java b/luni/src/main/java/java/math/BigDecimal.java
index d03b66f..6ba251b 100644
--- a/luni/src/main/java/java/math/BigDecimal.java
+++ b/luni/src/main/java/java/math/BigDecimal.java
@@ -2034,9 +2034,7 @@
         long newScale = scale;
 
         if (isZero()) {
-            // Preserve RI compatibility, so BigDecimal.equals (which checks
-            // value *and* scale) continues to work.
-            return this;
+            return new BigDecimal(BigInteger.ZERO, 0);
         }
         BigInteger strippedBI = getUnscaledValue();
         BigInteger[] quotAndRem;
diff --git a/luni/src/main/java/libcore/api/CorePlatformApi.java b/luni/src/main/java/libcore/api/CorePlatformApi.java
new file mode 100644
index 0000000..09837a0
--- /dev/null
+++ b/luni/src/main/java/libcore/api/CorePlatformApi.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.api;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is part of a contract provided by the "core" set of
+ * libraries to select parts of the Android software stack.
+ *
+ * <p>This annotation should only appear on either (a) classes that are hidden by <pre>@hide</pre>
+ * javadoc tags or equivalent annotations, or (b) members of such classes. It is for use with
+ * metalava's {@code --show-single-annotation} option and so must be applied at the class level and
+ * applied again each member that is to be made part of the API. Members that are not part of the
+ * API do not have to be explicitly hidden.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface CorePlatformApi {
+}
diff --git a/luni/src/main/java/libcore/api/IntraCoreApi.java b/luni/src/main/java/libcore/api/IntraCoreApi.java
new file mode 100644
index 0000000..87cfcff
--- /dev/null
+++ b/luni/src/main/java/libcore/api/IntraCoreApi.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.api;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is part of a contract within the "core" set of libraries, some of which may
+ * be mmodules.
+ *
+ * <p>This annotation should only appear on either (a) classes that are hidden by <pre>@hide</pre>
+ * javadoc tags or equivalent annotations, or (b) members of such classes. It is for use with
+ * metalava's {@code --show-single-annotation} option and so must be applied at the class level and
+ * applied again each member that is to be made part of the API. Members that are not part of the
+ * API do not have to be explicitly hidden.
+ *
+ * @hide
+ */
+@IntraCoreApi // @IntraCoreApi is itself part of the intra-core API
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface IntraCoreApi {
+}
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index 154ea68..45f4b29 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -16,9 +16,14 @@
 
 package libcore.icu;
 
+import android.icu.impl.ICUData;
+import android.icu.impl.ICUResourceBundle;
+import android.icu.text.NumberingSystem;
+import android.icu.util.UResourceBundle;
 import java.text.DateFormat;
 import java.util.HashMap;
 import java.util.Locale;
+import java.util.MissingResourceException;
 import libcore.util.Objects;
 
 /**
@@ -200,6 +205,9 @@
             throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
         }
 
+        // Libcore localizes pattern separator while ICU doesn't. http://b/112080617
+        initializePatternSeparator(localeData, locale);
+
         // Get the SHORT and MEDIUM 12- and 24-hour time format strings.
         localeData.timeFormat_hm = ICU.getBestDateTimePattern("hm", locale);
         localeData.timeFormat_Hm = ICU.getBestDateTimePattern("Hm", locale);
@@ -226,4 +234,45 @@
         }
         return localeData;
     }
+
+    // Libcore localizes pattern separator while ICU doesn't. http://b/112080617
+    private static void initializePatternSeparator(LocaleData localeData, Locale locale) {
+        NumberingSystem ns = NumberingSystem.getInstance(locale);
+        // A numbering system could be numeric or algorithmic. DecimalFormat can only use
+        // a numeric and decimal-based (radix == 10) system. Fallback to a Latin, a known numeric
+        // and decimal-based if the default numbering system isn't. All locales should have data
+        // for Latin numbering system after locale data fallback. See Numbering system section
+        // in Unicode Technical Standard #35 for more details.
+        String nsName = ns != null && ns.getRadix() == 10 && !ns.isAlgorithmic()
+            ? ns.getName() : "latn";
+        ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(
+            ICUData.ICU_BASE_NAME, locale);
+        String patternSeparator = null;
+        // The fallback of number format data isn't well-specified in the spec.
+        // But the separator can't be null / empty, and ICU uses Latin numbering system
+        // as fallback.
+        if (!"latn".equals(nsName)) {
+            try {
+                patternSeparator = rb.getStringWithFallback(
+                    "NumberElements/" + nsName +"/symbols/list");
+            } catch (MissingResourceException e) {
+                // Try Latin numbering system later
+            }
+        }
+
+        if (patternSeparator == null) {
+            try {
+                patternSeparator = rb.getStringWithFallback("NumberElements/latn/symbols/list");
+            } catch (MissingResourceException e) {
+                // Fallback to the default separator ';'.
+            }
+        }
+
+        if (patternSeparator == null || patternSeparator.isEmpty()) {
+            patternSeparator = ";";
+        }
+
+        // Pattern separator in libcore supports single java character only.
+        localeData.patternSeparator = patternSeparator.charAt(0);
+    }
 }
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index 9b1ebe9..ac10da6 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -65,16 +65,19 @@
 
     @Override public boolean access(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return os.access(path, mode);
     }
 
     @Override public void chmod(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.chmod(path, mode);
     }
 
     @Override public void chown(String path, int uid, int gid) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.chown(path, uid, gid);
     }
 
@@ -174,11 +177,14 @@
 
     @Override public void lchown(String path, int uid, int gid) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.lchown(path, uid, gid);
     }
 
     @Override public void link(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
         os.link(oldPath, newPath);
     }
 
@@ -189,21 +195,25 @@
 
     @Override public StructStat lstat(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return os.lstat(path);
     }
 
     @Override public void mkdir(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.mkdir(path, mode);
     }
 
     @Override public void mkfifo(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.mkfifo(path, mode);
     }
 
     @Override public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         if ((flags & O_ACCMODE) != O_RDONLY) {
             BlockGuard.getThreadPolicy().onWriteToDisk();
         }
@@ -256,11 +266,13 @@
 
     @Override public String readlink(String path) throws ErrnoException {
       BlockGuard.getThreadPolicy().onReadFromDisk();
+      BlockGuard.getVmPolicy().onPathAccess(path);
       return os.readlink(path);
     }
 
     @Override public String realpath(String path) throws ErrnoException {
       BlockGuard.getThreadPolicy().onReadFromDisk();
+      BlockGuard.getVmPolicy().onPathAccess(path);
       return os.realpath(path);
     }
 
@@ -281,11 +293,14 @@
 
     @Override public void remove(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.remove(path);
     }
 
     @Override public void rename(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
         os.rename(oldPath, newPath);
     }
 
@@ -325,16 +340,20 @@
 
     @Override public StructStat stat(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return os.stat(path);
     }
 
     @Override public StructStatVfs statvfs(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return os.statvfs(path);
     }
 
     @Override public void symlink(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
         os.symlink(oldPath, newPath);
     }
 
@@ -355,17 +374,20 @@
 
     @Override public void execv(String filename, String[] argv) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(filename);
         os.execv(filename, argv);
     }
 
     @Override public void execve(String filename, String[] argv, String[] envp)
             throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(filename);
         os.execve(filename, argv, envp);
     }
 
     @Override public byte[] getxattr(String path, String name) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return os.getxattr(path, name);
     }
 
@@ -378,12 +400,14 @@
 
     @Override public void removexattr(String path, String name) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.removexattr(path, name);
     }
 
     @Override public void setxattr(String path, String name, byte[] value, int flags)
             throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         os.setxattr(path, name, value, flags);
     }
 
@@ -395,6 +419,7 @@
 
     @Override public void unlink(String pathname) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(pathname);
         os.unlink(pathname);
     }
 
diff --git a/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java b/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
index 117c1f8..1413223 100644
--- a/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
+++ b/luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java
@@ -25,7 +25,6 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.URLEncoder;
 import java.net.URLStreamHandler;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
@@ -57,7 +56,7 @@
    * entry cannot be found under the exact name presented.
    */
   public URL getEntryUrlOrNull(String entryName) {
-    if (findEntryWithDirectoryFallback(jarFile, entryName) != null) {
+    if (jarFile.getEntry(entryName) != null) {
       try {
         // Encode the path to ensure that any special characters like # survive their trip through
         // the URL. Entry names must use / as the path separator.
@@ -89,19 +88,6 @@
     jarFile.close();
   }
 
-  /**
-   * Finds an entry with the specified name in the {@code jarFile}. If an exact match isn't found it
-   * will also try with "/" appended, if appropriate. This is to maintain compatibility with
-   * {@link sun.net.www.protocol.jar.Handler} and its treatment of directory entries.
-   */
-  static ZipEntry findEntryWithDirectoryFallback(JarFile jarFile, String entryName) {
-    ZipEntry entry = jarFile.getEntry(entryName);
-    if (entry == null && !entryName.endsWith("/") ) {
-      entry = jarFile.getEntry(entryName + "/");
-    }
-    return entry;
-  }
-
   private class ClassPathURLConnection extends JarURLConnection {
     // The JarFile instance can be shared across URLConnections and should not be closed when it is:
     //
@@ -139,8 +125,7 @@
     @Override
     public void connect() throws IOException {
       if (!connected) {
-        this.jarEntry = findEntryWithDirectoryFallback(ClassPathURLStreamHandler.this.jarFile,
-            getEntryName());
+        this.jarEntry = jarFile.getEntry(getEntryName());
         if (jarEntry == null) {
           throw new FileNotFoundException(
               "URL does not correspond to an entry in the zip file. URL=" + url
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index f141694..2e0ce9f 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -70,6 +70,11 @@
     public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
     public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
     public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); }
+    public void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId) { os.android_fdsan_exchange_owner_tag(fd, previousOwnerId, newOwnerId); }
+    public long android_fdsan_get_owner_tag(FileDescriptor fd) { return os.android_fdsan_get_owner_tag(fd); }
+    public String android_fdsan_get_tag_type(long tag) { return os.android_fdsan_get_tag_type(tag); }
+    public long android_fdsan_get_tag_value(long tag) { return os.android_fdsan_get_tag_value(tag); }
+
     public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.connect(fd, address, port); }
     public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.connect(fd, address); }
     public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException { return os.dup(oldFd); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index a950bf5..8c1e7cb 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -22,6 +22,9 @@
 import android.system.StructLinger;
 import android.system.StructPollfd;
 import android.system.StructTimeval;
+
+import libcore.util.ArrayUtils;
+
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -41,7 +44,6 @@
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 
 import static android.system.OsConstants.*;
@@ -227,9 +229,11 @@
     }
 
     /**
-     * Closes the supplied file descriptor and sends a signal to any threads are currently blocking.
-     * In order for the signal to be sent the blocked threads must have registered with
-     * the AsynchronousCloseMonitor before they entered the blocking operation.
+     * Closes the Unix file descriptor associated with the supplied file descriptor, resets the
+     * internal int to -1, and sends a signal to any threads are currently blocking. In order for
+     * the signal to be sent the blocked threads must have registered with the
+     * AsynchronousCloseMonitor before they entered the blocking operation. {@code fd} will be
+     * invalid after this call.
      *
      * <p>This method is a no-op if passed a {@code null} or already-closed file descriptor.
      */
@@ -237,15 +241,13 @@
         if (fd == null || !fd.valid()) {
             return;
         }
-        int intFd = fd.getInt$();
-        fd.setInt$(-1);
-        FileDescriptor oldFd = new FileDescriptor();
-        oldFd.setInt$(intFd);
+        // fd is invalid after we call release.
+        FileDescriptor oldFd = fd.release$();
         AsynchronousCloseMonitor.signalBlockedThreads(oldFd);
         try {
             Libcore.os.close(oldFd);
         } catch (ErrnoException errnoException) {
-            // TODO: are there any cases in which we should throw?
+            throw errnoException.rethrowAsIOException();
         }
     }
 
@@ -273,7 +275,9 @@
         }
         String detail = createMessageForException(fd, inetAddress, port, timeoutMs, cause);
         if (cause.errno == ETIMEDOUT) {
-            throw new SocketTimeoutException(detail, cause);
+            SocketTimeoutException e = new SocketTimeoutException(detail);
+            e.initCause(cause);
+            throw e;
         }
         throw new ConnectException(detail, cause);
     }
@@ -478,7 +482,7 @@
         } catch (ErrnoException errnoException) {
             try {
                 if (fd != null) {
-                    IoUtils.close(fd);
+                    closeAndSignalBlockedThreads(fd);
                 }
             } catch (IOException ignored) {
             }
@@ -493,7 +497,7 @@
      * Unix practice where you'd read until you got 0 bytes (and any future read would return -1).
      */
     public static int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws IOException {
-        Arrays.checkOffsetAndCount(bytes.length, byteOffset, byteCount);
+        ArrayUtils.throwsIfOutOfBounds(bytes.length, byteOffset, byteCount);
         if (byteCount == 0) {
             return 0;
         }
@@ -517,7 +521,7 @@
      * Unix it never just writes as many bytes as happens to be convenient.)
      */
     public static void write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws IOException {
-        Arrays.checkOffsetAndCount(bytes.length, byteOffset, byteCount);
+        ArrayUtils.throwsIfOutOfBounds(bytes.length, byteOffset, byteCount);
         if (byteCount == 0) {
             return;
         }
@@ -627,7 +631,9 @@
             if (isConnected && errnoException.errno == ECONNREFUSED) {
                 throw new PortUnreachableException("ICMP Port Unreachable", errnoException);
             } else if (errnoException.errno == EAGAIN) {
-                throw new SocketTimeoutException(errnoException);
+                SocketTimeoutException e = new SocketTimeoutException();
+                e.initCause(errnoException);
+                throw e;
             } else {
                 throw errnoException.rethrowAsSocketException();
             }
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index b01759d..46ea573 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -26,7 +26,9 @@
 import java.net.Socket;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.util.Objects;
 import java.util.Random;
+import libcore.util.NonNull;
 import static android.system.OsConstants.*;
 
 public final class IoUtils {
@@ -34,17 +36,116 @@
     }
 
     /**
+     * Acquires ownership of an integer file descriptor from a FileDescriptor.
+     *
+     * This method invalidates the FileDescriptor passed in.
+     *
+     * The important part of this function is that you are taking ownership of a resource that you
+     * must either clean up yourself, or hand off to some other object that does that for you.
+     *
+     * See bionic/include/android/fdsan.h for more details.
+     *
+     * @param fd FileDescriptor to take ownership from, must be non-null.
+     * @throws NullPointerException if fd is null
+     */
+    public static int acquireRawFd(@NonNull FileDescriptor fd) {
+        Objects.requireNonNull(fd);
+
+        FileDescriptor copy = fd.release$();
+        // Get the numeric Unix file descriptor. -1 means it is invalid; for example if
+        // {@link FileDescriptor#release$()} has already been called on the FileDescriptor.
+        int rawFd = copy.getInt$();
+        long previousOwnerId = copy.getOwnerId$();
+        if (rawFd != -1 && previousOwnerId != FileDescriptor.NO_OWNER) {
+          // Clear the file descriptor's owner ID, aborting if the previous value isn't as expected.
+          Libcore.os.android_fdsan_exchange_owner_tag(copy, previousOwnerId,
+                                                      FileDescriptor.NO_OWNER);
+        }
+        return rawFd;
+    }
+
+    private static boolean isParcelFileDescriptor(Object object) {
+        // We need to look up ParcelFileDescriptor dynamically, because there are cases where the
+        // framework classes will not be found on the classpath such as on-host development.
+        try {
+            Class<?> pfdClass = Class.forName("android.os.ParcelFileDescriptor");
+            if (pfdClass.isInstance(object)) {
+                return true;
+            }
+            return false;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+
+    private static long generateFdOwnerId(Object owner) {
+        if (owner == null) {
+            return 0;
+        }
+
+        // Type values from bionic's <android/fdsan.h>.
+        long tagType;
+        if (owner instanceof java.io.FileInputStream) {
+            tagType = 5;
+        } else if (owner instanceof java.io.FileOutputStream) {
+            tagType = 6;
+        } else if (owner instanceof java.io.RandomAccessFile) {
+            tagType = 7;
+        } else if (owner instanceof java.net.DatagramSocketImpl) {
+            tagType = 10;
+        } else if (owner instanceof java.net.SocketImpl) {
+            tagType = 11;
+        } else if (isParcelFileDescriptor(owner)) {
+            tagType = 8;
+        } else {
+            // Generic Java type.
+            tagType = 255;
+        }
+
+        // The owner ID is not required to be unique but should be stable and attempt to avoid
+        // collision with identifiers generated both here and in native code (which are simply the
+        // address of the owning object). identityHashCode(Object) meets these requirements.
+        long tagValue = System.identityHashCode(owner);
+        return tagType << 56 | tagValue;
+    }
+
+    /**
+     * Assigns ownership of an unowned FileDescriptor.
+     *
+     * Associates the supplied FileDescriptor and the underlying Unix file descriptor with an owner
+     * ID derived from the supplied {@code owner} object. If the FileDescriptor already has an
+     * associated owner an {@link IllegalStateException} will be thrown. If the underlying Unix
+     * file descriptor already has an associated owner, the process will abort.
+     *
+     * See bionic/include/android/fdsan.h for more details.
+     *
+     * @param fd FileDescriptor to take ownership from, must be non-null.
+     * @throws NullPointerException if fd or owner are null
+     * @throws IllegalStateException if fd is already owned
+     */
+    public static void setFdOwner(@NonNull FileDescriptor fd, @NonNull Object owner) {
+        Objects.requireNonNull(fd);
+        Objects.requireNonNull(owner);
+
+        long previousOwnerId = fd.getOwnerId$();
+        if (previousOwnerId != FileDescriptor.NO_OWNER) {
+            throw new IllegalStateException("Attempted to take ownership of already-owned " +
+                                            "FileDescriptor");
+        }
+
+        long ownerId = generateFdOwnerId(owner);
+        fd.setOwnerId$(ownerId);
+
+        // Set the file descriptor's owner ID, aborting if the previous value isn't as expected.
+        Libcore.os.android_fdsan_exchange_owner_tag(fd, previousOwnerId, ownerId);
+    }
+
+    /**
      * Calls close(2) on 'fd'. Also resets the internal int to -1. Does nothing if 'fd' is null
      * or invalid.
      */
     public static void close(FileDescriptor fd) throws IOException {
-        try {
-            if (fd != null && fd.valid()) {
-                Libcore.os.close(fd);
-            }
-        } catch (ErrnoException errnoException) {
-            throw errnoException.rethrowAsIOException();
-        }
+        IoBridge.closeAndSignalBlockedThreads(fd);
     }
 
     /**
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index 807e5a2..3766ac1 100644
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -60,7 +60,13 @@
             throws ErrnoException;
     public native void chmod(String path, int mode) throws ErrnoException;
     public native void chown(String path, int uid, int gid) throws ErrnoException;
+
     public native void close(FileDescriptor fd) throws ErrnoException;
+    public native void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId);
+    public native long android_fdsan_get_owner_tag(FileDescriptor fd);
+    public native String android_fdsan_get_tag_type(long tag);
+    public native long android_fdsan_get_tag_value(long tag);
+
     public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
     public native void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
     public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 61584b4..3f1c809 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -54,7 +54,13 @@
     public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
     public void chmod(String path, int mode) throws ErrnoException;
     public void chown(String path, int uid, int gid) throws ErrnoException;
+
     public void close(FileDescriptor fd) throws ErrnoException;
+    public void android_fdsan_exchange_owner_tag(FileDescriptor fd, long previousOwnerId, long newOwnerId);
+    public long android_fdsan_get_owner_tag(FileDescriptor fd);
+    public String android_fdsan_get_tag_type(long tag);
+    public long android_fdsan_get_tag_value(long tag);
+
     public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
     public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
     public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Streams.java b/luni/src/main/java/libcore/io/Streams.java
index 1f78edd..346bba0 100644
--- a/luni/src/main/java/libcore/io/Streams.java
+++ b/luni/src/main/java/libcore/io/Streams.java
@@ -16,6 +16,8 @@
 
 package libcore.io;
 
+import libcore.util.ArrayUtils;
+
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
@@ -23,7 +25,6 @@
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.StringWriter;
-import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicReference;
 
 public final class Streams {
@@ -76,7 +77,7 @@
         if (dst == null) {
             throw new NullPointerException("dst == null");
         }
-        Arrays.checkOffsetAndCount(dst.length, offset, byteCount);
+        ArrayUtils.throwsIfOutOfBounds(dst.length, offset, byteCount);
         while (byteCount > 0) {
             int bytesRead = in.read(dst, offset, byteCount);
             if (bytesRead < 0) {
diff --git a/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java b/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java
new file mode 100644
index 0000000..360d2035ce
--- /dev/null
+++ b/luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.mmodule.libart;
+
+import libcore.mmodule.simple.DemoSimpleClass;
+
+/**
+ * A class that provides:
+ * <ul>
+ * <li>A method within core-libart for the core-simple mmodule to depend on,
+ * and a method that depends on the core-simple mmodule thereby demonstrating a
+ * bi-directional, intra-module dependency.</li>
+ * <li>A "core platform API" method for use by higher-level code.</li>
+ * </ul>
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
+public class DemoLibartClass {
+
+    private DemoLibartClass() {}
+
+    /**
+     * A method that depends on the simple mmodule to work.
+     */
+    @libcore.api.IntraCoreApi
+    public static String intraCoreDependencyMethod() {
+        // Delegate to core-simple code to implement the method.
+        return DemoSimpleClass.simpleMethod();
+    }
+
+    /**
+     * A simple method that has no native or data file dependencies but is part of the intra-core
+     * mmodule API contract.
+     */
+    @libcore.api.IntraCoreApi
+    public static String simpleMethod() {
+        return "Hello World";
+    }
+
+    /**
+     * A core platform API method provided to higher-level code in the Android software stack.
+     */
+    @libcore.api.CorePlatformApi
+    public static String corePlatformApiMethod() {
+        return "Hello World";
+    }
+
+    /**
+     * A method that is public but not part of either the intra-core or core platform API
+     * contracts, i.e. it cannot be used from the rest of the platform or another core mmodule.
+     */
+    public static String hiddenMethod() {
+        return "Hello World";
+    }
+}
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 3ab4300..bd7c874 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -16,401 +16,73 @@
 
 package libcore.net;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 /**
  * Utilities for dealing with MIME types.
  * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap.
  */
 public final class MimeUtils {
+    private static final Pattern splitPattern = Pattern.compile("\\s+");
+
     private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<String, String>();
 
     private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
 
     static {
-        // The following table is based on /etc/mime.types data minus
-        // chemical/* MIME types and MIME types that don't map to any
-        // file extensions. We also exclude top-level domain names to
-        // deal with cases like:
-        //
-        // mail.google.com/a/google.com
-        //
-        // and "active" MIME types (due to potential security issues).
-
-        // Note that this list is _not_ in alphabetical order and must not be sorted.
-        // The "most popular" extension must come first, so that it's the one returned
-        // by guessExtensionFromMimeType.
-
-        add("application/andrew-inset", "ez");
-        add("application/dsptype", "tsp");
-        add("application/epub+zip", "epub");
-        add("application/hta", "hta");
-        add("application/mac-binhex40", "hqx");
-        add("application/mathematica", "nb");
-        add("application/msaccess", "mdb");
-        add("application/oda", "oda");
-        add("application/ogg", "ogx");
-        add("application/pdf", "pdf");
-        add("application/pgp-keys", "key");
-        add("application/pgp-signature", "pgp");
-        add("application/pics-rules", "prf");
-        add("application/pkix-cert", "cer");
-        add("application/rar", "rar");
-        add("application/rdf+xml", "rdf");
-        add("application/rss+xml", "rss");
-        add("application/zip", "zip");
-        add("application/vnd.android.package-archive", "apk");
-        add("application/vnd.cinderella", "cdy");
-        add("application/vnd.ms-pki.stl", "stl");
-        add("application/vnd.oasis.opendocument.database", "odb");
-        add("application/vnd.oasis.opendocument.formula", "odf");
-        add("application/vnd.oasis.opendocument.graphics", "odg");
-        add("application/vnd.oasis.opendocument.graphics-template", "otg");
-        add("application/vnd.oasis.opendocument.image", "odi");
-        add("application/vnd.oasis.opendocument.presentation", "odp");
-        add("application/vnd.oasis.opendocument.presentation-template", "otp");
-        add("application/vnd.oasis.opendocument.spreadsheet", "ods");
-        add("application/vnd.oasis.opendocument.spreadsheet-template", "ots");
-        add("application/vnd.oasis.opendocument.text", "odt");
-        add("application/vnd.oasis.opendocument.text-master", "odm");
-        add("application/vnd.oasis.opendocument.text-template", "ott");
-        add("application/vnd.oasis.opendocument.text-web", "oth");
-        add("application/vnd.google-earth.kml+xml", "kml");
-        add("application/vnd.google-earth.kmz", "kmz");
-        add("application/msword", "doc");
-        add("application/msword", "dot");
-        add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
-        add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx");
-        add("application/vnd.ms-excel", "xls");
-        add("application/vnd.ms-excel", "xlt");
-        add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx");
-        add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx");
-        add("application/vnd.ms-powerpoint", "ppt");
-        add("application/vnd.ms-powerpoint", "pot");
-        add("application/vnd.ms-powerpoint", "pps");
-        add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx");
-        add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx");
-        add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx");
-        add("application/vnd.rim.cod", "cod");
-        add("application/vnd.smaf", "mmf");
-        add("application/vnd.stardivision.calc", "sdc");
-        add("application/vnd.stardivision.draw", "sda");
-        add("application/vnd.stardivision.impress", "sdd");
-        add("application/vnd.stardivision.impress", "sdp");
-        add("application/vnd.stardivision.math", "smf");
-        add("application/vnd.stardivision.writer", "sdw");
-        add("application/vnd.stardivision.writer", "vor");
-        add("application/vnd.stardivision.writer-global", "sgl");
-        add("application/vnd.sun.xml.calc", "sxc");
-        add("application/vnd.sun.xml.calc.template", "stc");
-        add("application/vnd.sun.xml.draw", "sxd");
-        add("application/vnd.sun.xml.draw.template", "std");
-        add("application/vnd.sun.xml.impress", "sxi");
-        add("application/vnd.sun.xml.impress.template", "sti");
-        add("application/vnd.sun.xml.math", "sxm");
-        add("application/vnd.sun.xml.writer", "sxw");
-        add("application/vnd.sun.xml.writer.global", "sxg");
-        add("application/vnd.sun.xml.writer.template", "stw");
-        add("application/vnd.visio", "vsd");
-        add("application/vnd.youtube.yt", "yt");
-        add("application/x-abiword", "abw");
-        add("application/x-apple-diskimage", "dmg");
-        add("application/x-bcpio", "bcpio");
-        add("application/x-bittorrent", "torrent");
-        add("application/x-cdf", "cdf");
-        add("application/x-cdlink", "vcd");
-        add("application/x-chess-pgn", "pgn");
-        add("application/x-cpio", "cpio");
-        add("application/x-debian-package", "deb");
-        add("application/x-debian-package", "udeb");
-        add("application/x-director", "dcr");
-        add("application/x-director", "dir");
-        add("application/x-director", "dxr");
-        add("application/x-dms", "dms");
-        add("application/x-doom", "wad");
-        add("application/x-dvi", "dvi");
-        add("application/x-font", "pfa");
-        add("application/x-font", "pfb");
-        add("application/x-font", "gsf");
-        add("application/x-font", "pcf");
-        add("application/x-font", "pcf.Z");
-        add("application/x-freemind", "mm");
-        // application/futuresplash isn't IANA, so application/x-futuresplash should come first.
-        add("application/x-futuresplash", "spl");
-        add("application/futuresplash", "spl");
-        add("application/x-gnumeric", "gnumeric");
-        add("application/x-go-sgf", "sgf");
-        add("application/x-graphing-calculator", "gcf");
-        add("application/x-gtar", "tgz");
-        add("application/x-gtar", "gtar");
-        add("application/x-gtar", "taz");
-        add("application/x-hdf", "hdf");
-        add("application/x-hwp", "hwp"); // http://b/18788282.
-        add("application/x-ica", "ica");
-        add("application/x-internet-signup", "ins");
-        add("application/x-internet-signup", "isp");
-        add("application/x-iphone", "iii");
-        add("application/x-iso9660-image", "iso");
-        add("application/x-jmol", "jmz");
-        add("application/x-kchart", "chrt");
-        add("application/x-killustrator", "kil");
-        add("application/x-koan", "skp");
-        add("application/x-koan", "skd");
-        add("application/x-koan", "skt");
-        add("application/x-koan", "skm");
-        add("application/x-kpresenter", "kpr");
-        add("application/x-kpresenter", "kpt");
-        add("application/x-kspread", "ksp");
-        add("application/x-kword", "kwd");
-        add("application/x-kword", "kwt");
-        add("application/x-latex", "latex");
-        add("application/x-lha", "lha");
-        add("application/x-lzh", "lzh");
-        add("application/x-lzx", "lzx");
-        add("application/x-maker", "frm");
-        add("application/x-maker", "maker");
-        add("application/x-maker", "frame");
-        add("application/x-maker", "fb");
-        add("application/x-maker", "book");
-        add("application/x-maker", "fbdoc");
-        add("application/x-mif", "mif");
-        add("application/x-ms-wmd", "wmd");
-        add("application/x-ms-wmz", "wmz");
-        add("application/x-msi", "msi");
-        add("application/x-ns-proxy-autoconfig", "pac");
-        add("application/x-nwc", "nwc");
-        add("application/x-object", "o");
-        add("application/x-oz-application", "oza");
-        add("application/x-pem-file", "pem");
-        add("application/x-pkcs12", "p12");
-        add("application/x-pkcs12", "pfx");
-        add("application/x-pkcs7-certreqresp", "p7r");
-        add("application/x-pkcs7-crl", "crl");
-        add("application/x-quicktimeplayer", "qtl");
-        add("application/x-shar", "shar");
-        add("application/x-shockwave-flash", "swf");
-        add("application/x-stuffit", "sit");
-        add("application/x-sv4cpio", "sv4cpio");
-        add("application/x-sv4crc", "sv4crc");
-        add("application/x-tar", "tar");
-        add("application/x-texinfo", "texinfo");
-        add("application/x-texinfo", "texi");
-        add("application/x-troff", "t");
-        add("application/x-troff", "roff");
-        add("application/x-troff-man", "man");
-        add("application/x-ustar", "ustar");
-        add("application/x-wais-source", "src");
-        add("application/x-wingz", "wz");
-        add("application/x-webarchive", "webarchive");
-        add("application/x-webarchive-xml", "webarchivexml");
-        add("application/x-x509-ca-cert", "crt");
-        add("application/x-x509-user-cert", "crt");
-        add("application/x-x509-server-cert", "crt");
-        add("application/x-xcf", "xcf");
-        add("application/x-xfig", "fig");
-        add("application/xhtml+xml", "xhtml");
-        // Video mime types for 3GPP first so they'll be default for guessMimeTypeFromExtension
-        // See RFC 3839 for 3GPP and RFC 4393 for 3GPP2
-        add("video/3gpp", "3gpp");
-        add("video/3gpp", "3gp");
-        add("video/3gpp2", "3gpp2");
-        add("video/3gpp2", "3g2");
-        add("audio/3gpp", "3gpp");
-        add("audio/aac", "aac");
-        add("audio/aac-adts", "aac");
-        add("audio/amr", "amr");
-        add("audio/amr-wb", "awb");
-        add("audio/basic", "snd");
-        add("audio/flac", "flac");
-        add("application/x-flac", "flac");
-        add("audio/imelody", "imy");
-        add("audio/midi", "mid");
-        add("audio/midi", "midi");
-        add("audio/midi", "ota");
-        add("audio/midi", "kar");
-        add("audio/midi", "rtttl");
-        add("audio/midi", "xmf");
-        add("audio/mobile-xmf", "mxmf");
-        // add ".mp3" first so it will be the default for guessExtensionFromMimeType
-        add("audio/mpeg", "mp3");
-        add("audio/mpeg", "mpga");
-        add("audio/mpeg", "mpega");
-        add("audio/mpeg", "mp2");
-        add("audio/mpeg", "m4a");
-        add("audio/mpegurl", "m3u");
-        add("audio/ogg", "oga");
-        add("audio/ogg", "ogg");
-        add("audio/ogg", "spx");
-        add("audio/prs.sid", "sid");
-        add("audio/x-aiff", "aif");
-        add("audio/x-aiff", "aiff");
-        add("audio/x-aiff", "aifc");
-        add("audio/x-gsm", "gsm");
-        add("audio/x-matroska", "mka");
-        add("audio/x-mpegurl", "m3u");
-        add("audio/x-ms-wma", "wma");
-        add("audio/x-ms-wax", "wax");
-        add("audio/x-pn-realaudio", "ra");
-        add("audio/x-pn-realaudio", "rm");
-        add("audio/x-pn-realaudio", "ram");
-        add("audio/x-realaudio", "ra");
-        add("audio/x-scpls", "pls");
-        add("audio/x-sd2", "sd2");
-        add("audio/x-wav", "wav");
-        // image/bmp isn't IANA, so image/x-ms-bmp should come first.
-        add("image/x-ms-bmp", "bmp");
-        add("image/bmp", "bmp");
-        add("image/gif", "gif");
-        // image/ico isn't IANA, so image/x-icon should come first.
-        add("image/x-icon", "ico");
-        add("image/ico", "cur");
-        add("image/ico", "ico");
-        add("image/ief", "ief");
-        // add ".jpg" first so it will be the default for guessExtensionFromMimeType
-        add("image/jpeg", "jpg");
-        add("image/jpeg", "jpeg");
-        add("image/jpeg", "jpe");
-        add("image/pcx", "pcx");
-        add("image/png", "png");
-        add("image/svg+xml", "svg");
-        add("image/svg+xml", "svgz");
-        add("image/tiff", "tiff");
-        add("image/tiff", "tif");
-        add("image/vnd.djvu", "djvu");
-        add("image/vnd.djvu", "djv");
-        add("image/vnd.wap.wbmp", "wbmp");
-        add("image/webp", "webp");
-        add("image/x-adobe-dng", "dng");
-        add("image/x-canon-cr2", "cr2");
-        add("image/x-cmu-raster", "ras");
-        add("image/x-coreldraw", "cdr");
-        add("image/x-coreldrawpattern", "pat");
-        add("image/x-coreldrawtemplate", "cdt");
-        add("image/x-corelphotopaint", "cpt");
-        add("image/x-fuji-raf", "raf");
-        add("image/x-jg", "art");
-        add("image/x-jng", "jng");
-        add("image/x-nikon-nef", "nef");
-        add("image/x-nikon-nrw", "nrw");
-        add("image/x-olympus-orf", "orf");
-        add("image/x-panasonic-rw2", "rw2");
-        add("image/x-pentax-pef", "pef");
-        add("image/x-photoshop", "psd");
-        add("image/x-portable-anymap", "pnm");
-        add("image/x-portable-bitmap", "pbm");
-        add("image/x-portable-graymap", "pgm");
-        add("image/x-portable-pixmap", "ppm");
-        add("image/x-samsung-srw", "srw");
-        add("image/x-sony-arw", "arw");
-        add("image/x-rgb", "rgb");
-        add("image/x-xbitmap", "xbm");
-        add("image/x-xpixmap", "xpm");
-        add("image/x-xwindowdump", "xwd");
-        add("model/iges", "igs");
-        add("model/iges", "iges");
-        add("model/mesh", "msh");
-        add("model/mesh", "mesh");
-        add("model/mesh", "silo");
-        add("text/calendar", "ics");
-        add("text/calendar", "icz");
-        add("text/comma-separated-values", "csv");
-        add("text/css", "css");
-        add("text/html", "htm");
-        add("text/html", "html");
-        add("text/h323", "323");
-        add("text/iuls", "uls");
-        add("text/mathml", "mml");
-        // add ".txt" first so it will be the default for guessExtensionFromMimeType
-        add("text/plain", "txt");
-        add("text/plain", "asc");
-        add("text/plain", "text");
-        add("text/plain", "diff");
-        add("text/plain", "po");     // reserve "pot" for vnd.ms-powerpoint
-        add("text/richtext", "rtx");
-        add("text/rtf", "rtf");
-        add("text/text", "phps");
-        add("text/tab-separated-values", "tsv");
-        add("text/xml", "xml");
-        add("text/x-bibtex", "bib");
-        add("text/x-boo", "boo");
-        add("text/x-c++hdr", "hpp");
-        add("text/x-c++hdr", "h++");
-        add("text/x-c++hdr", "hxx");
-        add("text/x-c++hdr", "hh");
-        add("text/x-c++src", "cpp");
-        add("text/x-c++src", "c++");
-        add("text/x-c++src", "cc");
-        add("text/x-c++src", "cxx");
-        add("text/x-chdr", "h");
-        add("text/x-component", "htc");
-        add("text/x-csh", "csh");
-        add("text/x-csrc", "c");
-        add("text/x-dsrc", "d");
-        add("text/x-haskell", "hs");
-        add("text/x-java", "java");
-        add("text/x-literate-haskell", "lhs");
-        add("text/x-moc", "moc");
-        add("text/x-pascal", "p");
-        add("text/x-pascal", "pas");
-        add("text/x-pcs-gcd", "gcd");
-        add("text/x-setext", "etx");
-        add("text/x-tcl", "tcl");
-        add("text/x-tex", "tex");
-        add("text/x-tex", "ltx");
-        add("text/x-tex", "sty");
-        add("text/x-tex", "cls");
-        add("text/x-vcalendar", "vcs");
-        add("text/x-vcard", "vcf");
-        add("video/avi", "avi");
-        add("video/dl", "dl");
-        add("video/dv", "dif");
-        add("video/dv", "dv");
-        add("video/fli", "fli");
-        add("video/m4v", "m4v");
-        add("video/mp2ts", "ts");
-        add("video/mpeg", "mpeg");
-        add("video/mpeg", "mpg");
-        add("video/mpeg", "mpe");
-        add("video/mp4", "mp4");
-        add("video/mpeg", "VOB");
-        add("video/ogg", "ogv");
-        add("video/quicktime", "qt");
-        add("video/quicktime", "mov");
-        add("video/vnd.mpegurl", "mxu");
-        add("video/webm", "webm");
-        add("video/x-la-asf", "lsf");
-        add("video/x-la-asf", "lsx");
-        add("video/x-matroska", "mkv");
-        add("video/x-mng", "mng");
-        add("video/x-ms-asf", "asf");
-        add("video/x-ms-asf", "asx");
-        add("video/x-ms-wm", "wm");
-        add("video/x-ms-wmv", "wmv");
-        add("video/x-ms-wmx", "wmx");
-        add("video/x-ms-wvx", "wvx");
-        add("video/x-sgi-movie", "movie");
-        add("video/x-webex", "wrf");
-        add("x-conference/x-cooltalk", "ice");
-        add("x-epoc/x-sisx-app", "sisx");
+        parseTypes("mime.types");
+        parseTypes("android.mime.types");
     }
 
-    private static void add(String mimeType, String extension) {
-        // If we have an existing x -> y mapping, we do not want to
-        // override it with another mapping x -> y2.
-        // If a mime type maps to several extensions
-        // the first extension added is considered the most popular
-        // so we do not want to overwrite it later.
-        if (!mimeTypeToExtensionMap.containsKey(mimeType)) {
-            mimeTypeToExtensionMap.put(mimeType, extension);
-        }
-        if (!extensionToMimeTypeMap.containsKey(extension)) {
-            extensionToMimeTypeMap.put(extension, mimeType);
-        }
-    }
+    private static void parseTypes(String resource) {
+        try (BufferedReader r = new BufferedReader(
+                new InputStreamReader(MimeUtils.class.getResourceAsStream(resource)))) {
+            String line;
+            while ((line = r.readLine()) != null) {
+                int commentPos = line.indexOf('#');
+                if (commentPos >= 0) {
+                    line = line.substring(0, commentPos);
+                }
+                line = line.trim();
+                if (line.equals("")) {
+                    continue;
+                }
 
-    private MimeUtils() {
+                final String[] split = splitPattern.split(line);
+                final String mimeType = split[0];
+                for (int i = 1; i < split.length; i++) {
+                    String extension = split[i].toLowerCase(Locale.US);
+
+                    // Normally the first MIME type definition wins, and the
+                    // last extension definition wins. However, a file can
+                    // override a MIME type definition by adding the "!" suffix
+                    // to an extension.
+
+                    if (extension.endsWith("!")) {
+                        extension = extension.substring(0, extension.length() - 1);
+
+                        // Overriding MIME definition wins
+                        mimeTypeToExtensionMap.put(mimeType, extension);
+                    } else {
+                        // First MIME definition wins
+                        if (!mimeTypeToExtensionMap.containsKey(mimeType)) {
+                            mimeTypeToExtensionMap.put(mimeType, extension);
+                        }
+                    }
+
+                    // Last extension definition wins
+                    extensionToMimeTypeMap.put(extension, mimeType);
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to parse " + resource, e);
+        }
     }
 
     /**
diff --git a/luni/src/main/java/libcore/net/UriCodec.java b/luni/src/main/java/libcore/net/UriCodec.java
deleted file mode 100644
index 240e910..0000000
--- a/luni/src/main/java/libcore/net/UriCodec.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package libcore.net;
-
-import java.io.ByteArrayOutputStream;
-import java.net.URISyntaxException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Encodes and decodes “application/x-www-form-urlencoded” content.
- *
- * Subclasses define “isRetained”, which decides which chars need to be escaped and which don’t.
- * Output is encoded as UTF-8 by default. I.e, each character (or surrogate pair) is converted to
- * its equivalent UTF-8 encoded byte sequence, which is then converted to it’s escaped form.
- * e.g a 4 byte sequence might look like” %c6%ef%e0%e8”
- */
-public abstract class UriCodec {
-    /**
-     * Returns true iff. ‘c’ does not need to be escaped.
-     * 'a’ - ‘z’ , ‘A’ - ‘Z’ and ‘0’ - ‘9’ are always considered valid (i.e, don’t need to be
-     * escaped. This set is referred to as the ``whitelist''.
-     */
-    protected abstract boolean isRetained(char c);
-
-    private static boolean isWhitelisted(char c) {
-        return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9');
-    }
-
-    private boolean isWhitelistedOrRetained(char c) {
-        return isWhitelisted(c) || isRetained(c);
-    }
-
-    /**
-     * Throw URISyntaxException if any of the characters in the range [start, end) are not valid
-     * according to this codec.
-     *  - If a char is in the whitelist or retained, it is valid both escaped and unescaped.
-     *  - All escaped octets appearing in the input are structurally valid hex, i.e convertible to
-     *  decimals.
-     *
-     * On success, the substring [start, end) is returned.
-     * {@code name} is not used, except to generate debugging info.
-     */
-    public final String validate(String uri, int start, int end, String name)
-            throws URISyntaxException {
-        int i = start;
-        while (i < end) {
-            char c = uri.charAt(i++);
-            if (isWhitelistedOrRetained(c)) {
-                continue;
-            }
-            // c is either '%' or character not allowed in a uri.
-            if (c != '%') {
-                throw unexpectedCharacterException(uri, name, c, i - 1);
-            }
-            // Expect two characters representing a number in hex.
-            for (int j = 0; j < 2; j++) {
-                c = getNextCharacter(uri, i++, end, name);
-                if (hexCharToValue(c) < 0) {
-                    throw unexpectedCharacterException(uri, name, c, i - 1);
-                }
-            }
-        }
-        return uri.substring(start, end);
-    }
-
-    /**
-     * Interprets a char as hex digits, returning a number from -1 (invalid char) to 15 ('f').
-     */
-    private static int hexCharToValue(char c) {
-        if('0' <= c && c <= '9') {
-            return c - '0';
-        }
-        if ('a' <= c && c <= 'f') {
-            return 10 + c - 'a';
-        }
-        if ('A' <= c && c <= 'F') {
-            return 10 + c - 'A';
-        }
-        return -1;
-    }
-
-    private static URISyntaxException unexpectedCharacterException(
-            String uri, String name, char unexpected, int index) {
-        String nameString = (name == null) ? "" :  " in [" + name + "]";
-        return new URISyntaxException(
-                uri, "Unexpected character" + nameString + ": " + unexpected, index);
-    }
-
-    private static char getNextCharacter(String uri, int index, int end, String name)
-             throws URISyntaxException {
-        if (index >= end) {
-            String nameString = (name == null) ? "" :  " in [" + name + "]";
-            throw new URISyntaxException(
-                    uri, "Unexpected end of string" + nameString, index);
-        }
-        return uri.charAt(index);
-    }
-
-    /**
-     * Throws {@link URISyntaxException} if any character in {@code uri} is neither whitelisted nor
-     * in {@code legal}.
-     */
-    public static void validateSimple(String uri, String legal) throws URISyntaxException {
-        for (int i = 0; i < uri.length(); i++) {
-            char c = uri.charAt(i);
-            if (!isWhitelisted(c) && legal.indexOf(c) < 0) {
-                throw unexpectedCharacterException(uri, null /* name */, c, i);
-            }
-        }
-    }
-
-    /**
-     * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
-     *
-     * @throws IllegalArgumentException if the encoder is unable to encode a sequence of bytes.
-     */
-    public final String encode(String s, Charset charset) {
-        StringBuilder builder = new StringBuilder(s.length());
-        appendEncoded(builder, s, charset, false);
-        return builder.toString();
-    }
-
-    /**
-     * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
-     *
-     * Encoded output is appended to {@code builder}. This uses the default output encoding (UTF-8).
-     */
-    public final void appendEncoded(StringBuilder builder, String s) {
-        appendEncoded(builder, s, StandardCharsets.UTF_8, false);
-    }
-
-    /**
-     * Encodes the string {@code s} as per the rules of this encoder (see class level comment).
-     *
-     * Encoded output is appended to {@code builder}. This uses the default output encoding (UTF-8).
-     * This method must produce partially encoded output. What this means is that if encoded octets
-     * appear in the input string, they are passed through unmodified, instead of being double
-     * escaped. Consider a decoder operating on the global whitelist dealing with a string
-     * “foo%25bar”. With this method, the output will be “foo%25bar”, but with appendEncoded, it
-     * will be double encoded into “foo%2525bar”.
-     */
-    public final void appendPartiallyEncoded(StringBuilder builder, String s) {
-        appendEncoded(builder, s, StandardCharsets.UTF_8, true);
-    }
-
-    private void appendEncoded(
-            StringBuilder builder, String s, Charset charset, boolean partiallyEncoded) {
-        CharsetEncoder encoder = charset.newEncoder()
-                .onMalformedInput(CodingErrorAction.REPORT)
-                .onUnmappableCharacter(CodingErrorAction.REPORT);
-        CharBuffer cBuffer = CharBuffer.allocate(s.length());
-        for (int i = 0; i < s.length(); i++) {
-            char c = s.charAt(i);
-            if (c == '%' && partiallyEncoded) {
-                // In case there are characters waiting to be encoded.
-                flushEncodingCharBuffer(builder, encoder, cBuffer);
-                builder.append('%');
-                continue;
-            }
-
-            if (c == ' ' && isRetained(' ')) {
-                flushEncodingCharBuffer(builder, encoder, cBuffer);
-                builder.append('+');
-                continue;
-            }
-
-            if (isWhitelistedOrRetained(c)) {
-                flushEncodingCharBuffer(builder, encoder, cBuffer);
-                builder.append(c);
-                continue;
-            }
-
-            // Put the character in the queue for encoding.
-            cBuffer.put(c);
-        }
-        flushEncodingCharBuffer(builder, encoder, cBuffer);
-    }
-
-    private static void flushEncodingCharBuffer(
-            StringBuilder builder,
-            CharsetEncoder encoder,
-            CharBuffer cBuffer) {
-        if (cBuffer.position() == 0) {
-            return;
-        }
-        // We are reading from the buffer now.
-        cBuffer.flip();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(
-                cBuffer.remaining() * (int) Math.ceil(encoder.maxBytesPerChar()));
-        byteBuffer.position(0);
-        CoderResult result = encoder.encode(cBuffer, byteBuffer, true /* endOfInput */);
-        // According to the {@code CharsetEncoder#encode} spec, the method returns underflow
-        // and leaves an empty output when all bytes were processed correctly.
-        if (result != CoderResult.UNDERFLOW) {
-            throw new IllegalArgumentException(
-                    "Error encoding, unexpected result ["
-                            + result.toString()
-                            + "] using encoder for ["
-                            + encoder.charset().name()
-                            + "]");
-        }
-        if (cBuffer.hasRemaining()) {
-            throw new IllegalArgumentException(
-                    "Encoder for [" + encoder.charset().name() + "] failed with underflow with "
-                            + "remaining input [" + cBuffer + "]");
-        }
-        // Need to flush in case the encoder saves internal state.
-        encoder.flush(byteBuffer);
-        if (result != CoderResult.UNDERFLOW) {
-            throw new IllegalArgumentException(
-                    "Error encoding, unexpected result ["
-                            + result.toString()
-                            + "] flushing encoder for ["
-                            + encoder.charset().name()
-                            + "]");
-        }
-        encoder.reset();
-
-        byteBuffer.flip();
-        // Write the encoded bytes.
-        while(byteBuffer.hasRemaining()) {
-            byte b = byteBuffer.get();
-            builder.append('%');
-            builder.append(intToHexDigit((b & 0xf0) >>> 4));
-            builder.append(intToHexDigit(b & 0x0f));
-
-        }
-        // Use the character buffer to write again.
-        cBuffer.flip();
-        cBuffer.limit(cBuffer.capacity());
-    }
-
-    private static char intToHexDigit(int b) {
-        if (b < 10) {
-            return (char) ('0' + b);
-        } else {
-            return (char) ('A' + b - 10);
-        }
-    }
-
-    /**
-     * Decode a string according to the rules of this decoder.
-     *
-     * - if {@code convertPlus == true} all ‘+’ chars in the decoded output are converted to ‘ ‘
-     *   (white space)
-     * - if {@code throwOnFailure == true}, an {@link IllegalArgumentException} is thrown for
-     *   invalid inputs. Else, U+FFFd is emitted to the output in place of invalid input octets.
-     */
-    public static String decode(
-            String s, boolean convertPlus, Charset charset, boolean throwOnFailure) {
-        StringBuilder builder = new StringBuilder(s.length());
-        appendDecoded(builder, s, convertPlus, charset, throwOnFailure);
-        return builder.toString();
-    }
-
-    /**
-     * Character to be output when there's an error decoding an input.
-     */
-    private static final char INVALID_INPUT_CHARACTER = '\ufffd';
-
-    private static void appendDecoded(
-            StringBuilder builder,
-            String s,
-            boolean convertPlus,
-            Charset charset,
-            boolean throwOnFailure) {
-        CharsetDecoder decoder = charset.newDecoder()
-                .onMalformedInput(CodingErrorAction.REPLACE)
-                .replaceWith("\ufffd")
-                .onUnmappableCharacter(CodingErrorAction.REPORT);
-        // Holds the bytes corresponding to the escaped chars being read (empty if the last char
-        // wasn't a escaped char).
-        ByteBuffer byteBuffer = ByteBuffer.allocate(s.length());
-        int i = 0;
-        while (i < s.length()) {
-            char c = s.charAt(i);
-            i++;
-            switch (c) {
-                case '+':
-                    flushDecodingByteAccumulator(
-                            builder, decoder, byteBuffer, throwOnFailure);
-                    builder.append(convertPlus ? ' ' : '+');
-                    break;
-                case '%':
-                    // Expect two characters representing a number in hex.
-                    byte hexValue = 0;
-                    for (int j = 0; j < 2; j++) {
-                        try {
-                            c = getNextCharacter(s, i, s.length(), null /* name */);
-                        } catch (URISyntaxException e) {
-                            // Unexpected end of input.
-                            if (throwOnFailure) {
-                                throw new IllegalArgumentException(e);
-                            } else {
-                                flushDecodingByteAccumulator(
-                                        builder, decoder, byteBuffer, throwOnFailure);
-                                builder.append(INVALID_INPUT_CHARACTER);
-                                return;
-                            }
-                        }
-                        i++;
-                        int newDigit = hexCharToValue(c);
-                        if (newDigit < 0) {
-                            if (throwOnFailure) {
-                                throw new IllegalArgumentException(
-                                        unexpectedCharacterException(s, null /* name */, c, i - 1));
-                            } else {
-                                flushDecodingByteAccumulator(
-                                        builder, decoder, byteBuffer, throwOnFailure);
-                                builder.append(INVALID_INPUT_CHARACTER);
-                                break;
-                            }
-                        }
-                        hexValue = (byte) (hexValue * 0x10 + newDigit);
-                    }
-                    byteBuffer.put(hexValue);
-                    break;
-                default:
-                    flushDecodingByteAccumulator(builder, decoder, byteBuffer, throwOnFailure);
-                    builder.append(c);
-            }
-        }
-        flushDecodingByteAccumulator(builder, decoder, byteBuffer, throwOnFailure);
-    }
-
-    private static void flushDecodingByteAccumulator(
-            StringBuilder builder,
-            CharsetDecoder decoder,
-            ByteBuffer byteBuffer,
-            boolean throwOnFailure) {
-        if (byteBuffer.position() == 0) {
-            return;
-        }
-        byteBuffer.flip();
-        try {
-            builder.append(decoder.decode(byteBuffer));
-        } catch (CharacterCodingException e) {
-            if (throwOnFailure) {
-                throw new IllegalArgumentException(e);
-            } else {
-                builder.append(INVALID_INPUT_CHARACTER);
-            }
-        } finally {
-            // Use the byte buffer to write again.
-            byteBuffer.flip();
-            byteBuffer.limit(byteBuffer.capacity());
-        }
-    }
-
-    /**
-     * Equivalent to {@code decode(s, false, UTF_8, true)}
-     */
-    public static String decode(String s) {
-        return decode(
-                s, false /* convertPlus */, StandardCharsets.UTF_8, true /* throwOnFailure */);
-    }
-}
\ No newline at end of file
diff --git a/luni/src/main/java/libcore/net/android.mime.types b/luni/src/main/java/libcore/net/android.mime.types
new file mode 100644
index 0000000..0413051
--- /dev/null
+++ b/luni/src/main/java/libcore/net/android.mime.types
@@ -0,0 +1,93 @@
+
+###############################################################################
+#
+#  Android-specific MIME type mappings
+#
+#  MIME types that Android has manually added or historically chosen to
+#  override, and which take precidence over any upstream mime.types.
+#
+###############################################################################
+
+application/epub+zip epub
+application/pkix-cert cer
+application/rss+xml rss
+application/vnd.apple.mpegurl m3u8
+application/vnd.ms-pki.stl stl
+application/vnd.ms-powerpoint pot
+application/vnd.ms-wpl wpl
+application/vnd.stardivision.impress sdp
+application/vnd.stardivision.writer vor
+application/vnd.youtube.yt yt
+application/x-android-drm-fl fl
+application/x-flac flac
+application/x-font pcf
+application/x-mpegurl m3u m3u8
+application/x-pem-file pem
+application/x-pkcs12 p12 pfx
+application/x-webarchive webarchive
+application/x-webarchive-xml webarchivexml
+application/x-x509-server-cert crt
+application/x-x509-user-cert crt
+
+audio/3gpp 3gpp
+audio/aac-adts aac
+audio/imelody imy
+audio/midi ota rtttl xmf
+audio/mobile-xmf mxmf
+audio/mp4 m4a
+audio/mpegurl m3u
+audio/sp-midi smf
+audio/x-matroska mka
+audio/x-pn-realaudio ra
+
+image/bmp bmp
+image/heic heic
+image/heic-sequence heics
+image/heif heif hif
+image/heif-sequence heifs
+image/ico cur
+image/webp webp
+image/x-adobe-dng dng
+image/x-fuji-raf raf
+image/x-icon ico
+image/x-nikon-nrw nrw
+image/x-panasonic-rw2 rw2
+image/x-pentax-pef pef
+image/x-samsung-srw srw
+image/x-sony-arw arw
+
+text/comma-separated-values csv
+text/plain diff po
+text/rtf rtf
+text/text phps
+text/xml xml
+text/x-vcard vcf
+
+video/3gpp2 3gpp2 3g2
+video/3gpp 3gpp
+video/avi avi
+video/m4v m4v
+video/mp2p mpeg
+video/mp2ts ts
+video/x-webex wrf
+
+# Special cases where Android has a strong opinion about mappings, so we
+# define them very last and use "!" to ensure that we force the mapping
+# in both directions.
+application/pgp-signature pgp!
+application/x-x509-ca-cert crt!
+audio/aac aac!
+audio/basic snd!
+audio/flac flac!
+audio/midi rtx!
+audio/mpeg mp3! m4a
+audio/x-mpegurl m3u8! m3u!
+image/jpeg jpg!
+image/x-ms-bmp bmp!
+text/plain txt!
+text/x-c++hdr hpp!
+text/x-c++src cpp!
+video/3gpp 3gpp!
+video/mpeg mpeg!
+video/quicktime mov!
+video/x-matroska mkv!
diff --git a/luni/src/main/java/libcore/net/mime.types b/luni/src/main/java/libcore/net/mime.types
new file mode 100644
index 0000000..dfa7a42
--- /dev/null
+++ b/luni/src/main/java/libcore/net/mime.types
@@ -0,0 +1,844 @@
+###############################################################################
+#
+#  MIME media types and the extensions that represent them.
+#
+#  The format of this file is a media type on the left and zero or more
+#  filename extensions on the right.  Programs using this file will map
+#  files ending with those extensions to the associated type.
+#
+#  This file is part of the "mime-support" package.  Please report a bug using
+#  the "reportbug" command of the "reportbug" package if you would like new
+#  types or extensions to be added.
+#
+#  The reason that all types are managed by the mime-support package instead
+#  allowing individual packages to install types in much the same way as they
+#  add entries in to the mailcap file is so these types can be referenced by
+#  other programs (such as a web server) even if the specific support package
+#  for that type is not installed.
+#
+#  Users can add their own types if they wish by creating a ".mime.types"
+#  file in their home directory.  Definitions included there will take
+#  precedence over those listed here.
+#
+###############################################################################
+
+
+application/activemessage
+application/andrew-inset			ez
+application/annodex				anx
+application/applefile
+application/atom+xml				atom
+application/atomcat+xml				atomcat
+application/atomicmail
+application/atomserv+xml			atomsrv
+application/batch-SMTP
+application/bbolin				lin
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cu-seeme				cu
+application/cybercash
+application/davmount+xml			davmount
+application/dca-rft
+application/dec-dx
+application/dicom				dcm
+application/docbook+xml
+application/dsptype				tsp
+application/dvcs
+application/ecmascript				es
+application/edi-consent
+application/edi-x12
+application/edifact
+application/epub+zip				epub
+application/eshop
+application/font-sfnt				otf ttf
+application/font-tdpfr				pfr
+application/font-woff				woff
+application/futuresplash			spl
+application/ghostview
+application/gzip				gz
+application/hta					hta
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/java-archive			jar
+application/java-serialized-object		ser
+application/java-vm				class
+application/javascript				js
+application/json				json
+application/m3g					m3g
+application/mac-binhex40			hqx
+application/mac-compactpro			cpt
+application/macwriteii
+application/marc
+application/mathematica				nb nbp
+application/mbox				mbox
+application/ms-tnef
+application/msaccess				mdb
+application/msword				doc dot
+application/mxf					mxf
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream			bin deploy msu msp
+application/oda					oda
+application/oebps-package+xml			opf
+application/ogg					ogx
+application/onenote				one onetoc2 onetmp onepkg
+application/parityfec
+application/pdf					pdf
+application/pgp-encrypted			pgp
+application/pgp-keys				key
+application/pgp-signature			sig
+application/pics-rules				prf
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript				ps ai eps epsi epsf eps2 eps3
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/rar					rar
+application/rdf+xml				rdf
+application/remote-printing
+application/riscos
+application/rtf					rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/sla					stl
+application/slate
+application/smil+xml				smi smil
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/x400-bp
+application/xhtml+xml				xhtml xht
+application/xml					xml xsd
+application/xml-dtd
+application/xml-external-parsed-entity
+application/xslt+xml				xsl xslt
+application/xspf+xml				xspf
+application/zip					zip
+application/vnd.3M.Post-it-Notes
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.android.package-archive						apk
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.bmi
+application/vnd.businessobjects
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.cinderella							cdy
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.ctc-posml
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.cybank
+application/vnd.debian.binary-package						deb ddeb udeb
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.flographit
+application/vnd.font-fontforge-sfd						sfd
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.google-earth.kml+xml						kml
+application/vnd.google-earth.kmz						kmz
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.MiniPay
+application/vnd.ibm.afplinedata
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml							xul
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel							xls xlb xlt
+application/vnd.ms-excel.addin.macroEnabled.12					xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12				xlsb
+application/vnd.ms-excel.sheet.macroEnabled.12					xlsm
+application/vnd.ms-excel.template.macroEnabled.12				xltm
+application/vnd.ms-fontobject							eot
+application/vnd.ms-lrm
+application/vnd.ms-officetheme							thmx
+application/vnd.ms-pki.seccat							cat
+#application/vnd.ms-pki.stl							stl
+application/vnd.ms-powerpoint							ppt pps
+application/vnd.ms-powerpoint.addin.macroEnabled.12				ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12			pptm
+application/vnd.ms-powerpoint.slide.macroEnabled.12				sldm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12				ppsm
+application/vnd.ms-powerpoint.template.macroEnabled.12				potm
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-word.document.macroEnabled.12				docm
+application/vnd.ms-word.template.macroEnabled.12				dotm
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.oasis.opendocument.chart					odc
+application/vnd.oasis.opendocument.database					odb
+application/vnd.oasis.opendocument.formula					odf
+application/vnd.oasis.opendocument.graphics					odg
+application/vnd.oasis.opendocument.graphics-template				otg
+application/vnd.oasis.opendocument.image					odi
+application/vnd.oasis.opendocument.presentation					odp
+application/vnd.oasis.opendocument.presentation-template			otp
+application/vnd.oasis.opendocument.spreadsheet					ods
+application/vnd.oasis.opendocument.spreadsheet-template				ots
+application/vnd.oasis.opendocument.text						odt
+application/vnd.oasis.opendocument.text-master					odm
+application/vnd.oasis.opendocument.text-template				ott
+application/vnd.oasis.opendocument.text-web					oth
+application/vnd.openxmlformats-officedocument.presentationml.presentation	pptx
+application/vnd.openxmlformats-officedocument.presentationml.slide		sldx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow		ppsx
+application/vnd.openxmlformats-officedocument.presentationml.template		potx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet		xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template		xltx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document		docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template		dotx
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.rim.cod								cod
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.smaf								mmf
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.stardivision.calc						sdc
+application/vnd.stardivision.chart						sds
+application/vnd.stardivision.draw						sda
+application/vnd.stardivision.impress						sdd
+application/vnd.stardivision.math						sdf
+application/vnd.stardivision.writer						sdw
+application/vnd.stardivision.writer-global					sgl
+application/vnd.street-stream
+application/vnd.sun.xml.calc							sxc
+application/vnd.sun.xml.calc.template						stc
+application/vnd.sun.xml.draw							sxd
+application/vnd.sun.xml.draw.template						std
+application/vnd.sun.xml.impress							sxi
+application/vnd.sun.xml.impress.template					sti
+application/vnd.sun.xml.math							sxm
+application/vnd.sun.xml.writer							sxw
+application/vnd.sun.xml.writer.global						sxg
+application/vnd.sun.xml.writer.template						stw
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.symbian.install							sis
+application/vnd.tcpdump.pcap							cap pcap
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio								vsd vst vsw vss
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml							wbxml
+application/vnd.wap.wmlc							wmlc
+application/vnd.wap.wmlscriptc							wmlsc
+application/vnd.webturbo
+application/vnd.wordperfect							wpd
+application/vnd.wordperfect5.1							wp5
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/zlib
+application/x-123				wk
+application/x-7z-compressed			7z
+application/x-abiword				abw
+application/x-apple-diskimage			dmg
+application/x-bcpio				bcpio
+application/x-bittorrent			torrent
+application/x-cab				cab
+application/x-cbr				cbr
+application/x-cbz				cbz
+application/x-cdf				cdf cda
+application/x-cdlink				vcd
+application/x-chess-pgn				pgn
+application/x-comsol				mph
+application/x-core
+application/x-cpio				cpio
+application/x-csh				csh
+application/x-debian-package			deb udeb
+application/x-director				dcr dir dxr
+application/x-dms				dms
+application/x-doom				wad
+application/x-dvi				dvi
+application/x-executable
+application/x-font				pfa pfb gsf
+application/x-font-pcf				pcf pcf.Z
+application/x-freemind				mm
+application/x-futuresplash			spl
+application/x-ganttproject			gan
+application/x-gnumeric				gnumeric
+application/x-go-sgf				sgf
+application/x-graphing-calculator		gcf
+application/x-gtar				gtar
+application/x-gtar-compressed			tgz taz
+application/x-hdf				hdf
+#application/x-httpd-eruby			rhtml
+#application/x-httpd-php			phtml pht php
+#application/x-httpd-php-source			phps
+#application/x-httpd-php3			php3
+#application/x-httpd-php3-preprocessed		php3p
+#application/x-httpd-php4			php4
+#application/x-httpd-php5			php5
+application/x-hwp				hwp
+application/x-ica				ica
+application/x-info				info
+application/x-internet-signup			ins isp
+application/x-iphone				iii
+application/x-iso9660-image			iso
+application/x-jam				jam
+application/x-java-applet
+application/x-java-bean
+application/x-java-jnlp-file			jnlp
+application/x-jmol				jmz
+application/x-kchart				chrt
+application/x-kdelnk
+application/x-killustrator			kil
+application/x-koan				skp skd skt skm
+application/x-kpresenter			kpr kpt
+application/x-kspread				ksp
+application/x-kword				kwd kwt
+application/x-latex				latex
+application/x-lha				lha
+application/x-lyx				lyx
+application/x-lzh				lzh
+application/x-lzx				lzx
+application/x-maker				frm maker frame fm fb book fbdoc
+application/x-mif				mif
+application/x-mpegURL				m3u8
+application/x-ms-application			application
+application/x-ms-manifest			manifest
+application/x-ms-wmd				wmd
+application/x-ms-wmz				wmz
+application/x-msdos-program			com exe bat dll
+application/x-msi				msi
+application/x-netcdf				nc
+application/x-ns-proxy-autoconfig		pac
+application/x-nwc				nwc
+application/x-object				o
+application/x-oz-application			oza
+application/x-pkcs7-certreqresp			p7r
+application/x-pkcs7-crl				crl
+application/x-python-code			pyc pyo
+application/x-qgis				qgs shp shx
+application/x-quicktimeplayer			qtl
+application/x-rdp				rdp
+application/x-redhat-package-manager		rpm
+application/x-rss+xml				rss
+application/x-ruby				rb
+application/x-rx
+application/x-scilab				sci sce
+application/x-scilab-xcos			xcos
+application/x-sh				sh
+application/x-shar				shar
+application/x-shellscript
+application/x-shockwave-flash			swf swfl
+application/x-silverlight			scr
+application/x-sql				sql
+application/x-stuffit				sit sitx
+application/x-sv4cpio				sv4cpio
+application/x-sv4crc				sv4crc
+application/x-tar				tar
+application/x-tcl				tcl
+application/x-tex-gf				gf
+application/x-tex-pk				pk
+application/x-texinfo				texinfo texi
+application/x-trash				~ % bak old sik
+application/x-troff				t tr roff
+application/x-troff-man				man
+application/x-troff-me				me
+application/x-troff-ms				ms
+application/x-ustar				ustar
+application/x-videolan
+application/x-wais-source			src
+application/x-wingz				wz
+application/x-x509-ca-cert			crt
+application/x-xcf				xcf
+application/x-xfig				fig
+application/x-xpinstall				xpi
+application/x-xz				xz
+
+audio/32kadpcm
+audio/3gpp
+audio/amr					amr
+audio/amr-wb					awb
+audio/annodex					axa
+audio/basic					au snd
+audio/csound					csd orc sco
+audio/flac					flac
+audio/g.722.1
+audio/l16
+audio/midi					mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg					mpga mpega mp2 mp3 m4a
+audio/mpegurl					m3u
+audio/ogg					oga ogg opus spx
+audio/parityfec
+audio/prs.sid					sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff					aif aiff aifc
+audio/x-gsm					gsm
+audio/x-mpegurl					m3u
+audio/x-ms-wma					wma
+audio/x-ms-wax					wax
+audio/x-pn-realaudio-plugin
+audio/x-pn-realaudio				ra rm ram
+audio/x-realaudio				ra
+audio/x-scpls					pls
+audio/x-sd2					sd2
+audio/x-wav					wav
+
+chemical/x-alchemy				alc
+chemical/x-cache				cac cache
+chemical/x-cache-csf				csf
+chemical/x-cactvs-binary			cbin cascii ctab
+chemical/x-cdx					cdx
+chemical/x-cerius				cer
+chemical/x-chem3d				c3d
+chemical/x-chemdraw				chm
+chemical/x-cif					cif
+chemical/x-cmdf					cmdf
+chemical/x-cml					cml
+chemical/x-compass				cpa
+chemical/x-crossfire				bsd
+chemical/x-csml					csml csm
+chemical/x-ctx					ctx
+chemical/x-cxf					cxf cef
+#chemical/x-daylight-smiles			smi
+chemical/x-embl-dl-nucleotide			emb embl
+chemical/x-galactic-spc				spc
+chemical/x-gamess-input				inp gam gamin
+chemical/x-gaussian-checkpoint			fch fchk
+chemical/x-gaussian-cube			cub
+chemical/x-gaussian-input			gau gjc gjf
+chemical/x-gaussian-log				gal
+chemical/x-gcg8-sequence			gcg
+chemical/x-genbank				gen
+chemical/x-hin					hin
+chemical/x-isostar				istr ist
+chemical/x-jcamp-dx				jdx dx
+chemical/x-kinemage				kin
+chemical/x-macmolecule				mcm
+chemical/x-macromodel-input			mmd mmod
+chemical/x-mdl-molfile				mol
+chemical/x-mdl-rdfile				rd
+chemical/x-mdl-rxnfile				rxn
+chemical/x-mdl-sdfile				sd sdf
+chemical/x-mdl-tgf				tgf
+#chemical/x-mif					mif
+chemical/x-mmcif				mcif
+chemical/x-mol2					mol2
+chemical/x-molconn-Z				b
+chemical/x-mopac-graph				gpt
+chemical/x-mopac-input				mop mopcrt mpc zmt
+chemical/x-mopac-out				moo
+chemical/x-mopac-vib				mvb
+chemical/x-ncbi-asn1				asn
+chemical/x-ncbi-asn1-ascii			prt ent
+chemical/x-ncbi-asn1-binary			val aso
+chemical/x-ncbi-asn1-spec			asn
+chemical/x-pdb					pdb ent
+chemical/x-rosdal				ros
+chemical/x-swissprot				sw
+chemical/x-vamas-iso14976			vms
+chemical/x-vmd					vmd
+chemical/x-xtel					xtel
+chemical/x-xyz					xyz
+
+font/collection					ttc
+font/otf					ttf otf
+font/sfnt					ttf otf
+font/ttf					ttf otf
+font/woff					woff
+font/woff2					woff2
+
+image/cgm
+image/g3fax
+image/gif					gif
+image/ief					ief
+image/jp2					jp2 jpg2
+image/jpeg					jpeg jpg jpe
+image/jpm					jpm
+image/jpx					jpx jpf
+image/naplps
+image/pcx					pcx
+image/png					png
+image/prs.btif
+image/prs.pti
+image/svg+xml					svg svgz
+image/tiff					tiff tif
+image/vnd.cns.inf2
+image/vnd.djvu					djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.microsoft.icon			ico
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp				wbmp
+image/vnd.xiff
+image/x-canon-cr2				cr2
+image/x-canon-crw				crw
+image/x-cmu-raster				ras
+image/x-coreldraw				cdr
+image/x-coreldrawpattern			pat
+image/x-coreldrawtemplate			cdt
+image/x-corelphotopaint				cpt
+image/x-epson-erf				erf
+image/x-icon
+image/x-jg					art
+image/x-jng					jng
+image/x-ms-bmp					bmp
+image/x-nikon-nef				nef
+image/x-olympus-orf				orf
+image/x-photoshop				psd
+image/x-portable-anymap				pnm
+image/x-portable-bitmap				pbm
+image/x-portable-graymap			pgm
+image/x-portable-pixmap				ppm
+image/x-rgb					rgb
+image/x-xbitmap					xbm
+image/x-xpixmap					xpm
+image/x-xwindowdump				xwd
+
+inode/chardevice
+inode/blockdevice
+inode/directory-locked
+inode/directory
+inode/fifo
+inode/socket
+
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/s-http
+message/news
+message/partial
+message/rfc822					eml
+
+model/iges					igs iges
+model/mesh					msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml					wrl vrml
+model/x3d+vrml					x3dv
+model/x3d+xml					x3d
+model/x3d+binary				x3db
+
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+
+text/cache-manifest				appcache
+text/calendar					ics icz
+text/css					css
+text/csv					csv
+text/directory
+text/english
+text/enriched
+text/h323					323
+text/html					html htm shtml
+text/iuls					uls
+text/mathml					mml
+text/markdown                                   md markdown
+text/parityfec
+text/plain					asc txt text pot brf srt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext					rtx
+text/rtf
+text/scriptlet					sct wsc
+text/t140
+text/texmacs					tm
+text/tab-separated-values			tsv
+text/turtle					ttl
+text/uri-list
+text/vcard					vcf vcard
+text/vnd.abc
+text/vnd.curl
+text/vnd.debian.copyright
+text/vnd.DMClientScript
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.IPTC.NewsML
+text/vnd.IPTC.NITF
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.sun.j2me.app-descriptor		jad
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml				wml
+text/vnd.wap.wmlscript				wmls
+text/x-bibtex					bib
+text/x-boo					boo
+text/x-c++hdr					h++ hpp hxx hh
+text/x-c++src					c++ cpp cxx cc
+text/x-chdr					h
+text/x-component				htc
+text/x-crontab
+text/x-csh					csh
+text/x-csrc					c
+text/x-dsrc					d
+text/x-diff					diff patch
+text/x-haskell					hs
+text/x-java					java
+text/x-lilypond					ly
+text/x-literate-haskell				lhs
+text/x-makefile
+text/x-moc					moc
+text/x-pascal					p pas
+text/x-pcs-gcd					gcd
+text/x-perl					pl pm
+text/x-python					py
+text/x-scala					scala
+text/x-server-parsed-html
+text/x-setext					etx
+text/x-sfv					sfv
+text/x-sh					sh
+text/x-tcl					tcl tk
+text/x-tex					tex ltx sty cls
+text/x-vcalendar				vcs
+
+video/3gpp					3gp
+video/annodex					axv
+video/dl					dl
+video/dv					dif dv
+video/fli					fli
+video/gl					gl
+video/mpeg					mpeg mpg mpe
+video/MP2T					ts
+video/mp4					mp4
+video/quicktime					qt mov
+video/mp4v-es
+video/ogg					ogv
+video/parityfec
+video/pointer
+video/webm					webm
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl				mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-flv					flv
+video/x-la-asf					lsf lsx
+video/x-mng					mng
+video/x-ms-asf					asf asx
+video/x-ms-wm					wm
+video/x-ms-wmv					wmv
+video/x-ms-wmx					wmx
+video/x-ms-wvx					wvx
+video/x-msvideo					avi
+video/x-sgi-movie				movie
+video/x-matroska				mpv mkv
+
+x-conference/x-cooltalk				ice
+
+x-epoc/x-sisx-app				sisx
+x-world/x-vrml					vrm vrml wrl
diff --git a/luni/src/main/java/libcore/net/mime.types.README b/luni/src/main/java/libcore/net/mime.types.README
new file mode 100644
index 0000000..3479703
--- /dev/null
+++ b/luni/src/main/java/libcore/net/mime.types.README
@@ -0,0 +1,13 @@
+
+Debian is the upstream for this mapping file:
+https://salsa.debian.org/debian/mime-support
+
+Last updated as of commit d4bbcca4ba04582ad1d253d82fc139bb23841a43.
+
+Copyright: public-domain
+License: ad-hoc
+ This package was written by Brian White <bcwhite@pobox.com> and others.
+ It contains public information compiled from around the 'net and many people.
+ .
+ The "update-mime" program was written by Brian White and has been
+ placed in the public domain.
diff --git a/luni/src/main/java/libcore/util/ArrayUtils.java b/luni/src/main/java/libcore/util/ArrayUtils.java
new file mode 100644
index 0000000..2d25bc8
--- /dev/null
+++ b/luni/src/main/java/libcore/util/ArrayUtils.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.util;
+
+public final class ArrayUtils {
+    private ArrayUtils() {}
+
+    /**
+     * Throws {@link ArrayIndexOutOfBoundsException} if the range is out of bounds.
+     * @param len length of the array. Must be non-negative
+     * @param offset start index of the range. Must be non-negative
+     * @param count length of the range. Must be non-negative
+     * @throws ArrayIndexOutOfBoundsException if the range from {@code offset} with length
+     * {@code count} is out of bounds of the array
+     */
+    public static void throwsIfOutOfBounds(int len, int offset, int count) {
+        if (len < 0) {
+            throw new ArrayIndexOutOfBoundsException("Negative length: " + len);
+        }
+
+        if ((offset | count) < 0 || offset > len - count) {
+            throw new ArrayIndexOutOfBoundsException(
+                "length=" + len + "; regionStart=" + offset + "; regionLength=" + count);
+        }
+    }
+}
diff --git a/luni/src/main/java/libcore/util/RecoverySystem.java b/luni/src/main/java/libcore/util/RecoverySystem.java
deleted file mode 100644
index ea9a889..0000000
--- a/luni/src/main/java/libcore/util/RecoverySystem.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package libcore.util;
-
-import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.X509Certificate;
-import java.util.Set;
-
-public class RecoverySystem {
-    private RecoverySystem() {
-    }
-
-    /**
-     * Verifies that the signature computed from {@code contentStream} matches
-     * that specified in {@code blockStream}. The public key of the certificates specified
-     * in the PCKS7 block must match  
-     */
-    public static void verify(InputStream blockStream, InputStream contentStream,
-                              Set<X509Certificate> trustedCerts)
-            throws IOException, SignatureException, NoSuchAlgorithmException {
-        PKCS7 block = new PKCS7(blockStream);
-
-        // Take the first certificate from the signature (packages
-        // should contain only one).
-        X509Certificate[] certificates = block.getCertificates();
-        if (certificates == null || certificates.length == 0) {
-            throw new SignatureException("signature contains no certificates");
-        }
-        X509Certificate cert = certificates[0];
-        PublicKey signatureKey = cert.getPublicKey();
-
-        SignerInfo[] signerInfos = block.getSignerInfos();
-        if (signerInfos == null || signerInfos.length == 0) {
-            throw new SignatureException("signature contains no signedData");
-        }
-        SignerInfo signerInfo = signerInfos[0];
-
-        boolean verified = false;
-        for (X509Certificate c : trustedCerts) {
-            if (c.getPublicKey().equals(signatureKey)) {
-                verified = true;
-                break;
-            }
-        }
-
-        if (!verified) {
-            throw new SignatureException("signature doesn't match any trusted key");
-        }
-
-        SignerInfo verifyResult = block.verify(signerInfo, contentStream);
-        if (verifyResult == null) {
-            throw new SignatureException("signature digest verification failed");
-        }
-    }
-}
diff --git a/luni/src/main/java/libcore/util/XmlObjectFactory.java b/luni/src/main/java/libcore/util/XmlObjectFactory.java
new file mode 100644
index 0000000..139f3a0
--- /dev/null
+++ b/luni/src/main/java/libcore/util/XmlObjectFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import com.android.org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlSerializer;
+import org.apache.harmony.xml.ExpatReader;
+import org.xml.sax.XMLReader;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+/**
+ * An internal class for creating platform-default XML parsers and related objects.
+ */
+public class XmlObjectFactory {
+
+    private XmlObjectFactory() {}
+
+    /**
+     * Returns a new instance of the platform default {@link XmlSerializer} more efficiently than
+     * using {@code XmlPullParserFactory.newInstance().newSerializer()}.
+     */
+    public static XmlSerializer newXmlSerializer() {
+        return new KXmlSerializer();
+    }
+
+    /**
+     * Returns a new instance of the platform default {@link XmlPullParser} more efficiently than
+     * using {@code XmlPullParserFactory.newInstance().newPullParser()}.
+     */
+    public static XmlPullParser newXmlPullParser() {
+        return new KXmlParser();
+    }
+
+    /**
+     * Returns the plaform default {@link XMLReader}.
+     */
+    public static XMLReader newXMLReader() {
+        return new ExpatReader();
+    }
+}
diff --git a/luni/src/main/java/libcore/util/ZoneInfo.java b/luni/src/main/java/libcore/util/ZoneInfo.java
index 4236061..66fb518 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -290,6 +290,8 @@
 
         // Use the latest non-daylight offset (if any) as the raw offset.
         if (mTransitions.length == 0) {
+            // This case is no longer expected to occur in the data used on Android after changes
+            // made in zic version 2014c. It is kept as a fallback.
             // If there are no transitions then use the first GMT offset.
             mRawOffset = gmtOffsets[0];
         } else {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java b/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java
deleted file mode 100644
index a31ecc0..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.util;
-
-/**
- * This class provides a way to add an implementation specific way to
- * access the current timezone.
- */
-public abstract class TimezoneGetter {
-
-    private static TimezoneGetter instance;
-
-    /**
-     * Retrieves the singleton instance of this class.
-     *
-     * @return TimezoneGetter the single instance of this class.
-     */
-    public static TimezoneGetter getInstance() {
-        return instance;
-    }
-
-    /**
-     * Sets the singleton instance of this class.
-     *
-     * @param instance
-     *            TimezoneGetter the single instance of this class.
-     */
-    public static void setInstance(TimezoneGetter getter) {
-        if (instance != null) {
-            throw new UnsupportedOperationException("TimezoneGetter instance already set");
-        }
-        instance = getter;
-    }
-
-    /**
-     * Retrieves the ID of the current time zone.
-     *
-     * @return String the ID of the current time zone.
-     */
-    public abstract String getId();
-}
diff --git a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 4f54fb5..b6ed988 100644
--- a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml.parsers;
 
+import com.android.org.kxml2.io.KXmlParser;
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLConnection;
@@ -26,7 +27,6 @@
 import org.apache.harmony.xml.dom.DocumentImpl;
 import org.apache.harmony.xml.dom.DocumentTypeImpl;
 import org.apache.harmony.xml.dom.TextImpl;
-import org.kxml2.io.KXmlParser;
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
diff --git a/include/ScopedIcuLocale.h b/luni/src/main/native/ScopedIcuLocale.h
similarity index 100%
rename from include/ScopedIcuLocale.h
rename to luni/src/main/native/ScopedIcuLocale.h
diff --git a/include/ScopedJavaUnicodeString.h b/luni/src/main/native/ScopedJavaUnicodeString.h
similarity index 100%
rename from include/ScopedJavaUnicodeString.h
rename to luni/src/main/native/ScopedJavaUnicodeString.h
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index e373a12..60d36f1 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -385,6 +385,7 @@
     initConstant(env, c, "MS_SYNC", MS_SYNC);
     initConstant(env, c, "NETLINK_NETFILTER", NETLINK_NETFILTER);
     initConstant(env, c, "NETLINK_ROUTE", NETLINK_ROUTE);
+    initConstant(env, c, "NETLINK_INET_DIAG", NETLINK_INET_DIAG);
     initConstant(env, c, "NI_DGRAM", NI_DGRAM);
     initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD);
     initConstant(env, c, "NI_NOFQDN", NI_NOFQDN);
diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp
index 11af4bd..47d8b80 100644
--- a/luni/src/main/native/java_util_regex_Matcher.cpp
+++ b/luni/src/main/native/java_util_regex_Matcher.cpp
@@ -161,7 +161,11 @@
 // Return a guess of the amount of native memory to be deallocated by a typical call to
 // Matcher_free().
 static jint Matcher_nativeSize(JNIEnv*, jclass) {
-    return 200;  // Very rough guess based on a quick look at the implementation.
+    // This value can be tuned. 200 was found to cause performance issues (b/111141123) so 10000
+    // is being used instead. If the value is too small, there's no pressure to collect matchers,
+    // too large and we'll run GC too often.
+    // Also see b/111141123.
+    return 10000;
 }
 
 static jint Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jint startIndex, jintArray offsets) {
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index 30da35c..8a3e1be 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -49,8 +49,13 @@
 
 #include <memory>
 
+#if defined(__BIONIC__)
+#include <android/fdsan.h>
+#endif
+
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/macros.h>
 #include <android-base/strings.h>
 #include <log/log.h>
 #include <nativehelper/AsynchronousCloseMonitor.h>
@@ -1086,13 +1091,65 @@
 static void Linux_close(JNIEnv* env, jobject, jobject javaFd) {
     // Get the FileDescriptor's 'fd' field and clear it.
     // We need to do this before we can throw an IOException (http://b/3222087).
+    if (javaFd == nullptr) {
+        jniThrowNullPointerException(env, "null fd");
+        return;
+    }
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     jniSetFileDescriptorOfFD(env, javaFd, -1);
 
+#if defined(__BIONIC__)
+    jlong ownerId = jniGetOwnerIdFromFileDescriptor(env, javaFd);
+
+    // Close with bionic's fd ownership tracking (which returns 0 in the case of EINTR).
+    throwIfMinusOne(env, "close", android_fdsan_close_with_tag(fd, ownerId));
+#else
     // Even if close(2) fails with EINTR, the fd will have been closed.
     // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.
     // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
     throwIfMinusOne(env, "close", close(fd));
+#endif
+}
+
+static void Linux_android_fdsan_exchange_owner_tag(JNIEnv* env, jclass,
+                                                   jobject javaFd,
+                                                   jlong expectedOwnerId,
+                                                   jlong newOwnerId) {
+#if defined(__BIONIC__)
+    int fd = jniGetFDFromFileDescriptor(env, javaFd);
+    android_fdsan_exchange_owner_tag(fd, expectedOwnerId, newOwnerId);
+#else
+    UNUSED(env, javaFd, expectedOwnerId, newOwnerId);
+#endif
+}
+
+static jlong Linux_android_fdsan_get_owner_tag(JNIEnv* env, jclass, jobject javaFd) {
+#if defined(__BIONIC__)
+    int fd = jniGetFDFromFileDescriptor(env, javaFd);
+    return android_fdsan_get_owner_tag(fd);
+#else
+    UNUSED(env, javaFd);
+    return 0;
+#endif
+}
+
+static jstring Linux_android_fdsan_get_tag_type(JNIEnv* env, jclass, jlong tag) {
+#if defined(__BIONIC__)
+    return env->NewStringUTF(android_fdsan_get_tag_type(tag));
+#else
+    UNUSED(tag);
+    return env->NewStringUTF("unknown");
+#endif
+}
+
+static jlong Linux_android_fdsan_get_tag_value(JNIEnv* env, jclass, jlong tag) {
+#if defined(__BIONIC__)
+    UNUSED(env);
+    return android_fdsan_get_tag_value(tag);
+#else
+    UNUSED(env, tag);
+    return 0;
+#endif
 }
 
 static void Linux_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
@@ -2297,10 +2354,18 @@
 
 static void Linux_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
     int fds[2];
-    int rc = throwIfMinusOne(env, "socketpair", TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
-    if (rc != -1) {
-        jniSetFileDescriptorOfFD(env, javaFd1, fds[0]);
-        jniSetFileDescriptorOfFD(env, javaFd2, fds[1]);
+    // Fail fast to avoid leaking file descriptors if either FileDescriptor is null.
+    if (javaFd1 == nullptr) {
+        jniThrowNullPointerException(env, "null fd1");
+    } else if (javaFd2 == nullptr) {
+        jniThrowNullPointerException(env, "null fd2");
+    } else {
+        int rc = throwIfMinusOne(env, "socketpair",
+                TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
+        if (rc != -1) {
+            jniSetFileDescriptorOfFD(env, javaFd1, fds[0]);
+            jniSetFileDescriptorOfFD(env, javaFd2, fds[1]);
+        }
     }
 }
 
@@ -2467,6 +2532,10 @@
 static JNINativeMethod gMethods[] = {
     NATIVE_METHOD(Linux, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
     NATIVE_METHOD(Linux, access, "(Ljava/lang/String;I)Z"),
+    NATIVE_METHOD(Linux, android_fdsan_exchange_owner_tag, "(Ljava/io/FileDescriptor;JJ)V"),
+    NATIVE_METHOD(Linux, android_fdsan_get_owner_tag, "(Ljava/io/FileDescriptor;)J"),
+    NATIVE_METHOD(Linux, android_fdsan_get_tag_type, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, android_fdsan_get_tag_value, "(J)J"),
     NATIVE_METHOD(Linux, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
     NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
     NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
diff --git a/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java b/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
index fa99f53..440fd40 100644
--- a/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/BlockGuardTest.java
@@ -117,8 +117,11 @@
         try {
             recorder.clear();
 
+            // Opening a file for read triggers:
+            // 1. Read violation from open()
+            // 2. Read violation from EISDIR check
             FileInputStream fis = new FileInputStream(tmpFile);
-            recorder.expectAndClear("onReadFromDisk");
+            recorder.expectAndClear("onReadFromDisk", "onReadFromDisk");
 
             fis.read(new byte[4], 0, 4);
             recorder.expectAndClear("onReadFromDisk");
@@ -139,8 +142,12 @@
         File f = File.createTempFile("foo", "bar");
         recorder.clear();
 
+        // Opening a file for write triggers:
+        // 1. Read violation from open()
+        // 2. Write violation from open()
+        // 3. Read violation from EISDIR check
         FileOutputStream fos = new FileOutputStream(f);
-        recorder.expectAndClear("onWriteToDisk");
+        recorder.expectAndClear("onReadFromDisk", "onWriteToDisk", "onReadFromDisk");
 
         fos.write(new byte[3]);
         recorder.expectAndClear("onWriteToDisk");
@@ -155,6 +162,32 @@
         recorder.expectNoViolations();
     }
 
+    public void testRandomAccessFile() throws Exception {
+        File f = File.createTempFile("foo", "bar");
+        recorder.clear();
+
+        // Opening a file for write triggers:
+        // 1. Read violation from open()
+        // 2. Write violation from open()
+        // 3. Read violation from EISDIR check
+        RandomAccessFile raf = new RandomAccessFile(f, "rw");
+        recorder.expectAndClear("onReadFromDisk", "onWriteToDisk", "onReadFromDisk");
+
+        raf.seek(0);
+        recorder.expectAndClear("onReadFromDisk");
+
+        raf.length();
+        recorder.expectAndClear("onReadFromDisk");
+
+        raf.read();
+        recorder.expectAndClear("onReadFromDisk");
+
+        raf.write(42);
+        recorder.expectAndClear("onWriteToDisk");
+
+        raf.close();
+    }
+
     public void testUnbufferedIO() throws Exception {
         File f = File.createTempFile("foo", "bar");
         recorder.setChecks(EnumSet.of(RecordingPolicy.Check.UNBUFFERED_IO));
@@ -266,7 +299,13 @@
         Os.close(fd);
     }
 
-    public static class RecordingPolicy implements BlockGuard.Policy {
+    public void testSystemGc() throws Exception {
+        recorder.clear();
+        Runtime.getRuntime().gc();
+        recorder.expectAndClear("onExplicitGc");
+    }
+
+    private static class RecordingPolicy implements BlockGuard.Policy {
         private final List<String> violations = new ArrayList<>();
         private Set<Check> checksList;
 
@@ -275,6 +314,7 @@
             READ_FROM_DISK,
             NETWORK,
             UNBUFFERED_IO,
+            EXPLICIT_GC,
         }
 
         public void setChecks(EnumSet<Check> checksList) {
@@ -309,6 +349,13 @@
             }
         }
 
+        @Override
+        public void onExplicitGc() {
+            if (checksList != null && checksList.contains(Check.EXPLICIT_GC)) {
+                addViolation("onExplicitGc");
+            }
+        }
+
         private void addViolation(String type) {
             StackTraceElement[] threadTrace = Thread.currentThread().getStackTrace();
 
diff --git a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
index 552c732..1320d6c 100644
--- a/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/PathClassLoaderTest.java
@@ -150,6 +150,11 @@
             }
 
             @Override
+            public void onExplicitGc() {
+                throw new RuntimeException("onExplicitGc");
+            }
+
+            @Override
             public int getPolicyMask() {
                 return 0;
             }
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 3619497..dd8e15b 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -2069,6 +2069,16 @@
         }
     }
 
+    public void testSetSSLSocketFactory_null() throws Exception {
+        URL url = new URL("https://google.com");
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        try {
+            connection.setSSLSocketFactory(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     public void testSetDefaultSSLSocketFactory_null() {
         try {
             HttpsURLConnection.setDefaultSSLSocketFactory(null);
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 1ff9b33..333594c 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -913,6 +913,11 @@
             }
 
             @Override
+            public void onExplicitGc() {
+                fail("Blockguard.Policy.onExplicitGc");
+            }
+
+            @Override
             public int getPolicyMask() {
                 return 0;
             }
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index 5950690..206f37d 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -60,62 +60,6 @@
         return result;
     }
 
-    /**
-     * Try to create a {@link MappedByteBuffer} from /dev/zero, to see if
-     * we support mapping UNIX character devices.
-     */
-    public void testDevZeroMap() throws Exception {
-        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "r");
-        try {
-            MappedByteBuffer mbb = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, 65536);
-
-            // Create an array initialized to all "(byte) 1"
-            byte[] buf1 = new byte[65536];
-            Arrays.fill(buf1, (byte) 1);
-
-            // Read from mapped /dev/zero, and overwrite this array.
-            mbb.get(buf1);
-
-            // Verify that everything is zero
-            for (int i = 0; i < 65536; i++) {
-                assertEquals((byte) 0, buf1[i]);
-            }
-        } finally {
-            raf.close();
-        }
-    }
-
-    /**
-     * Same as {@link libcore.java.nio.BufferTest#testDevZeroMap()}, but try to see
-     * if we can write to the UNIX character device.
-     */
-    public void testDevZeroMapRW() throws Exception {
-        RandomAccessFile raf = new RandomAccessFile("/dev/zero", "rw");
-        try {
-            MappedByteBuffer mbb = raf.getChannel()
-                    .map(FileChannel.MapMode.READ_WRITE, 65536, 131072);
-
-            // Create an array initialized to all "(byte) 1"
-            byte[] buf1 = new byte[65536];
-            Arrays.fill(buf1, (byte) 1);
-
-            // Put all "(byte) 1"s into the /dev/zero MappedByteBuffer.
-            mbb.put(buf1);
-
-            mbb.position(0);
-
-            byte[] buf2 = new byte[65536];
-            mbb.get(buf2);
-
-            // Verify that everything is one
-            for (int i = 0; i < 65536; i++) {
-                assertEquals((byte) 1, buf2[i]);
-            }
-        } finally {
-            raf.close();
-        }
-    }
-
     public void testByteSwappedBulkGetDirect() throws Exception {
         testByteSwappedBulkGet(ByteBuffer.allocateDirect(10));
     }
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
deleted file mode 100644
index ac6148a..0000000
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.security;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.Provider.Service;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.crypto.interfaces.DHPrivateKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-
-import junit.framework.TestCase;
-
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
-public class KeyPairGeneratorTest extends TestCase {
-
-    private List<Provider> providers = new ArrayList<Provider>();
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        // Allow access to deprecated BC algorithms in this test, so we can ensure they
-        // continue to work
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                VMRuntime.getRuntime().getTargetSdkVersion());
-
-        Provider[] providers = Security.getProviders();
-        for (Provider p : providers) {
-            // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for
-            // signature verification. It's OKish not to test here because it's tested by
-            // cts/tests/tests/keystore.
-            if (!p.getName().startsWith("AndroidKeyStore")) {
-                this.providers.add(p);
-            }
-        }
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        providers.clear();
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
-        super.tearDown();
-    }
-
-    public void test_providerCount() {
-        // We expect there to be at least one provider.
-        assertTrue(providers.size() > 0);
-        // If this fails remember to add _provider methods below. This test is sharded because it
-        // takes a long time to execute.
-        assertTrue(providers.size() < 10);
-    }
-
-    public void test_getInstance_provider0() throws Exception {
-        test_getInstance(0);
-    }
-
-    public void test_getInstance_provider1() throws Exception {
-        test_getInstance(1);
-    }
-
-    public void test_getInstance_provider2() throws Exception {
-        test_getInstance(2);
-    }
-
-    public void test_getInstance_provider3() throws Exception {
-        test_getInstance(3);
-    }
-
-    public void test_getInstance_provider4() throws Exception {
-        test_getInstance(4);
-    }
-
-    public void test_getInstance_provider5() throws Exception {
-        test_getInstance(5);
-    }
-
-    public void test_getInstance_provider6() throws Exception {
-        test_getInstance(6);
-    }
-
-    public void test_getInstance_provider7() throws Exception {
-        test_getInstance(7);
-    }
-
-    public void test_getInstance_provider8() throws Exception {
-        test_getInstance(8);
-    }
-
-    public void test_getInstance_provider9() throws Exception {
-        test_getInstance(9);
-    }
-
-    private void test_getInstance(int providerIndex) throws Exception {
-        if (providerIndex >= providers.size()) {
-            // Providers can be added by vendors and other tests. We do not
-            // specify a fixed number and silenty pass if the provider at the
-            // specified index does not exist.
-            return;
-        }
-
-        Provider provider = providers.get(providerIndex);
-        Set<Provider.Service> services = provider.getServices();
-        for (Provider.Service service : services) {
-            String type = service.getType();
-            if (!type.equals("KeyPairGenerator")) {
-                continue;
-            }
-            String algorithm = service.getAlgorithm();
-            AlgorithmParameterSpec params = null;
-
-            if ("DH".equals(algorithm)) {
-                params = getDHParams();
-            }
-
-            try {
-                // KeyPairGenerator.getInstance(String)
-                KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
-                assertEquals(algorithm, kpg1.getAlgorithm());
-                if (params != null) {
-                    kpg1.initialize(params);
-                }
-                test_KeyPairGenerator(kpg1);
-
-                // KeyPairGenerator.getInstance(String, Provider)
-                KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
-                assertEquals(algorithm, kpg2.getAlgorithm());
-                assertEquals(provider, kpg2.getProvider());
-                if (params != null) {
-                    kpg2.initialize(params);
-                }
-                test_KeyPairGenerator(kpg2);
-
-                // KeyPairGenerator.getInstance(String, String)
-                KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
-                                                                    provider.getName());
-                assertEquals(algorithm, kpg3.getAlgorithm());
-                assertEquals(provider, kpg3.getProvider());
-                if (params != null) {
-                    kpg3.initialize(params);
-                }
-                test_KeyPairGenerator(kpg3);
-            } catch (Exception e) {
-                throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
-            }
-        }
-    }
-
-    private static final Map<String, List<Integer>> KEY_SIZES
-            = new HashMap<String, List<Integer>>();
-    private static void putKeySize(String algorithm, int keySize) {
-        algorithm = algorithm.toUpperCase();
-        List<Integer> keySizes = KEY_SIZES.get(algorithm);
-        if (keySizes == null) {
-            keySizes = new ArrayList<Integer>();
-            KEY_SIZES.put(algorithm, keySizes);
-        }
-        keySizes.add(keySize);
-    }
-    private static List<Integer> getKeySizes(String algorithm) throws Exception {
-        algorithm = algorithm.toUpperCase();
-        List<Integer> keySizes = KEY_SIZES.get(algorithm);
-        if (keySizes == null) {
-            throw new Exception("Unknown key sizes for KeyPairGenerator." + algorithm);
-        }
-        return keySizes;
-    }
-    static {
-        putKeySize("DSA", 512);
-        putKeySize("DSA", 512+64);
-        putKeySize("DSA", 1024);
-        putKeySize("RSA", 512);
-        putKeySize("DH", 512);
-        putKeySize("DH", 512+64);
-        putKeySize("DH", 1024);
-        putKeySize("DiffieHellman", 512);
-        putKeySize("DiffieHellman", 512+64);
-        putKeySize("DiffieHellman", 1024);
-        putKeySize("EC", 224);
-        putKeySize("EC", 256);
-        putKeySize("EC", 384);
-        putKeySize("EC", 521);
-    }
-
-    /** Elliptic Curve Crypto named curves that should be supported. */
-    private static final String[] EC_NAMED_CURVES = {
-        // NIST P-256 aka SECG secp256r1 aka ANSI X9.62 prime256v1
-        "secp256r1", "prime256v1",
-        // NIST P-521 aka SECG secp521r1
-        "secp521r1",
-    };
-
-    private void test_KeyPairGenerator(KeyPairGenerator kpg) throws Exception {
-        // without a call to initialize
-        test_KeyPair(kpg, kpg.genKeyPair());
-        test_KeyPair(kpg, kpg.generateKeyPair());
-
-        String algorithm = kpg.getAlgorithm();
-
-        // TODO: detect if we're running in vogar and run the full test
-        if ("DH".equals(algorithm)) {
-            // Disabled because this takes too long on devices.
-            // TODO: Re-enable DH test. http://b/5513723.
-            return;
-        }
-
-        List<Integer> keySizes = getKeySizes(algorithm);
-        for (int keySize : keySizes) {
-            kpg.initialize(keySize);
-            test_KeyPair(kpg, kpg.genKeyPair());
-            test_KeyPair(kpg, kpg.generateKeyPair());
-
-            kpg.initialize(keySize, (SecureRandom) null);
-            test_KeyPair(kpg, kpg.genKeyPair());
-            test_KeyPair(kpg, kpg.generateKeyPair());
-
-            kpg.initialize(keySize, new SecureRandom());
-            test_KeyPair(kpg, kpg.genKeyPair());
-            test_KeyPair(kpg, kpg.generateKeyPair());
-        }
-
-        if (("EC".equals(algorithm)) || ("ECDH".equals(algorithm))
-                || ("ECDSA".equals(algorithm))) {
-            for (String curveName : EC_NAMED_CURVES) {
-                kpg.initialize(new ECGenParameterSpec(curveName));
-                test_KeyPair(kpg, kpg.genKeyPair());
-                test_KeyPair(kpg, kpg.generateKeyPair());
-
-                kpg.initialize(new ECGenParameterSpec(curveName), (SecureRandom) null);
-                test_KeyPair(kpg, kpg.genKeyPair());
-                test_KeyPair(kpg, kpg.generateKeyPair());
-
-                kpg.initialize(new ECGenParameterSpec(curveName), new SecureRandom());
-                test_KeyPair(kpg, kpg.genKeyPair());
-                test_KeyPair(kpg, kpg.generateKeyPair());
-            }
-        }
-    }
-
-    private void test_KeyPair(KeyPairGenerator kpg, KeyPair kp) throws Exception {
-        assertNotNull(kp);
-        test_Key(kpg, kp.getPrivate());
-        test_Key(kpg, kp.getPublic());
-    }
-
-    private void test_Key(KeyPairGenerator kpg, Key k) throws Exception {
-        String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(Locale.ROOT);
-        if (StandardNames.IS_RI && expectedAlgorithm.equals("DIFFIEHELLMAN")) {
-            expectedAlgorithm = "DH";
-        }
-        assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase());
-        if (expectedAlgorithm.equals("DH")) {
-            if (k instanceof DHPublicKey) {
-                DHPublicKey dhPub = (DHPublicKey) k;
-                assertEquals(dhPub.getParams().getP(), getDHParams().getP());
-            } else if (k instanceof DHPrivateKey) {
-                DHPrivateKey dhPriv = (DHPrivateKey) k;
-                assertEquals(dhPriv.getParams().getP(), getDHParams().getP());
-            } else {
-                fail("not a public or private key!?");
-            }
-        }
-        assertNotNull(k.getEncoded());
-        assertNotNull(k.getFormat());
-
-        // Test serialization
-        {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream(16384);
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(k);
-
-            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-            ObjectInputStream ois = new ObjectInputStream(bais);
-            Key inflatedKey = (Key) ois.readObject();
-
-            assertEquals(k, inflatedKey);
-        }
-
-        test_KeyWithAllKeyFactories(k);
-    }
-
-    private void test_KeyWithAllKeyFactories(Key k) throws Exception {
-        byte[] encoded = k.getEncoded();
-
-        String keyAlgo = k.getAlgorithm();
-        for (Provider p : providers) {
-            Set<Provider.Service> services = p.getServices();
-            for (Provider.Service service : services) {
-                if (!"KeyFactory".equals(service.getType())) {
-                    continue;
-                }
-                if (!service.getAlgorithm().equals(keyAlgo)) {
-                    continue;
-                }
-
-                if ("PKCS#8".equals(k.getFormat())) {
-                    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
-                    KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
-                    PrivateKey privKey = kf.generatePrivate(spec);
-                    assertNotNull(k.getAlgorithm() + ", provider=" + p.getName(), privKey);
-
-                    /*
-                     * EC keys are unique because they can have explicit parameters or a curve
-                     * name. Check them specially so this test can continue to function.
-                     */
-                    if (k instanceof ECPrivateKey) {
-                        assertECPrivateKeyEquals((ECPrivateKey) k, (ECPrivateKey) privKey);
-                    } else {
-                        assertEquals(k.getAlgorithm() + ", provider=" + p.getName(),
-                                Arrays.toString(encoded),
-                                Arrays.toString(privKey.getEncoded()));
-                    }
-                } else if ("X.509".equals(k.getFormat())) {
-                    X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
-                    KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
-                    PublicKey pubKey = kf.generatePublic(spec);
-                    assertNotNull(pubKey);
-                    assertTrue(Arrays.equals(encoded, pubKey.getEncoded()));
-                }
-            }
-        }
-    }
-
-    private static void assertECPrivateKeyEquals(ECPrivateKey expected, ECPrivateKey actual) {
-        assertEquals(expected.getS(), actual.getS());
-        assertECParametersEquals(expected.getParams(), actual.getParams());
-    }
-
-    private static void assertECParametersEquals(ECParameterSpec expected, ECParameterSpec actual) {
-        assertEquals(expected.getCurve(), actual.getCurve());
-        assertEquals(expected.getGenerator(), actual.getGenerator());
-        assertEquals(expected.getOrder(), actual.getOrder());
-        assertEquals(expected.getCofactor(), actual.getCofactor());
-    }
-
-    /**
-     * DH parameters pre-generated so that the test doesn't take too long.
-     * These parameters were generated with:
-     *
-     * openssl gendh 512 | openssl dhparams -C
-     */
-    private static DHParameterSpec getDHParams() {
-        BigInteger p = new BigInteger("E7AB1768BD75CD24700960FFA32D3F1557344E587101237532CC641646ED7A7C104743377F6D46251698B665CE2A6CBAB6714C2569A7D2CA22C0CF03FA40AC93", 16);
-        BigInteger g = new BigInteger("02", 16);
-        return new DHParameterSpec(p, g, 512);
-    }
-
-    private static final BigInteger DSA_P = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
-        (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
-        (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
-        (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
-        (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
-        (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
-        (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
-        (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
-        (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
-        (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
-        (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
-        (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
-        (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
-        (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
-        (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
-        (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
-        (byte) 0x23,
-    });
-
-    private static final BigInteger DSA_Q = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
-        (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
-        (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
-    });
-
-    private static final BigInteger DSA_G = new BigInteger(new byte[] {
-        (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
-        (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
-        (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
-        (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
-        (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
-        (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
-        (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
-        (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
-        (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
-        (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
-        (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
-        (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
-        (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
-        (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
-        (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
-        (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
-    });
-
-    public void testDSAGeneratorWithParams() throws Exception {
-        final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G);
-
-        final Provider[] providers = Security.getProviders();
-        for (final Provider p : providers) {
-            Service s = p.getService("KeyPairGenerator", "DSA");
-            if (s == null) {
-                continue;
-            }
-
-            final KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", p);
-            kpg.initialize(dsaSpec);
-            KeyPair pair = kpg.generateKeyPair();
-            DSAPrivateKey privKey = (DSAPrivateKey) pair.getPrivate();
-            DSAPublicKey pubKey = (DSAPublicKey) pair.getPublic();
-
-            DSAParams actualParams = privKey.getParams();
-            assertNotNull("DSA params should not be null", actualParams);
-
-            assertEquals("DSA P should be the same as supplied with provider " + p.getName(),
-                    DSA_P, actualParams.getP());
-            assertEquals("DSA Q should be the same as supplied with provider " + p.getName(),
-                    DSA_Q, actualParams.getQ());
-            assertEquals("DSA G should be the same as supplied with provider " + p.getName(),
-                    DSA_G, actualParams.getG());
-
-            actualParams = pubKey.getParams();
-            assertNotNull("DSA params should not be null", actualParams);
-
-            assertEquals("DSA P should be the same as supplied with provider " + p.getName(),
-                    DSA_P, actualParams.getP());
-            assertEquals("DSA Q should be the same as supplied with provider " + p.getName(),
-                    DSA_Q, actualParams.getQ());
-            assertEquals("DSA G should be the same as supplied with provider " + p.getName(),
-                    DSA_G, actualParams.getG());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/java/security/MessageDigestTest.java b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
index d08920b..e896459 100644
--- a/luni/src/test/java/libcore/java/security/MessageDigestTest.java
+++ b/luni/src/test/java/libcore/java/security/MessageDigestTest.java
@@ -19,16 +19,9 @@
 import java.lang.reflect.Method;
 import java.security.MessageDigest;
 import java.security.MessageDigestSpi;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
@@ -36,238 +29,8 @@
 import java.util.concurrent.TimeUnit;
 import junit.framework.TestCase;
 
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
 public final class MessageDigestTest extends TestCase {
 
-    // Allow access to deprecated BC algorithms in this test, so we can ensure they
-    // continue to work
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                VMRuntime.getRuntime().getTargetSdkVersion());
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
-        super.tearDown();
-    }
-
-    private final byte[] sha_456 = {
-            -24,   9, -59, -47,  -50,  -92, 123, 69, -29,  71,
-              1, -46,  63,  96, -118, -102,  88,  3,  77, -55
-    };
-
-    public void testShaReset() throws NoSuchAlgorithmException {
-        MessageDigest sha = MessageDigest.getInstance("SHA");
-        sha.update(new byte[] { 1, 2, 3 });
-        sha.reset();
-        sha.update(new byte[] { 4, 5, 6 });
-        assertEquals(Arrays.toString(sha_456), Arrays.toString(sha.digest()));
-    }
-
-    public void test_getInstance() throws Exception {
-        Provider[] providers = Security.getProviders();
-        for (Provider provider : providers) {
-            Set<Provider.Service> services = provider.getServices();
-            for (Provider.Service service : services) {
-                String type = service.getType();
-                if (!type.equals("MessageDigest")) {
-                    continue;
-                }
-                String algorithm = service.getAlgorithm();
-                try {
-                    // MessageDigest.getInstance(String)
-                    MessageDigest md1 = MessageDigest.getInstance(algorithm);
-                    assertEquals(algorithm, md1.getAlgorithm());
-                    test_MessageDigest(md1);
-
-                    // MessageDigest.getInstance(String, Provider)
-                    MessageDigest md2 = MessageDigest.getInstance(algorithm, provider);
-                    assertEquals(algorithm, md2.getAlgorithm());
-                    assertEquals(provider, md2.getProvider());
-                    test_MessageDigest(md2);
-
-                    // MessageDigest.getInstance(String, String)
-                    MessageDigest md3 = MessageDigest.getInstance(algorithm, provider.getName());
-                    assertEquals(algorithm, md3.getAlgorithm());
-                    assertEquals(provider, md3.getProvider());
-                    test_MessageDigest(md3);
-                } catch (Exception e) {
-                    throw new Exception("Problem testing MessageDigest." + algorithm, e);
-                }
-            }
-        }
-    }
-
-    private static final Map<String, Map<String, byte[]>> EXPECTATIONS
-            = new HashMap<String, Map<String, byte[]>>();
-    private static void putExpectation(String algorithm, String inputName, byte[] expected) {
-        algorithm = algorithm.toUpperCase();
-        Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
-        if (expectations == null) {
-            expectations = new HashMap<String, byte[]>();
-            EXPECTATIONS.put(algorithm, expectations);
-        }
-        expectations.put(inputName, expected);
-    }
-    private static Map<String, byte[]> getExpectations(String algorithm) throws Exception {
-        algorithm = algorithm.toUpperCase();
-        Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
-        if (expectations == null) {
-            throw new Exception("No expectations for MessageDigest." + algorithm);
-        }
-        return expectations;
-    }
-    private static final String INPUT_EMPTY = "empty";
-    private static final String INPUT_256MB = "256mb";
-    static {
-        // INPUT_EMPTY
-        putExpectation("MD2",
-                       INPUT_EMPTY,
-                       new byte[] { -125, 80, -27, -93, -30, 76, 21, 61,
-                                    -14, 39, 92, -97, -128, 105, 39, 115 });
-        putExpectation("MD5",
-                       INPUT_EMPTY,
-                       new byte[] { -44, 29, -116, -39, -113, 0, -78, 4,
-                                    -23, -128, 9, -104, -20, -8, 66, 126 });
-        putExpectation("SHA",
-                       INPUT_EMPTY,
-                       new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
-                                    50, 85, -65, -17, -107, 96, 24, -112,
-                                    -81, -40, 7, 9});
-        putExpectation("SHA-1",
-                       INPUT_EMPTY,
-                       new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
-                                    50, 85, -65, -17, -107, 96, 24, -112,
-                                    -81, -40, 7, 9});
-        putExpectation("SHA-224",
-                       INPUT_EMPTY,
-                       new byte[] { -47, 74, 2, -116, 42, 58, 43, -55, 71,
-                                    97, 2, -69, 40, -126, 52, -60, 21,
-                                    -94, -80, 31, -126, -114, -90, 42,
-                                    -59, -77, -28, 47});
-        putExpectation("SHA-256",
-                       INPUT_EMPTY,
-                       new byte[] { -29, -80, -60, 66, -104, -4, 28, 20,
-                                    -102, -5, -12, -56, -103, 111, -71, 36,
-                                    39, -82, 65, -28, 100, -101, -109, 76,
-                                    -92, -107, -103, 27, 120, 82, -72, 85 });
-        putExpectation("SHA-384",
-                       INPUT_EMPTY,
-                       new byte[] { 56, -80, 96, -89, 81, -84, -106, 56,
-                                    76, -39, 50, 126, -79, -79, -29, 106,
-                                    33, -3, -73, 17, 20, -66, 7, 67,
-                                    76, 12, -57, -65, 99, -10, -31, -38,
-                                    39, 78, -34, -65, -25, 111, 101, -5,
-                                    -43, 26, -46, -15, 72, -104, -71, 91 });
-        putExpectation("SHA-512",
-                       INPUT_EMPTY,
-                       new byte[] { -49, -125, -31, 53, 126, -17, -72, -67,
-                                    -15, 84, 40, 80, -42, 109, -128, 7,
-                                    -42, 32, -28, 5, 11, 87, 21, -36,
-                                    -125, -12, -87, 33, -45, 108, -23, -50,
-                                    71, -48, -47, 60, 93, -123, -14, -80,
-                                    -1, -125, 24, -46, -121, 126, -20, 47,
-                                    99, -71, 49, -67, 71, 65, 122, -127,
-                                    -91, 56, 50, 122, -7, 39, -38, 62 });
-
-        // Regression test for a SHA-1 problem with inputs larger than 256 MiB. http://b/4501620
-        // In mid-2013 this takes 3 minutes even on the host, so let's not run it on devices.
-        if (System.getenv("ANDROID_BUILD_TOP") != null) {
-            // INPUT_256MB
-            putExpectation("MD2",
-                           INPUT_256MB,
-                           new byte[] { -63, -120, 6, 67, 12, -87, -39, -11,
-                                        -67, -3, -31, -41, -91, 16, -35, 91 });
-            putExpectation("MD5",
-                           INPUT_256MB,
-                           new byte[] { 31, 80, 57, -27, 11, -42, 107, 41,
-                                        12, 86, 104, 77, -123, 80, -58, -62 });
-            putExpectation("SHA",
-                           INPUT_256MB,
-                           new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
-                                        -33, 108, -120, 71, -76, -86, 105, 101,
-                                        86, 108, 92, 117 });
-            putExpectation("SHA-1",
-                           INPUT_256MB,
-                           new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
-                                        -33, 108, -120, 71, -76, -86, 105, 101,
-                                        86, 108, 92, 117 });
-            putExpectation("SHA-224",
-                           INPUT_256MB,
-                           new byte[] { -78, 82, 5, -71, 57, 119, 77, -32,
-                                        -62, -74, -40, 64, -57, 79, 40, 116,
-                                        -18, 48, -69, 45, 18, -94, 111, 114,
-                                        -45, -93, 43, -11 });
-            putExpectation("SHA-256",
-                           INPUT_256MB,
-                           new byte[] { -90, -41, 42, -57, 105, 15, 83, -66,
-                                        106, -28, 107, -88, -123, 6, -67, -105,
-                                        48, 42, 9, 63, 113, 8, 71, 43,
-                                        -39, -17, -61, -50, -3, -96, 100, -124 });
-            putExpectation("SHA-384",
-                           INPUT_256MB,
-                           new byte[] { 71, 72, 77, -83, -110, 22, -118, -18,
-                                        -58, 119, 115, 74, -67, -36, 84, 122,
-                                        -105, -67, -75, 15, -33, 37, 78, -95,
-                                        4, 118, -53, 106, 65, -115, -19, 121,
-                                        -59, -94, -45, -111, -124, 35, 35, 60,
-                                        67, -34, 62, 106, -16, 122, -110, -14 });
-            putExpectation("SHA-512",
-                           INPUT_256MB,
-                           new byte[] { 36, 7, -120, 39, -87, -87, 84, -40,
-                                        -66, 114, 62, -73, 107, 101, -117, -12,
-                                        -124, 20, 109, 103, -92, 125, 111, 102,
-                                        12, 114, -68, 100, 30, 25, -88, 62,
-                                        108, 56, 9, -107, 89, -25, -50, 118,
-                                        -87, 100, 13, 37, -14, 66, -40, -97,
-                                        105, -27, 79, -62, 53, -31, 83, 40,
-                                        4, 57, 90, -81, 63, -77, -42, 113 });
-        }
-    }
-
-    private void test_MessageDigest(MessageDigest md) throws Exception {
-        String algorithm = md.getAlgorithm();
-        for (Map.Entry<String, byte[]> expectation : getExpectations(algorithm).entrySet()) {
-            String inputName = expectation.getKey();
-            byte[] expected = expectation.getValue();
-            byte[] actual;
-            if (inputName.equals(INPUT_EMPTY)) {
-                actual = md.digest();
-            } else if (inputName.equals(INPUT_256MB)) {
-                byte[] mb = new byte[1 * 1024 * 1024];
-                for (int i = 0; i < 256; i++) {
-                    md.update(mb);
-                }
-                actual = md.digest();
-            } else {
-                throw new AssertionError(inputName);
-            }
-            assertDigest(algorithm, expected, actual);
-            assertEquals(algorithm, expected.length, md.getDigestLength());
-        }
-    }
-
-    private void assertDigest(String algorithm, byte[] actual, byte[] expected) {
-        assertEquals(algorithm, javaBytes(actual), javaBytes(expected));
-    }
-
-    private String javaBytes(byte[] bytes) {
-        StringBuffer buf = new StringBuffer();
-        buf.append("new byte[] { ");
-        for (byte b : bytes) {
-            buf.append(b);
-            buf.append(", ");
-        }
-        buf.append(" }");
-        return buf.toString();
-    }
-
     private final int THREAD_COUNT = 10;
 
     public void testMessageDigest_MultipleThreads_Misuse() throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/README b/luni/src/test/java/libcore/java/security/README
new file mode 100644
index 0000000..f89b27d
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/README
@@ -0,0 +1,2 @@
+Most tests for java.security can be found in external/conscrypt.  They
+should be updated at http://github.com/google/conscrypt.
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 28e735c..3750742 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -16,21 +16,16 @@
 
 package libcore.java.security;
 
-import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
 import java.lang.reflect.Method;
-import java.math.BigInteger;
 import java.security.AlgorithmParameters;
 import java.security.InvalidKeyException;
 import java.security.InvalidParameterException;
 import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
@@ -38,36 +33,11 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.SignatureSpi;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.EllipticCurve;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
 import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
 import junit.framework.TestCase;
-
 import libcore.util.HexEncoding;
 
 import dalvik.system.VMRuntime;
@@ -342,6 +312,13 @@
         }
     }
 
+    private static final byte[] PK_BYTES = HexEncoding.decode(
+            "30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
+                    + "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
+                    + "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
+                    + "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
+                    + "0001");
+
     private static PublicKey createPublicKey() throws Exception {
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
@@ -470,2835 +447,6 @@
         }
     }
 
-    // 20 bytes for DSA
-    private final byte[] DATA = new byte[20];
-
-    public void test_getInstance() throws Exception {
-        Provider[] providers = Security.getProviders();
-        for (Provider provider : providers) {
-            // Do not test AndroidKeyStore's Signature. It needs an AndroidKeyStore-specific key.
-            // It's OKish not to test AndroidKeyStore's Signature here because it's tested
-            // by cts/tests/test/keystore.
-            if (provider.getName().startsWith("AndroidKeyStore")) {
-                continue;
-            }
-            Set<Provider.Service> services = provider.getServices();
-            for (Provider.Service service : services) {
-                String type = service.getType();
-                if (!type.equals("Signature")) {
-                    continue;
-                }
-                String algorithm = service.getAlgorithm();
-                try {
-                    KeyPair kp = keyPair(algorithm, provider.getName());
-                    // Signature.getInstance(String)
-                    Signature sig1 = Signature.getInstance(algorithm);
-                    assertEquals(algorithm, sig1.getAlgorithm());
-                    test_Signature(sig1, kp);
-
-                    // Signature.getInstance(String, Provider)
-                    Signature sig2 = Signature.getInstance(algorithm, provider);
-                    assertEquals(algorithm, sig2.getAlgorithm());
-                    assertEquals(provider, sig2.getProvider());
-                    test_Signature(sig2, kp);
-
-                    // Signature.getInstance(String, String)
-                    Signature sig3 = Signature.getInstance(algorithm, provider.getName());
-                    assertEquals(algorithm, sig3.getAlgorithm());
-                    assertEquals(provider, sig3.getProvider());
-                    test_Signature(sig3, kp);
-                } catch (Exception e) {
-                    throw new Exception("Problem testing Signature." + algorithm, e);
-                }
-            }
-        }
-    }
-
-    private final Map<String, KeyPair> keypairAlgorithmToInstance
-            = new HashMap<String, KeyPair>();
-
-    private KeyPair keyPair(String sigAlgorithm, String providerName) throws Exception {
-        String sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
-        if (sigAlgorithmUpperCase.endsWith("ENCRYPTION")) {
-            sigAlgorithm = sigAlgorithm.substring(0, sigAlgorithm.length()-"ENCRYPTION".length());
-            sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
-        }
-
-        String kpAlgorithm;
-        // note ECDSA must be before DSA
-        if (sigAlgorithmUpperCase.endsWith("ECDSA")) {
-            kpAlgorithm = "EC";
-        } else if (sigAlgorithmUpperCase.endsWith("DSA")) {
-            kpAlgorithm = "DSA";
-        } else if ((sigAlgorithmUpperCase.endsWith("RSA"))
-                || (sigAlgorithmUpperCase.endsWith("RSA/PSS"))) {
-            kpAlgorithm = "RSA";
-        } else {
-            throw new Exception("Unknown KeyPair algorithm for Signature algorithm "
-                                + sigAlgorithm);
-        }
-
-        KeyPair kp = keypairAlgorithmToInstance.get(kpAlgorithm);
-        if (kp == null) {
-            kp = KeyPairGenerator.getInstance(kpAlgorithm).generateKeyPair();
-            keypairAlgorithmToInstance.put(kpAlgorithm, kp);
-        }
-        return kp;
-    }
-
-    private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
-        sig.initSign(keyPair.getPrivate());
-        sig.update(DATA);
-        byte[] signature = sig.sign();
-        assertNotNull(sig.getAlgorithm(), signature);
-        assertTrue(sig.getAlgorithm(), signature.length > 0);
-
-        sig.initVerify(keyPair.getPublic());
-        sig.update(DATA);
-        assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
-        // After verify, should be reusable as if we are after initVerify
-        sig.update(DATA);
-        assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
-        /*
-         * The RI appears to clear out the input data in RawDSA while calling
-         * verify a second time.
-         */
-        if (StandardNames.IS_RI && "NONEwithDSA".equalsIgnoreCase(sig.getAlgorithm())) {
-            try {
-                sig.verify(signature);
-                fail("Expected RI to have a NONEwithDSA bug");
-            } catch (SignatureException bug) {
-            }
-        } else {
-            // Calling Signature.verify a second time should not throw
-            // http://code.google.com/p/android/issues/detail?id=34933
-            sig.verify(signature);
-        }
-
-        testSignature_MultipleThreads_Misuse(sig);
-    }
-
-    private static final byte[] PK_BYTES = HexEncoding.decode(
-            "30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
-            + "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
-            + "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
-            + "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
-            + "0001");
-    private static final byte[] CONTENT = HexEncoding.decode(
-            "f2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95030b93ce7260423e5c00"
-            + "fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc00fabd44657669636573"
-            + "00faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f53d19693d480de767e5fb"
-            + "976f3562324006372300fabdfd04e1f51ef3aa00fa8d00000001a203e202859471968cc68835f8a6"
-            + "8dde10f53d19693d480de767e5fb976f356232400637230002bab504e1f51ef5810002c29d28463f"
-            + "0003da8d000001e201eaf2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95"
-            + "030b93ce7260423e5c00fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc"
-            + "00fabd4465766963657300faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f5"
-            + "3d19693d480de767e5fb976f3562324006372300fabdfd04e1f51ef3aa000003e202859471968cc6"
-            + "8835f8a68dde10f53d19693d480de767e5fb976f3562324006372300000000019a0a9530819f300d"
-            + "06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce30012604218320"
-            + "c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc64f202fca21"
-            + "099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e66986039012626194840e0896b"
-            + "1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301000100");
-    private static final byte[] SIGNATURE = HexEncoding.decode(
-            "b4016456148cd2e9f580470aad63d19c1fee52b38c9dcb5b4d61a7ca369a7277497775d106d86394"
-            + "a69229184333b5a3e6261d5bcebdb02530ca9909f4d790199eae7c140f7db39dee2232191bdf0bfb"
-            + "34fdadc44326b9b3f3fa828652bab07f0362ac141c8c3784ebdec44e0b156a5e7bccdc81a56fe954"
-            + "56ac8c0e4ae12d97");
-
-
-    /**
-     * This should actually fail because the ASN.1 encoding is incorrect. It is
-     * missing the NULL in the AlgorithmIdentifier field.
-     * <p>
-     * http://code.google.com/p/android/issues/detail?id=18566 <br/>
-     * http://b/5038554
-     */
-    public void test18566_AlgorithmOid_MissingNull_Failure() throws Exception {
-        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
-        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-        PublicKey pk = keyFactory.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA");
-        sig.initVerify(pk);
-        sig.update(CONTENT);
-        assertFalse(sig.verify(SIGNATURE));
-    }
-
-    /*
-     * Test vectors generated with this private key:
-     *
-     * -----BEGIN RSA PRIVATE KEY-----
-     * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
-     * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
-     * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
-     * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
-     * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
-     * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
-     * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
-     * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
-     * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
-     * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
-     * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
-     * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
-     * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
-     * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
-     * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
-     * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
-     * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
-     * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
-     * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
-     * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
-     * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
-     * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
-     * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
-     * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
-     * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
-     * -----END RSA PRIVATE KEY-----
-     *
-     */
-
-    private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
-        (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
-        (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
-        (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
-        (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
-        (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
-        (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
-        (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
-        (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
-        (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
-        (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
-        (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
-        (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
-        (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
-        (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
-        (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
-        (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
-        (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
-        (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
-        (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
-        (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
-        (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
-        (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
-        (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
-        (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
-        (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
-        (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
-        (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
-        (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
-        (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
-        (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
-        (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
-        (byte) 0x69,
-    });
-
-    private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
-        (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
-        (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
-        (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
-        (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
-        (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0x80, (byte) 0xf0, (byte) 0x19,
-        (byte) 0x7a, (byte) 0x80, (byte) 0xd0, (byte) 0x73, (byte) 0x09, (byte) 0xe6, (byte) 0xc6, (byte) 0xa9,
-        (byte) 0x6f, (byte) 0x92, (byte) 0x53, (byte) 0x31, (byte) 0xe5, (byte) 0x7f, (byte) 0x8b, (byte) 0x4a,
-        (byte) 0xc6, (byte) 0xf4, (byte) 0xd4, (byte) 0x5e, (byte) 0xda, (byte) 0x45, (byte) 0xa2, (byte) 0x32,
-        (byte) 0x69, (byte) 0xc0, (byte) 0x9f, (byte) 0xc4, (byte) 0x28, (byte) 0xc0, (byte) 0x7a, (byte) 0x4e,
-        (byte) 0x6e, (byte) 0xdf, (byte) 0x73, (byte) 0x8a, (byte) 0x15, (byte) 0xde, (byte) 0xc9, (byte) 0x7f,
-        (byte) 0xab, (byte) 0xd2, (byte) 0xf2, (byte) 0xbb, (byte) 0x47, (byte) 0xa1, (byte) 0x4f, (byte) 0x20,
-        (byte) 0xea, (byte) 0x72, (byte) 0xfc, (byte) 0xfe, (byte) 0x4c, (byte) 0x36, (byte) 0xe0, (byte) 0x1a,
-        (byte) 0xda, (byte) 0x77, (byte) 0xbd, (byte) 0x13, (byte) 0x7c, (byte) 0xd8, (byte) 0xd4, (byte) 0xda,
-        (byte) 0x10, (byte) 0xbb, (byte) 0x16, (byte) 0x2e, (byte) 0x94, (byte) 0xa4, (byte) 0x66, (byte) 0x29,
-        (byte) 0x71, (byte) 0xf1, (byte) 0x75, (byte) 0xf9, (byte) 0x85, (byte) 0xfa, (byte) 0x18, (byte) 0x8f,
-        (byte) 0x05, (byte) 0x6c, (byte) 0xb9, (byte) 0x7e, (byte) 0xe2, (byte) 0x81, (byte) 0x6f, (byte) 0x43,
-        (byte) 0xab, (byte) 0x9d, (byte) 0x37, (byte) 0x47, (byte) 0x61, (byte) 0x24, (byte) 0x86, (byte) 0xcd,
-        (byte) 0xa8, (byte) 0xc1, (byte) 0x61, (byte) 0x96, (byte) 0xc3, (byte) 0x08, (byte) 0x18, (byte) 0xa9,
-        (byte) 0x95, (byte) 0xec, (byte) 0x85, (byte) 0xd3, (byte) 0x84, (byte) 0x67, (byte) 0x79, (byte) 0x12,
-        (byte) 0x67, (byte) 0xb3, (byte) 0xbf, (byte) 0x21, (byte) 0xf2, (byte) 0x73, (byte) 0x71, (byte) 0x0a,
-        (byte) 0x69, (byte) 0x25, (byte) 0x86, (byte) 0x25, (byte) 0x76, (byte) 0x84, (byte) 0x1c, (byte) 0x5b,
-        (byte) 0x67, (byte) 0x12, (byte) 0xc1, (byte) 0x2d, (byte) 0x4b, (byte) 0xd2, (byte) 0x0a, (byte) 0x2f,
-        (byte) 0x32, (byte) 0x99, (byte) 0xad, (byte) 0xb7, (byte) 0xc1, (byte) 0x35, (byte) 0xda, (byte) 0x5e,
-        (byte) 0x95, (byte) 0x15, (byte) 0xab, (byte) 0xda, (byte) 0x76, (byte) 0xe7, (byte) 0xca, (byte) 0xf2,
-        (byte) 0xa3, (byte) 0xbe, (byte) 0x80, (byte) 0x55, (byte) 0x1d, (byte) 0x07, (byte) 0x3b, (byte) 0x78,
-        (byte) 0xbf, (byte) 0x11, (byte) 0x62, (byte) 0xc4, (byte) 0x8a, (byte) 0xd2, (byte) 0xb7, (byte) 0xf4,
-        (byte) 0x74, (byte) 0x3a, (byte) 0x02, (byte) 0x38, (byte) 0xee, (byte) 0x4d, (byte) 0x25, (byte) 0x2f,
-        (byte) 0x7d, (byte) 0x5e, (byte) 0x7e, (byte) 0x65, (byte) 0x33, (byte) 0xcc, (byte) 0xae, (byte) 0x64,
-        (byte) 0xcc, (byte) 0xb3, (byte) 0x93, (byte) 0x60, (byte) 0x07, (byte) 0x5a, (byte) 0x2f, (byte) 0xd1,
-        (byte) 0xe0, (byte) 0x34, (byte) 0xec, (byte) 0x3a, (byte) 0xe5, (byte) 0xce, (byte) 0x9c, (byte) 0x40,
-        (byte) 0x8c, (byte) 0xcb, (byte) 0xf0, (byte) 0xe2, (byte) 0x5e, (byte) 0x41, (byte) 0x14, (byte) 0x02,
-        (byte) 0x16, (byte) 0x87, (byte) 0xb3, (byte) 0xdd, (byte) 0x47, (byte) 0x54, (byte) 0xae, (byte) 0x81,
-    });
-
-    private static final BigInteger RSA_2048_publicExponent = new BigInteger(new byte[] {
-        (byte) 0x01, (byte) 0x00, (byte) 0x01,
-    });
-
-    private static final BigInteger RSA_2048_primeP = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0xf5, (byte) 0x41, (byte) 0x88, (byte) 0x4b, (byte) 0xc3, (byte) 0x73, (byte) 0x7b,
-        (byte) 0x29, (byte) 0x22, (byte) 0xd4, (byte) 0x11, (byte) 0x9e, (byte) 0xf4, (byte) 0x5e, (byte) 0x2d,
-        (byte) 0xee, (byte) 0x2c, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x5f, (byte) 0x45, (byte) 0x50,
-        (byte) 0x5a, (byte) 0x15, (byte) 0x7a, (byte) 0xa5, (byte) 0x00, (byte) 0x9f, (byte) 0x99, (byte) 0xc7,
-        (byte) 0x3a, (byte) 0x2d, (byte) 0xf0, (byte) 0x72, (byte) 0x4a, (byte) 0xc4, (byte) 0x60, (byte) 0x24,
-        (byte) 0x30, (byte) 0x63, (byte) 0x32, (byte) 0xea, (byte) 0x89, (byte) 0x81, (byte) 0x77, (byte) 0x63,
-        (byte) 0x45, (byte) 0x46, (byte) 0x5d, (byte) 0xc6, (byte) 0xdf, (byte) 0x1e, (byte) 0x0a, (byte) 0x6f,
-        (byte) 0x14, (byte) 0x0a, (byte) 0xff, (byte) 0x3b, (byte) 0x73, (byte) 0x96, (byte) 0xe6, (byte) 0xa8,
-        (byte) 0x99, (byte) 0x4a, (byte) 0xc5, (byte) 0xda, (byte) 0xa9, (byte) 0x68, (byte) 0x73, (byte) 0x47,
-        (byte) 0x2f, (byte) 0xe3, (byte) 0x77, (byte) 0x49, (byte) 0xd1, (byte) 0x4e, (byte) 0xb3, (byte) 0xe0,
-        (byte) 0x75, (byte) 0xe6, (byte) 0x29, (byte) 0xdb, (byte) 0xeb, (byte) 0x35, (byte) 0x83, (byte) 0x33,
-        (byte) 0x8a, (byte) 0x6f, (byte) 0x36, (byte) 0x49, (byte) 0xd0, (byte) 0xa2, (byte) 0x65, (byte) 0x4a,
-        (byte) 0x7a, (byte) 0x42, (byte) 0xfd, (byte) 0x9a, (byte) 0xb6, (byte) 0xbf, (byte) 0xa4, (byte) 0xac,
-        (byte) 0x4d, (byte) 0x48, (byte) 0x1d, (byte) 0x39, (byte) 0x0b, (byte) 0xb2, (byte) 0x29, (byte) 0xb0,
-        (byte) 0x64, (byte) 0xbd, (byte) 0xc3, (byte) 0x11, (byte) 0xcc, (byte) 0x1b, (byte) 0xe1, (byte) 0xb6,
-        (byte) 0x31, (byte) 0x89, (byte) 0xda, (byte) 0x7c, (byte) 0x40, (byte) 0xcd, (byte) 0xec, (byte) 0xf2,
-        (byte) 0xb1,
-    });
-
-    private static final BigInteger RSA_2048_primeQ = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0xea, (byte) 0x1a, (byte) 0x74, (byte) 0x2d, (byte) 0xdb, (byte) 0x88, (byte) 0x1c,
-        (byte) 0xed, (byte) 0xb7, (byte) 0x28, (byte) 0x8c, (byte) 0x87, (byte) 0xe3, (byte) 0x8d, (byte) 0x86,
-        (byte) 0x8d, (byte) 0xd7, (byte) 0xa4, (byte) 0x09, (byte) 0xd1, (byte) 0x5a, (byte) 0x43, (byte) 0xf4,
-        (byte) 0x45, (byte) 0xd5, (byte) 0x37, (byte) 0x7a, (byte) 0x0b, (byte) 0x57, (byte) 0x31, (byte) 0xdd,
-        (byte) 0xbf, (byte) 0xca, (byte) 0x2d, (byte) 0xaf, (byte) 0x28, (byte) 0xa8, (byte) 0xe1, (byte) 0x3c,
-        (byte) 0xd5, (byte) 0xc0, (byte) 0xaf, (byte) 0xce, (byte) 0xc3, (byte) 0x34, (byte) 0x7d, (byte) 0x74,
-        (byte) 0xa3, (byte) 0x9e, (byte) 0x23, (byte) 0x5a, (byte) 0x3c, (byte) 0xd9, (byte) 0x63, (byte) 0x3f,
-        (byte) 0x27, (byte) 0x4d, (byte) 0xe2, (byte) 0xb9, (byte) 0x4f, (byte) 0x92, (byte) 0xdf, (byte) 0x43,
-        (byte) 0x83, (byte) 0x39, (byte) 0x11, (byte) 0xd9, (byte) 0xe9, (byte) 0xf1, (byte) 0xcf, (byte) 0x58,
-        (byte) 0xf2, (byte) 0x7d, (byte) 0xe2, (byte) 0xe0, (byte) 0x8f, (byte) 0xf4, (byte) 0x59, (byte) 0x64,
-        (byte) 0xc7, (byte) 0x20, (byte) 0xd3, (byte) 0xec, (byte) 0x21, (byte) 0x39, (byte) 0xdc, (byte) 0x7c,
-        (byte) 0xaf, (byte) 0xc9, (byte) 0x12, (byte) 0x95, (byte) 0x3c, (byte) 0xde, (byte) 0xcb, (byte) 0x2f,
-        (byte) 0x35, (byte) 0x5a, (byte) 0x2e, (byte) 0x2c, (byte) 0x35, (byte) 0xa5, (byte) 0x0f, (byte) 0xad,
-        (byte) 0x75, (byte) 0x4c, (byte) 0xb3, (byte) 0xb2, (byte) 0x31, (byte) 0x66, (byte) 0x42, (byte) 0x4b,
-        (byte) 0xa3, (byte) 0xb6, (byte) 0xe3, (byte) 0x11, (byte) 0x2a, (byte) 0x2b, (byte) 0x89, (byte) 0x8c,
-        (byte) 0x38, (byte) 0xc5, (byte) 0xc1, (byte) 0x5e, (byte) 0xdb, (byte) 0x23, (byte) 0x86, (byte) 0x93,
-        (byte) 0x39,
-    });
-
-    /* Test data is: "Android.\n" */
-    private static final byte[] Vector1Data = new byte[] {
-        (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x2e,
-        (byte) 0x0a,
-    };
-
-    private static final byte[] SHA1withRSA_Vector1Signature = {
-        (byte) 0x6d, (byte) 0x5b, (byte) 0xff, (byte) 0x68, (byte) 0xda, (byte) 0x18, (byte) 0x98, (byte) 0x72,
-        (byte) 0x5c, (byte) 0x1f, (byte) 0x46, (byte) 0x51, (byte) 0x77, (byte) 0x15, (byte) 0x11, (byte) 0xcb,
-        (byte) 0xe0, (byte) 0xb9, (byte) 0x3b, (byte) 0x7d, (byte) 0xf5, (byte) 0x96, (byte) 0x98, (byte) 0x24,
-        (byte) 0x85, (byte) 0x9d, (byte) 0x3e, (byte) 0xed, (byte) 0x9b, (byte) 0xb2, (byte) 0x8a, (byte) 0x91,
-        (byte) 0xfb, (byte) 0xf6, (byte) 0x85, (byte) 0x64, (byte) 0x74, (byte) 0x18, (byte) 0xb5, (byte) 0x1c,
-        (byte) 0xb3, (byte) 0x8d, (byte) 0x99, (byte) 0x0d, (byte) 0xdf, (byte) 0xaa, (byte) 0xa6, (byte) 0xa1,
-        (byte) 0xc3, (byte) 0xb6, (byte) 0x25, (byte) 0xb3, (byte) 0x06, (byte) 0xe0, (byte) 0xef, (byte) 0x28,
-        (byte) 0xb0, (byte) 0x4d, (byte) 0x50, (byte) 0xc7, (byte) 0x75, (byte) 0x39, (byte) 0xb9, (byte) 0x2c,
-        (byte) 0x47, (byte) 0xb5, (byte) 0xe2, (byte) 0x96, (byte) 0xf8, (byte) 0xf6, (byte) 0xcb, (byte) 0xa0,
-        (byte) 0x58, (byte) 0xc9, (byte) 0x3e, (byte) 0xd5, (byte) 0xfc, (byte) 0x26, (byte) 0xd9, (byte) 0x55,
-        (byte) 0x73, (byte) 0x39, (byte) 0x75, (byte) 0xb3, (byte) 0xb0, (byte) 0x0a, (byte) 0x5f, (byte) 0x5e,
-        (byte) 0x3b, (byte) 0x4a, (byte) 0x2e, (byte) 0xb1, (byte) 0x0e, (byte) 0x7d, (byte) 0xe5, (byte) 0xcc,
-        (byte) 0x04, (byte) 0x2c, (byte) 0xd1, (byte) 0x0a, (byte) 0x32, (byte) 0xaa, (byte) 0xd9, (byte) 0x8d,
-        (byte) 0x1f, (byte) 0xcb, (byte) 0xe3, (byte) 0x7f, (byte) 0x63, (byte) 0x12, (byte) 0xb1, (byte) 0x98,
-        (byte) 0x46, (byte) 0x46, (byte) 0x07, (byte) 0xd9, (byte) 0x49, (byte) 0xd2, (byte) 0xbf, (byte) 0xb5,
-        (byte) 0xbc, (byte) 0xbb, (byte) 0xfd, (byte) 0x1c, (byte) 0xd7, (byte) 0x11, (byte) 0x94, (byte) 0xaa,
-        (byte) 0x5f, (byte) 0x7b, (byte) 0xb2, (byte) 0x0c, (byte) 0x5d, (byte) 0x94, (byte) 0x53, (byte) 0x5e,
-        (byte) 0x81, (byte) 0x5c, (byte) 0xbb, (byte) 0x1d, (byte) 0x4f, (byte) 0x30, (byte) 0xcd, (byte) 0xf8,
-        (byte) 0xd7, (byte) 0xa5, (byte) 0xfa, (byte) 0x5e, (byte) 0xe0, (byte) 0x19, (byte) 0x3f, (byte) 0xa4,
-        (byte) 0xaa, (byte) 0x56, (byte) 0x4e, (byte) 0xec, (byte) 0xeb, (byte) 0xee, (byte) 0xa2, (byte) 0x6c,
-        (byte) 0xc9, (byte) 0x4f, (byte) 0xc2, (byte) 0xcc, (byte) 0x2a, (byte) 0xbc, (byte) 0x5b, (byte) 0x09,
-        (byte) 0x10, (byte) 0x73, (byte) 0x61, (byte) 0x0c, (byte) 0x04, (byte) 0xb6, (byte) 0xb7, (byte) 0x2c,
-        (byte) 0x37, (byte) 0xd2, (byte) 0xca, (byte) 0x2d, (byte) 0x54, (byte) 0xf2, (byte) 0xf7, (byte) 0x77,
-        (byte) 0xe1, (byte) 0xba, (byte) 0x9f, (byte) 0x29, (byte) 0x07, (byte) 0xa2, (byte) 0x74, (byte) 0xc6,
-        (byte) 0xe9, (byte) 0x1e, (byte) 0xde, (byte) 0xd7, (byte) 0x9c, (byte) 0x4b, (byte) 0xb7, (byte) 0x66,
-        (byte) 0x52, (byte) 0xe8, (byte) 0xac, (byte) 0xf6, (byte) 0x76, (byte) 0xab, (byte) 0x16, (byte) 0x82,
-        (byte) 0x96, (byte) 0x87, (byte) 0x40, (byte) 0x0f, (byte) 0xad, (byte) 0x2d, (byte) 0x46, (byte) 0xa6,
-        (byte) 0x28, (byte) 0x04, (byte) 0x13, (byte) 0xc2, (byte) 0xce, (byte) 0x50, (byte) 0x56, (byte) 0x6d,
-        (byte) 0xbe, (byte) 0x0c, (byte) 0x91, (byte) 0xd0, (byte) 0x8e, (byte) 0x80, (byte) 0x9e, (byte) 0x91,
-        (byte) 0x8f, (byte) 0x62, (byte) 0xb3, (byte) 0x57, (byte) 0xd6, (byte) 0xae, (byte) 0x53, (byte) 0x91,
-        (byte) 0x83, (byte) 0xe9, (byte) 0x38, (byte) 0x77, (byte) 0x8f, (byte) 0x20, (byte) 0xdd, (byte) 0x13,
-        (byte) 0x7d, (byte) 0x15, (byte) 0x44, (byte) 0x7e, (byte) 0xb5, (byte) 0x00, (byte) 0xd6, (byte) 0x45,
-    };
-
-    private static final byte[] Vector2Data = new byte[] {
-        (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20,
-        (byte) 0x61, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x65, (byte) 0x64,
-        (byte) 0x20, (byte) 0x6d, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x61, (byte) 0x67, (byte) 0x65,
-        (byte) 0x20, (byte) 0x66, (byte) 0x72, (byte) 0x6f, (byte) 0x6d, (byte) 0x20, (byte) 0x4b, (byte) 0x65,
-        (byte) 0x6e, (byte) 0x6e, (byte) 0x79, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74,
-        (byte) 0x2e, (byte) 0x0a,
-    };
-
-    private static final byte[] SHA1withRSA_Vector2Signature = new byte[] {
-        (byte) 0x2e, (byte) 0xa6, (byte) 0x33, (byte) 0xd1, (byte) 0x9d, (byte) 0xfc, (byte) 0x4e, (byte) 0x27,
-        (byte) 0xb3, (byte) 0xa8, (byte) 0x9a, (byte) 0xf2, (byte) 0x48, (byte) 0x62, (byte) 0x15, (byte) 0xa2,
-        (byte) 0xce, (byte) 0x5f, (byte) 0x2b, (byte) 0x0e, (byte) 0xc5, (byte) 0x26, (byte) 0xba, (byte) 0xd9,
-        (byte) 0x0f, (byte) 0x60, (byte) 0xeb, (byte) 0xf0, (byte) 0xd5, (byte) 0x5c, (byte) 0x6b, (byte) 0x23,
-        (byte) 0x11, (byte) 0x95, (byte) 0xa4, (byte) 0xbd, (byte) 0x11, (byte) 0x68, (byte) 0xe7, (byte) 0x3a,
-        (byte) 0x37, (byte) 0x3d, (byte) 0x79, (byte) 0xb8, (byte) 0x4f, (byte) 0xe9, (byte) 0xa1, (byte) 0x88,
-        (byte) 0xfb, (byte) 0xa9, (byte) 0x8b, (byte) 0x34, (byte) 0xa1, (byte) 0xe0, (byte) 0xca, (byte) 0x11,
-        (byte) 0xdd, (byte) 0xd0, (byte) 0x83, (byte) 0x7f, (byte) 0xc1, (byte) 0x0b, (byte) 0x16, (byte) 0x61,
-        (byte) 0xac, (byte) 0x09, (byte) 0xa2, (byte) 0xdd, (byte) 0x40, (byte) 0x5b, (byte) 0x8c, (byte) 0x7a,
-        (byte) 0xb2, (byte) 0xb4, (byte) 0x02, (byte) 0x7c, (byte) 0xd4, (byte) 0x9a, (byte) 0xe6, (byte) 0xa5,
-        (byte) 0x1a, (byte) 0x27, (byte) 0x77, (byte) 0x70, (byte) 0xe3, (byte) 0xe3, (byte) 0x71, (byte) 0xc7,
-        (byte) 0x59, (byte) 0xc7, (byte) 0x9f, (byte) 0xb8, (byte) 0xef, (byte) 0xe7, (byte) 0x15, (byte) 0x02,
-        (byte) 0x0d, (byte) 0x70, (byte) 0xdc, (byte) 0x2c, (byte) 0xe9, (byte) 0xf7, (byte) 0x63, (byte) 0x2a,
-        (byte) 0xb5, (byte) 0xee, (byte) 0x9f, (byte) 0x29, (byte) 0x56, (byte) 0x86, (byte) 0x99, (byte) 0xb3,
-        (byte) 0x0f, (byte) 0xe5, (byte) 0x1f, (byte) 0x76, (byte) 0x22, (byte) 0x3b, (byte) 0x7f, (byte) 0xa9,
-        (byte) 0x9e, (byte) 0xd4, (byte) 0xc4, (byte) 0x83, (byte) 0x5d, (byte) 0x57, (byte) 0xcc, (byte) 0x37,
-        (byte) 0xcb, (byte) 0x9a, (byte) 0x9e, (byte) 0x73, (byte) 0x44, (byte) 0x93, (byte) 0xb4, (byte) 0xf1,
-        (byte) 0x6b, (byte) 0x98, (byte) 0xa0, (byte) 0x57, (byte) 0xbb, (byte) 0x5e, (byte) 0x8f, (byte) 0x89,
-        (byte) 0x5b, (byte) 0x97, (byte) 0x26, (byte) 0xe4, (byte) 0xd0, (byte) 0x51, (byte) 0x0a, (byte) 0x5a,
-        (byte) 0xb7, (byte) 0x12, (byte) 0x1a, (byte) 0x6d, (byte) 0xb0, (byte) 0x79, (byte) 0x30, (byte) 0x51,
-        (byte) 0x83, (byte) 0x2e, (byte) 0xe2, (byte) 0x7a, (byte) 0x67, (byte) 0x66, (byte) 0xd3, (byte) 0x95,
-        (byte) 0xca, (byte) 0xfc, (byte) 0xcb, (byte) 0x92, (byte) 0x79, (byte) 0x32, (byte) 0x26, (byte) 0x86,
-        (byte) 0xe1, (byte) 0x0d, (byte) 0xd8, (byte) 0x19, (byte) 0xfa, (byte) 0x65, (byte) 0x37, (byte) 0xc9,
-        (byte) 0x4c, (byte) 0x2a, (byte) 0xe1, (byte) 0x42, (byte) 0xc7, (byte) 0xd4, (byte) 0xb7, (byte) 0xeb,
-        (byte) 0x1f, (byte) 0xc3, (byte) 0x53, (byte) 0x64, (byte) 0x6f, (byte) 0x2b, (byte) 0x78, (byte) 0x18,
-        (byte) 0x03, (byte) 0xda, (byte) 0x8d, (byte) 0x62, (byte) 0x24, (byte) 0x70, (byte) 0xab, (byte) 0xe6,
-        (byte) 0x16, (byte) 0x13, (byte) 0x24, (byte) 0x6b, (byte) 0x5f, (byte) 0xd3, (byte) 0xec, (byte) 0xc1,
-        (byte) 0x58, (byte) 0x64, (byte) 0xbd, (byte) 0x30, (byte) 0x98, (byte) 0x5e, (byte) 0x33, (byte) 0xce,
-        (byte) 0x87, (byte) 0x64, (byte) 0x14, (byte) 0x07, (byte) 0x85, (byte) 0x43, (byte) 0x3e, (byte) 0x9f,
-        (byte) 0x27, (byte) 0x9f, (byte) 0x63, (byte) 0x66, (byte) 0x9d, (byte) 0x26, (byte) 0x19, (byte) 0xc0,
-        (byte) 0x02, (byte) 0x08, (byte) 0x15, (byte) 0xcb, (byte) 0xb4, (byte) 0xaa, (byte) 0x4a, (byte) 0xc8,
-        (byte) 0xc0, (byte) 0x09, (byte) 0x15, (byte) 0x7d, (byte) 0x8a, (byte) 0x21, (byte) 0xbc, (byte) 0xa3,
-    };
-
-    /*
-     * echo 'Android.' | openssl dgst -sha224 -binary -sign privkey.pem  | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA224withRSA_Vector2Signature = new byte[] {
-        (byte) 0xBD, (byte) 0x3F, (byte) 0xD4, (byte) 0x20, (byte) 0x5B, (byte) 0xC0, (byte) 0x89, (byte) 0x4F,
-        (byte) 0x99, (byte) 0x6C, (byte) 0xF4, (byte) 0xA4, (byte) 0x70, (byte) 0xE3, (byte) 0x5B, (byte) 0x33,
-        (byte) 0xB3, (byte) 0xCA, (byte) 0xFE, (byte) 0x1F, (byte) 0xB9, (byte) 0x3A, (byte) 0xD6, (byte) 0x9B,
-        (byte) 0x1E, (byte) 0xDA, (byte) 0x65, (byte) 0x06, (byte) 0xBD, (byte) 0xC3, (byte) 0x2B, (byte) 0xF8,
-        (byte) 0x0E, (byte) 0xA0, (byte) 0xB5, (byte) 0x33, (byte) 0x7F, (byte) 0x15, (byte) 0xDC, (byte) 0xBB,
-        (byte) 0xDC, (byte) 0x98, (byte) 0x96, (byte) 0xF5, (byte) 0xF8, (byte) 0xE5, (byte) 0x55, (byte) 0x7D,
-        (byte) 0x48, (byte) 0x51, (byte) 0xC5, (byte) 0xAE, (byte) 0x12, (byte) 0xA2, (byte) 0x61, (byte) 0xC7,
-        (byte) 0xA2, (byte) 0x00, (byte) 0x0F, (byte) 0x35, (byte) 0x54, (byte) 0x3C, (byte) 0x7E, (byte) 0x97,
-        (byte) 0x19, (byte) 0x2D, (byte) 0x8F, (byte) 0xFD, (byte) 0x51, (byte) 0x04, (byte) 0x72, (byte) 0x23,
-        (byte) 0x65, (byte) 0x16, (byte) 0x41, (byte) 0x12, (byte) 0x46, (byte) 0xD6, (byte) 0x20, (byte) 0xB6,
-        (byte) 0x4E, (byte) 0xD6, (byte) 0xE8, (byte) 0x60, (byte) 0x91, (byte) 0x05, (byte) 0xCA, (byte) 0x57,
-        (byte) 0x6F, (byte) 0x53, (byte) 0xA4, (byte) 0x05, (byte) 0x2A, (byte) 0x37, (byte) 0xDD, (byte) 0x2E,
-        (byte) 0xA4, (byte) 0xC7, (byte) 0xBF, (byte) 0x9E, (byte) 0xF6, (byte) 0xD5, (byte) 0xD4, (byte) 0x34,
-        (byte) 0xB8, (byte) 0xB3, (byte) 0x8B, (byte) 0x66, (byte) 0x2C, (byte) 0xB6, (byte) 0x5F, (byte) 0xA4,
-        (byte) 0xB7, (byte) 0x77, (byte) 0xF8, (byte) 0x9A, (byte) 0x9C, (byte) 0x44, (byte) 0x9F, (byte) 0xF0,
-        (byte) 0xCA, (byte) 0x53, (byte) 0x56, (byte) 0x2F, (byte) 0x99, (byte) 0x2E, (byte) 0x4B, (byte) 0xA2,
-        (byte) 0x26, (byte) 0x50, (byte) 0x30, (byte) 0x97, (byte) 0x2B, (byte) 0x4B, (byte) 0x0C, (byte) 0x3E,
-        (byte) 0x28, (byte) 0x0B, (byte) 0x88, (byte) 0x87, (byte) 0x9E, (byte) 0xCE, (byte) 0xCB, (byte) 0x57,
-        (byte) 0x72, (byte) 0x6B, (byte) 0xF6, (byte) 0xD6, (byte) 0xAA, (byte) 0x4D, (byte) 0x5F, (byte) 0x19,
-        (byte) 0x7A, (byte) 0xAD, (byte) 0x44, (byte) 0x09, (byte) 0x33, (byte) 0x62, (byte) 0xC8, (byte) 0x56,
-        (byte) 0x82, (byte) 0x84, (byte) 0xBF, (byte) 0x52, (byte) 0xC6, (byte) 0xA2, (byte) 0x2B, (byte) 0xE3,
-        (byte) 0xC2, (byte) 0x7F, (byte) 0xE3, (byte) 0x06, (byte) 0xC3, (byte) 0x30, (byte) 0xB8, (byte) 0xD4,
-        (byte) 0x01, (byte) 0xE6, (byte) 0x3D, (byte) 0xDB, (byte) 0xCA, (byte) 0xE4, (byte) 0xFB, (byte) 0xA8,
-        (byte) 0x7B, (byte) 0x2D, (byte) 0x8F, (byte) 0x39, (byte) 0x7A, (byte) 0x63, (byte) 0x9F, (byte) 0x02,
-        (byte) 0xE8, (byte) 0x91, (byte) 0xD1, (byte) 0xEE, (byte) 0x60, (byte) 0xEE, (byte) 0xCA, (byte) 0xF2,
-        (byte) 0x33, (byte) 0x7D, (byte) 0xF2, (byte) 0x41, (byte) 0x52, (byte) 0x0B, (byte) 0x9B, (byte) 0x1B,
-        (byte) 0x2D, (byte) 0x89, (byte) 0x38, (byte) 0xEC, (byte) 0x24, (byte) 0x60, (byte) 0x40, (byte) 0x40,
-        (byte) 0x6F, (byte) 0xB6, (byte) 0x6F, (byte) 0x86, (byte) 0xB5, (byte) 0x0A, (byte) 0x3D, (byte) 0x98,
-        (byte) 0x77, (byte) 0x3F, (byte) 0x59, (byte) 0x41, (byte) 0x3E, (byte) 0x4D, (byte) 0xE4, (byte) 0x4E,
-        (byte) 0x91, (byte) 0xCD, (byte) 0x8E, (byte) 0x33, (byte) 0x60, (byte) 0x16, (byte) 0x8D, (byte) 0xAB,
-        (byte) 0x04, (byte) 0x14, (byte) 0xE8, (byte) 0x76, (byte) 0xF1, (byte) 0x06, (byte) 0xCD, (byte) 0x4A,
-        (byte) 0x88, (byte) 0xC7, (byte) 0x69, (byte) 0x6B, (byte) 0xC6, (byte) 0xDA, (byte) 0x9E, (byte) 0x09
-    };
-
-    private static final byte[] SHA256withRSA_Vector2Signature = new byte[] {
-        (byte) 0x18, (byte) 0x6e, (byte) 0x31, (byte) 0x1f, (byte) 0x1d, (byte) 0x44, (byte) 0x09, (byte) 0x3e,
-        (byte) 0xa0, (byte) 0xc4, (byte) 0x3d, (byte) 0xb4, (byte) 0x1b, (byte) 0xf2, (byte) 0xd8, (byte) 0xa4,
-        (byte) 0x59, (byte) 0xab, (byte) 0xb5, (byte) 0x37, (byte) 0x28, (byte) 0xb8, (byte) 0x94, (byte) 0x6b,
-        (byte) 0x6f, (byte) 0x13, (byte) 0x54, (byte) 0xff, (byte) 0xac, (byte) 0x15, (byte) 0x84, (byte) 0xd0,
-        (byte) 0xc9, (byte) 0x15, (byte) 0x5b, (byte) 0x69, (byte) 0x05, (byte) 0xf1, (byte) 0x44, (byte) 0xfd,
-        (byte) 0xde, (byte) 0xe8, (byte) 0xb4, (byte) 0x12, (byte) 0x59, (byte) 0x9e, (byte) 0x4c, (byte) 0x0b,
-        (byte) 0xd5, (byte) 0x49, (byte) 0x33, (byte) 0x28, (byte) 0xe0, (byte) 0xcb, (byte) 0x87, (byte) 0x85,
-        (byte) 0xd8, (byte) 0x18, (byte) 0x6f, (byte) 0xfe, (byte) 0xa2, (byte) 0x23, (byte) 0x82, (byte) 0xf0,
-        (byte) 0xe5, (byte) 0x39, (byte) 0x1b, (byte) 0x8c, (byte) 0x93, (byte) 0x11, (byte) 0x49, (byte) 0x72,
-        (byte) 0x2a, (byte) 0x5b, (byte) 0x25, (byte) 0xff, (byte) 0x4e, (byte) 0x88, (byte) 0x70, (byte) 0x9d,
-        (byte) 0x9d, (byte) 0xff, (byte) 0xe2, (byte) 0xc0, (byte) 0x7e, (byte) 0xc8, (byte) 0x03, (byte) 0x40,
-        (byte) 0xbe, (byte) 0x44, (byte) 0x09, (byte) 0xeb, (byte) 0x9e, (byte) 0x8e, (byte) 0x88, (byte) 0xe4,
-        (byte) 0x98, (byte) 0x82, (byte) 0x06, (byte) 0xa4, (byte) 0x9d, (byte) 0x63, (byte) 0x88, (byte) 0x65,
-        (byte) 0xa3, (byte) 0x8e, (byte) 0x0d, (byte) 0x22, (byte) 0xf3, (byte) 0x33, (byte) 0xf2, (byte) 0x40,
-        (byte) 0xe8, (byte) 0x91, (byte) 0x67, (byte) 0x72, (byte) 0x29, (byte) 0x1c, (byte) 0x08, (byte) 0xff,
-        (byte) 0x54, (byte) 0xa0, (byte) 0xcc, (byte) 0xad, (byte) 0x84, (byte) 0x88, (byte) 0x4b, (byte) 0x3b,
-        (byte) 0xef, (byte) 0xf9, (byte) 0x5e, (byte) 0xb3, (byte) 0x41, (byte) 0x6a, (byte) 0xbd, (byte) 0x94,
-        (byte) 0x16, (byte) 0x7d, (byte) 0x9d, (byte) 0x53, (byte) 0x77, (byte) 0xf1, (byte) 0x6a, (byte) 0x95,
-        (byte) 0x57, (byte) 0xad, (byte) 0x65, (byte) 0x9d, (byte) 0x75, (byte) 0x95, (byte) 0xf6, (byte) 0x6a,
-        (byte) 0xd2, (byte) 0x88, (byte) 0xea, (byte) 0x5b, (byte) 0xa2, (byte) 0x94, (byte) 0x8f, (byte) 0x5e,
-        (byte) 0x84, (byte) 0x18, (byte) 0x19, (byte) 0x46, (byte) 0x83, (byte) 0x0b, (byte) 0x6d, (byte) 0x5b,
-        (byte) 0xb9, (byte) 0xdb, (byte) 0xa4, (byte) 0xe5, (byte) 0x17, (byte) 0x02, (byte) 0x9e, (byte) 0x11,
-        (byte) 0xed, (byte) 0xd9, (byte) 0x7b, (byte) 0x83, (byte) 0x87, (byte) 0x89, (byte) 0xf3, (byte) 0xe4,
-        (byte) 0xbf, (byte) 0x0e, (byte) 0xe8, (byte) 0xdc, (byte) 0x55, (byte) 0x9c, (byte) 0xf7, (byte) 0xc9,
-        (byte) 0xc3, (byte) 0xe2, (byte) 0x2c, (byte) 0xf7, (byte) 0x8c, (byte) 0xaa, (byte) 0x17, (byte) 0x1f,
-        (byte) 0xd1, (byte) 0xc7, (byte) 0x74, (byte) 0xc7, (byte) 0x8e, (byte) 0x1c, (byte) 0x5b, (byte) 0xd2,
-        (byte) 0x31, (byte) 0x74, (byte) 0x43, (byte) 0x9a, (byte) 0x52, (byte) 0xbf, (byte) 0x89, (byte) 0xc5,
-        (byte) 0xb4, (byte) 0x80, (byte) 0x6a, (byte) 0x9e, (byte) 0x05, (byte) 0xdb, (byte) 0xbb, (byte) 0x07,
-        (byte) 0x8c, (byte) 0x08, (byte) 0x61, (byte) 0xba, (byte) 0xa4, (byte) 0xbc, (byte) 0x80, (byte) 0x3a,
-        (byte) 0xdd, (byte) 0x3b, (byte) 0x1a, (byte) 0x8c, (byte) 0x21, (byte) 0xd8, (byte) 0xa3, (byte) 0xc0,
-        (byte) 0xc7, (byte) 0xd1, (byte) 0x08, (byte) 0xe1, (byte) 0x34, (byte) 0x99, (byte) 0xc0, (byte) 0xcf,
-        (byte) 0x80, (byte) 0xff, (byte) 0xfa, (byte) 0x07, (byte) 0xef, (byte) 0x5c, (byte) 0x45, (byte) 0xe5,
-    };
-
-    private static final byte[] SHA384withRSA_Vector2Signature = new byte[] {
-        (byte) 0xaf, (byte) 0xf7, (byte) 0x7a, (byte) 0xc2, (byte) 0xbb, (byte) 0xb8, (byte) 0xbd, (byte) 0xe3,
-        (byte) 0x42, (byte) 0xaa, (byte) 0x16, (byte) 0x8a, (byte) 0x52, (byte) 0x6c, (byte) 0x99, (byte) 0x66,
-        (byte) 0x08, (byte) 0xbe, (byte) 0x15, (byte) 0xd9, (byte) 0x7c, (byte) 0x60, (byte) 0x2c, (byte) 0xac,
-        (byte) 0x4d, (byte) 0x4c, (byte) 0xf4, (byte) 0xdf, (byte) 0xbc, (byte) 0x16, (byte) 0x58, (byte) 0x0a,
-        (byte) 0x4e, (byte) 0xde, (byte) 0x8d, (byte) 0xb3, (byte) 0xbd, (byte) 0x03, (byte) 0x4e, (byte) 0x23,
-        (byte) 0x40, (byte) 0xa5, (byte) 0x80, (byte) 0xae, (byte) 0x83, (byte) 0xb4, (byte) 0x0f, (byte) 0x99,
-        (byte) 0x44, (byte) 0xc3, (byte) 0x5e, (byte) 0xdb, (byte) 0x59, (byte) 0x1d, (byte) 0xea, (byte) 0x7b,
-        (byte) 0x4d, (byte) 0xf3, (byte) 0xd2, (byte) 0xad, (byte) 0xbd, (byte) 0x21, (byte) 0x9f, (byte) 0x8e,
-        (byte) 0x87, (byte) 0x8f, (byte) 0x12, (byte) 0x13, (byte) 0x33, (byte) 0xf1, (byte) 0xc0, (byte) 0x9d,
-        (byte) 0xe7, (byte) 0xec, (byte) 0x6e, (byte) 0xad, (byte) 0xea, (byte) 0x5d, (byte) 0x69, (byte) 0xbb,
-        (byte) 0xab, (byte) 0x5b, (byte) 0xd8, (byte) 0x55, (byte) 0x56, (byte) 0xc8, (byte) 0xda, (byte) 0x81,
-        (byte) 0x41, (byte) 0xfb, (byte) 0xd3, (byte) 0x11, (byte) 0x6c, (byte) 0x97, (byte) 0xa7, (byte) 0xc3,
-        (byte) 0xf1, (byte) 0x31, (byte) 0xbf, (byte) 0xbe, (byte) 0x3f, (byte) 0xdb, (byte) 0x35, (byte) 0x85,
-        (byte) 0xb7, (byte) 0xb0, (byte) 0x75, (byte) 0x7f, (byte) 0xaf, (byte) 0xfb, (byte) 0x65, (byte) 0x61,
-        (byte) 0xc7, (byte) 0x0e, (byte) 0x63, (byte) 0xb5, (byte) 0x7d, (byte) 0x95, (byte) 0xe9, (byte) 0x16,
-        (byte) 0x9d, (byte) 0x6a, (byte) 0x00, (byte) 0x9f, (byte) 0x5e, (byte) 0xcd, (byte) 0xff, (byte) 0xa6,
-        (byte) 0xbc, (byte) 0x71, (byte) 0xf2, (byte) 0x2c, (byte) 0xd3, (byte) 0x68, (byte) 0xb9, (byte) 0x3f,
-        (byte) 0xaa, (byte) 0x06, (byte) 0xf1, (byte) 0x9c, (byte) 0x7e, (byte) 0xca, (byte) 0x4a, (byte) 0xfe,
-        (byte) 0xb1, (byte) 0x73, (byte) 0x19, (byte) 0x80, (byte) 0x05, (byte) 0xa6, (byte) 0x85, (byte) 0x14,
-        (byte) 0xda, (byte) 0x7a, (byte) 0x16, (byte) 0x7a, (byte) 0xc2, (byte) 0x46, (byte) 0x57, (byte) 0xa7,
-        (byte) 0xc0, (byte) 0xbf, (byte) 0xcd, (byte) 0xdc, (byte) 0x2f, (byte) 0x64, (byte) 0xf6, (byte) 0x6d,
-        (byte) 0xdc, (byte) 0xcb, (byte) 0x5a, (byte) 0x29, (byte) 0x95, (byte) 0x1c, (byte) 0xfe, (byte) 0xf2,
-        (byte) 0xda, (byte) 0x7e, (byte) 0xcb, (byte) 0x26, (byte) 0x12, (byte) 0xc6, (byte) 0xb0, (byte) 0xba,
-        (byte) 0x84, (byte) 0x9b, (byte) 0x4f, (byte) 0xba, (byte) 0x1b, (byte) 0x78, (byte) 0x25, (byte) 0xb8,
-        (byte) 0x8f, (byte) 0x2e, (byte) 0x51, (byte) 0x5f, (byte) 0x9e, (byte) 0xfc, (byte) 0x40, (byte) 0xbc,
-        (byte) 0x85, (byte) 0xcd, (byte) 0x86, (byte) 0x7f, (byte) 0x88, (byte) 0xc5, (byte) 0xaa, (byte) 0x2b,
-        (byte) 0x78, (byte) 0xb1, (byte) 0x9c, (byte) 0x51, (byte) 0x9a, (byte) 0xe1, (byte) 0xe1, (byte) 0xc0,
-        (byte) 0x40, (byte) 0x47, (byte) 0xcb, (byte) 0xa4, (byte) 0xb7, (byte) 0x6c, (byte) 0x31, (byte) 0xf2,
-        (byte) 0xc8, (byte) 0x9a, (byte) 0xad, (byte) 0x0b, (byte) 0xd3, (byte) 0xf6, (byte) 0x85, (byte) 0x9a,
-        (byte) 0x8f, (byte) 0x4f, (byte) 0xc9, (byte) 0xd8, (byte) 0x33, (byte) 0x7c, (byte) 0x45, (byte) 0x30,
-        (byte) 0xea, (byte) 0x17, (byte) 0xd3, (byte) 0xe3, (byte) 0x90, (byte) 0x2c, (byte) 0xda, (byte) 0xde,
-        (byte) 0x41, (byte) 0x17, (byte) 0x3f, (byte) 0x08, (byte) 0xb9, (byte) 0x34, (byte) 0xc0, (byte) 0xd1,
-    };
-
-    private static final byte[] SHA512withRSA_Vector2Signature = new byte[] {
-        (byte) 0x19, (byte) 0xe2, (byte) 0xe5, (byte) 0xf3, (byte) 0x18, (byte) 0x83, (byte) 0xec, (byte) 0xf0,
-        (byte) 0xab, (byte) 0x50, (byte) 0x05, (byte) 0x4b, (byte) 0x5f, (byte) 0x22, (byte) 0xfc, (byte) 0x82,
-        (byte) 0x6d, (byte) 0xca, (byte) 0xe7, (byte) 0xbe, (byte) 0x23, (byte) 0x94, (byte) 0xfa, (byte) 0xf9,
-        (byte) 0xa4, (byte) 0x8a, (byte) 0x95, (byte) 0x4d, (byte) 0x14, (byte) 0x08, (byte) 0x8b, (byte) 0x5e,
-        (byte) 0x03, (byte) 0x1b, (byte) 0x74, (byte) 0xde, (byte) 0xc1, (byte) 0x45, (byte) 0x9c, (byte) 0xce,
-        (byte) 0x1d, (byte) 0xac, (byte) 0xab, (byte) 0xd3, (byte) 0xa8, (byte) 0xc3, (byte) 0xca, (byte) 0x67,
-        (byte) 0x80, (byte) 0xf6, (byte) 0x03, (byte) 0x46, (byte) 0x65, (byte) 0x77, (byte) 0x59, (byte) 0xbb,
-        (byte) 0xb8, (byte) 0x83, (byte) 0xee, (byte) 0xc2, (byte) 0x3e, (byte) 0x78, (byte) 0xdd, (byte) 0x89,
-        (byte) 0xcd, (byte) 0x9b, (byte) 0x78, (byte) 0x35, (byte) 0xa9, (byte) 0x09, (byte) 0xc8, (byte) 0x77,
-        (byte) 0xdd, (byte) 0xd3, (byte) 0xa0, (byte) 0x64, (byte) 0xb0, (byte) 0x74, (byte) 0x48, (byte) 0x51,
-        (byte) 0x4f, (byte) 0xa0, (byte) 0xae, (byte) 0x33, (byte) 0xb3, (byte) 0x28, (byte) 0xb0, (byte) 0xa8,
-        (byte) 0x78, (byte) 0x8f, (byte) 0xa2, (byte) 0x32, (byte) 0xa6, (byte) 0x0a, (byte) 0xaa, (byte) 0x09,
-        (byte) 0xb5, (byte) 0x8d, (byte) 0x4c, (byte) 0x44, (byte) 0x46, (byte) 0xb4, (byte) 0xd2, (byte) 0x06,
-        (byte) 0x6b, (byte) 0x8c, (byte) 0x51, (byte) 0x6e, (byte) 0x9c, (byte) 0xfa, (byte) 0x1f, (byte) 0x94,
-        (byte) 0x3e, (byte) 0x19, (byte) 0x9c, (byte) 0x63, (byte) 0xfe, (byte) 0xa9, (byte) 0x9a, (byte) 0xe3,
-        (byte) 0x6c, (byte) 0x82, (byte) 0x64, (byte) 0x5f, (byte) 0xca, (byte) 0xc2, (byte) 0x8d, (byte) 0x66,
-        (byte) 0xbe, (byte) 0x12, (byte) 0x6e, (byte) 0xb6, (byte) 0x35, (byte) 0x6d, (byte) 0xaa, (byte) 0xed,
-        (byte) 0x4b, (byte) 0x50, (byte) 0x08, (byte) 0x1c, (byte) 0xbf, (byte) 0x07, (byte) 0x70, (byte) 0x78,
-        (byte) 0xc0, (byte) 0xbb, (byte) 0xc5, (byte) 0x8d, (byte) 0x6c, (byte) 0x8d, (byte) 0x35, (byte) 0xff,
-        (byte) 0x04, (byte) 0x81, (byte) 0xd8, (byte) 0xf4, (byte) 0xd2, (byte) 0x4a, (byte) 0xc3, (byte) 0x05,
-        (byte) 0x23, (byte) 0xcb, (byte) 0xeb, (byte) 0x20, (byte) 0xb1, (byte) 0xd4, (byte) 0x2d, (byte) 0xd8,
-        (byte) 0x7a, (byte) 0xd4, (byte) 0x7e, (byte) 0xf6, (byte) 0xa9, (byte) 0xe8, (byte) 0x72, (byte) 0x69,
-        (byte) 0xfe, (byte) 0xab, (byte) 0x54, (byte) 0x4d, (byte) 0xd1, (byte) 0xf4, (byte) 0x6b, (byte) 0x83,
-        (byte) 0x31, (byte) 0x17, (byte) 0xed, (byte) 0x26, (byte) 0xe9, (byte) 0xd2, (byte) 0x5b, (byte) 0xad,
-        (byte) 0x42, (byte) 0x42, (byte) 0xa5, (byte) 0x8f, (byte) 0x98, (byte) 0x7c, (byte) 0x1b, (byte) 0x5c,
-        (byte) 0x8e, (byte) 0x88, (byte) 0x56, (byte) 0x20, (byte) 0x8e, (byte) 0x48, (byte) 0xf9, (byte) 0x4d,
-        (byte) 0x82, (byte) 0x91, (byte) 0xcb, (byte) 0xc8, (byte) 0x1c, (byte) 0x7c, (byte) 0xa5, (byte) 0x69,
-        (byte) 0x1b, (byte) 0x40, (byte) 0xc2, (byte) 0x4c, (byte) 0x25, (byte) 0x16, (byte) 0x4f, (byte) 0xfa,
-        (byte) 0x09, (byte) 0xeb, (byte) 0xf5, (byte) 0x6c, (byte) 0x55, (byte) 0x3c, (byte) 0x6e, (byte) 0xf7,
-        (byte) 0xc0, (byte) 0xc1, (byte) 0x34, (byte) 0xd1, (byte) 0x53, (byte) 0xa3, (byte) 0x69, (byte) 0x64,
-        (byte) 0xee, (byte) 0xf4, (byte) 0xf9, (byte) 0xc7, (byte) 0x96, (byte) 0x60, (byte) 0x84, (byte) 0x87,
-        (byte) 0xb4, (byte) 0xc7, (byte) 0x3c, (byte) 0x26, (byte) 0xa7, (byte) 0x3a, (byte) 0xbf, (byte) 0x95,
-    };
-
-    private static final byte[] MD5withRSA_Vector2Signature = new byte[] {
-        (byte) 0x04, (byte) 0x17, (byte) 0x83, (byte) 0x10, (byte) 0xe2, (byte) 0x6e, (byte) 0xdf, (byte) 0xa9,
-        (byte) 0xae, (byte) 0xd2, (byte) 0xdc, (byte) 0x5f, (byte) 0x70, (byte) 0x1d, (byte) 0xaf, (byte) 0x54,
-        (byte) 0xc0, (byte) 0x5f, (byte) 0x0b, (byte) 0x2c, (byte) 0xe6, (byte) 0xd0, (byte) 0x00, (byte) 0x18,
-        (byte) 0x4c, (byte) 0xf6, (byte) 0x8f, (byte) 0x18, (byte) 0x10, (byte) 0x74, (byte) 0x90, (byte) 0x99,
-        (byte) 0xa9, (byte) 0x90, (byte) 0x3c, (byte) 0x5a, (byte) 0x38, (byte) 0xd3, (byte) 0x3d, (byte) 0x48,
-        (byte) 0xcf, (byte) 0x31, (byte) 0xaf, (byte) 0x12, (byte) 0x98, (byte) 0xfb, (byte) 0x66, (byte) 0xe8,
-        (byte) 0x58, (byte) 0xec, (byte) 0xca, (byte) 0xe1, (byte) 0x42, (byte) 0xf9, (byte) 0x84, (byte) 0x17,
-        (byte) 0x6f, (byte) 0x4c, (byte) 0x3e, (byte) 0xc4, (byte) 0x40, (byte) 0xc6, (byte) 0x70, (byte) 0xb0,
-        (byte) 0x38, (byte) 0xf3, (byte) 0x47, (byte) 0xeb, (byte) 0x6f, (byte) 0xcb, (byte) 0xea, (byte) 0x21,
-        (byte) 0x41, (byte) 0xf3, (byte) 0xa0, (byte) 0x3e, (byte) 0x42, (byte) 0xad, (byte) 0xa5, (byte) 0xad,
-        (byte) 0x5d, (byte) 0x2c, (byte) 0x1a, (byte) 0x8e, (byte) 0x3e, (byte) 0xb3, (byte) 0xa5, (byte) 0x78,
-        (byte) 0x3d, (byte) 0x56, (byte) 0x09, (byte) 0x93, (byte) 0xc9, (byte) 0x93, (byte) 0xd3, (byte) 0xd2,
-        (byte) 0x9a, (byte) 0xc5, (byte) 0xa5, (byte) 0x2e, (byte) 0xb2, (byte) 0xd8, (byte) 0x37, (byte) 0xc7,
-        (byte) 0x13, (byte) 0x1a, (byte) 0x0b, (byte) 0xda, (byte) 0x50, (byte) 0x28, (byte) 0x6d, (byte) 0x47,
-        (byte) 0x65, (byte) 0x52, (byte) 0xcd, (byte) 0xe7, (byte) 0xec, (byte) 0x57, (byte) 0x00, (byte) 0x41,
-        (byte) 0x34, (byte) 0x28, (byte) 0xb9, (byte) 0x8b, (byte) 0x03, (byte) 0x41, (byte) 0xb6, (byte) 0xd5,
-        (byte) 0xa8, (byte) 0xef, (byte) 0xd3, (byte) 0xdd, (byte) 0x80, (byte) 0xd5, (byte) 0x69, (byte) 0xe4,
-        (byte) 0xf0, (byte) 0x4d, (byte) 0xa4, (byte) 0x7d, (byte) 0x60, (byte) 0x2f, (byte) 0xef, (byte) 0x79,
-        (byte) 0x07, (byte) 0x75, (byte) 0xeb, (byte) 0xf7, (byte) 0x4b, (byte) 0x43, (byte) 0x41, (byte) 0xdb,
-        (byte) 0x33, (byte) 0xad, (byte) 0x9c, (byte) 0x7b, (byte) 0x78, (byte) 0x83, (byte) 0x34, (byte) 0x77,
-        (byte) 0xe4, (byte) 0x80, (byte) 0xbe, (byte) 0xe6, (byte) 0x6f, (byte) 0xdd, (byte) 0xac, (byte) 0xa5,
-        (byte) 0x37, (byte) 0xcf, (byte) 0xb5, (byte) 0x44, (byte) 0x11, (byte) 0x77, (byte) 0x96, (byte) 0x45,
-        (byte) 0xf9, (byte) 0xae, (byte) 0x48, (byte) 0xa6, (byte) 0xbe, (byte) 0x30, (byte) 0x32, (byte) 0xeb,
-        (byte) 0x43, (byte) 0x6f, (byte) 0x66, (byte) 0x39, (byte) 0x57, (byte) 0xf8, (byte) 0xe6, (byte) 0x60,
-        (byte) 0x31, (byte) 0xd0, (byte) 0xfc, (byte) 0xcf, (byte) 0x9f, (byte) 0xe5, (byte) 0x3d, (byte) 0xcf,
-        (byte) 0xbd, (byte) 0x7b, (byte) 0x13, (byte) 0x20, (byte) 0xce, (byte) 0x11, (byte) 0xfd, (byte) 0xe5,
-        (byte) 0xff, (byte) 0x90, (byte) 0x85, (byte) 0xdf, (byte) 0xca, (byte) 0x3d, (byte) 0xd9, (byte) 0x44,
-        (byte) 0x16, (byte) 0xc2, (byte) 0x32, (byte) 0x28, (byte) 0xc7, (byte) 0x01, (byte) 0x6d, (byte) 0xea,
-        (byte) 0xcb, (byte) 0x0d, (byte) 0x85, (byte) 0x08, (byte) 0x6f, (byte) 0xcb, (byte) 0x41, (byte) 0x6a,
-        (byte) 0x3c, (byte) 0x0f, (byte) 0x3d, (byte) 0x38, (byte) 0xb5, (byte) 0x61, (byte) 0xc5, (byte) 0x64,
-        (byte) 0x64, (byte) 0x81, (byte) 0x4c, (byte) 0xcd, (byte) 0xd1, (byte) 0x6a, (byte) 0x87, (byte) 0x28,
-        (byte) 0x02, (byte) 0xaf, (byte) 0x8f, (byte) 0x59, (byte) 0xe5, (byte) 0x67, (byte) 0x25, (byte) 0x00,
-    };
-
-    /*
-     * openssl rsautl -raw -sign -inkey rsa.key | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] NONEwithRSA_Vector1Signature = new byte[] {
-        (byte) 0x35, (byte) 0x43, (byte) 0x38, (byte) 0x44, (byte) 0xAD, (byte) 0x3F,
-        (byte) 0x97, (byte) 0x02, (byte) 0xFB, (byte) 0x59, (byte) 0x1F, (byte) 0x4A,
-        (byte) 0x2B, (byte) 0xB9, (byte) 0x06, (byte) 0xEC, (byte) 0x66, (byte) 0xE6,
-        (byte) 0xD2, (byte) 0xC5, (byte) 0x8B, (byte) 0x7B, (byte) 0xE3, (byte) 0x18,
-        (byte) 0xBF, (byte) 0x07, (byte) 0xD6, (byte) 0x01, (byte) 0xF9, (byte) 0xD9,
-        (byte) 0x89, (byte) 0xC4, (byte) 0xDB, (byte) 0x00, (byte) 0x68, (byte) 0xFF,
-        (byte) 0x9B, (byte) 0x43, (byte) 0x90, (byte) 0xF2, (byte) 0xDB, (byte) 0x83,
-        (byte) 0xF4, (byte) 0x7E, (byte) 0xC6, (byte) 0x81, (byte) 0x01, (byte) 0x3A,
-        (byte) 0x0B, (byte) 0xE5, (byte) 0xED, (byte) 0x08, (byte) 0x73, (byte) 0x3E,
-        (byte) 0xE1, (byte) 0x3F, (byte) 0xDF, (byte) 0x1F, (byte) 0x07, (byte) 0x6D,
-        (byte) 0x22, (byte) 0x8D, (byte) 0xCC, (byte) 0x4E, (byte) 0xE3, (byte) 0x9A,
-        (byte) 0xBC, (byte) 0xCC, (byte) 0x8F, (byte) 0x9E, (byte) 0x9B, (byte) 0x02,
-        (byte) 0x48, (byte) 0x00, (byte) 0xAC, (byte) 0x9F, (byte) 0xA4, (byte) 0x8F,
-        (byte) 0x87, (byte) 0xA1, (byte) 0xA8, (byte) 0xE6, (byte) 0x9D, (byte) 0xCD,
-        (byte) 0x8B, (byte) 0x05, (byte) 0xE9, (byte) 0xD2, (byte) 0x05, (byte) 0x8D,
-        (byte) 0xC9, (byte) 0x95, (byte) 0x16, (byte) 0xD0, (byte) 0xCD, (byte) 0x43,
-        (byte) 0x25, (byte) 0x8A, (byte) 0x11, (byte) 0x46, (byte) 0xD7, (byte) 0x74,
-        (byte) 0x4C, (byte) 0xCF, (byte) 0x58, (byte) 0xF9, (byte) 0xA1, (byte) 0x30,
-        (byte) 0x84, (byte) 0x52, (byte) 0xC9, (byte) 0x01, (byte) 0x5F, (byte) 0x24,
-        (byte) 0x4C, (byte) 0xB1, (byte) 0x9F, (byte) 0x7D, (byte) 0x12, (byte) 0x38,
-        (byte) 0x27, (byte) 0x0F, (byte) 0x5E, (byte) 0xFF, (byte) 0xE0, (byte) 0x55,
-        (byte) 0x8B, (byte) 0xA3, (byte) 0xAD, (byte) 0x60, (byte) 0x35, (byte) 0x83,
-        (byte) 0x58, (byte) 0xAF, (byte) 0x99, (byte) 0xDE, (byte) 0x3F, (byte) 0x5D,
-        (byte) 0x80, (byte) 0x80, (byte) 0xFF, (byte) 0x9B, (byte) 0xDE, (byte) 0x5C,
-        (byte) 0xAB, (byte) 0x97, (byte) 0x43, (byte) 0x64, (byte) 0xD9, (byte) 0x9F,
-        (byte) 0xFB, (byte) 0x67, (byte) 0x65, (byte) 0xA5, (byte) 0x99, (byte) 0xE7,
-        (byte) 0xE6, (byte) 0xEB, (byte) 0x05, (byte) 0x95, (byte) 0xFC, (byte) 0x46,
-        (byte) 0x28, (byte) 0x4B, (byte) 0xD8, (byte) 0x8C, (byte) 0xF5, (byte) 0x0A,
-        (byte) 0xEB, (byte) 0x1F, (byte) 0x30, (byte) 0xEA, (byte) 0xE7, (byte) 0x67,
-        (byte) 0x11, (byte) 0x25, (byte) 0xF0, (byte) 0x44, (byte) 0x75, (byte) 0x74,
-        (byte) 0x94, (byte) 0x06, (byte) 0x78, (byte) 0xD0, (byte) 0x21, (byte) 0xF4,
-        (byte) 0x3F, (byte) 0xC8, (byte) 0xC4, (byte) 0x4A, (byte) 0x57, (byte) 0xBE,
-        (byte) 0x02, (byte) 0x3C, (byte) 0x93, (byte) 0xF6, (byte) 0x95, (byte) 0xFB,
-        (byte) 0xD1, (byte) 0x77, (byte) 0x8B, (byte) 0x43, (byte) 0xF0, (byte) 0xB9,
-        (byte) 0x7D, (byte) 0xE0, (byte) 0x32, (byte) 0xE1, (byte) 0x72, (byte) 0xB5,
-        (byte) 0x62, (byte) 0x3F, (byte) 0x86, (byte) 0xC3, (byte) 0xD4, (byte) 0x5F,
-        (byte) 0x5E, (byte) 0x54, (byte) 0x1B, (byte) 0x5B, (byte) 0xE6, (byte) 0x74,
-        (byte) 0xA1, (byte) 0x0B, (byte) 0xE5, (byte) 0x18, (byte) 0xD2, (byte) 0x4F,
-        (byte) 0x93, (byte) 0xF3, (byte) 0x09, (byte) 0x58, (byte) 0xCE, (byte) 0xF0,
-        (byte) 0xA3, (byte) 0x61, (byte) 0xE4, (byte) 0x6E, (byte) 0x46, (byte) 0x45,
-        (byte) 0x89, (byte) 0x50, (byte) 0xBD, (byte) 0x03, (byte) 0x3F, (byte) 0x38,
-        (byte) 0xDA, (byte) 0x5D, (byte) 0xD0, (byte) 0x1B, (byte) 0x1F, (byte) 0xB1,
-        (byte) 0xEE, (byte) 0x89, (byte) 0x59, (byte) 0xC5,
-    };
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:20 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA1withRSAPSS_Vector2Signature = new byte[] {
-        (byte) 0x66, (byte) 0xE3, (byte) 0xA5, (byte) 0x20, (byte) 0xE9, (byte) 0x5D,
-        (byte) 0xDF, (byte) 0x99, (byte) 0xA6, (byte) 0x04, (byte) 0x77, (byte) 0xF8,
-        (byte) 0x39, (byte) 0x78, (byte) 0x74, (byte) 0xF5, (byte) 0xC2, (byte) 0x4E,
-        (byte) 0x9E, (byte) 0xEB, (byte) 0x24, (byte) 0xDE, (byte) 0xB4, (byte) 0x36,
-        (byte) 0x69, (byte) 0x1F, (byte) 0xAC, (byte) 0x01, (byte) 0xFF, (byte) 0x5A,
-        (byte) 0xE3, (byte) 0x89, (byte) 0x8A, (byte) 0xE9, (byte) 0x92, (byte) 0x32,
-        (byte) 0xA7, (byte) 0xA4, (byte) 0xC0, (byte) 0x25, (byte) 0x00, (byte) 0x14,
-        (byte) 0xFF, (byte) 0x38, (byte) 0x19, (byte) 0x37, (byte) 0x84, (byte) 0x1A,
-        (byte) 0x3D, (byte) 0xCA, (byte) 0xEE, (byte) 0xF3, (byte) 0xC6, (byte) 0x91,
-        (byte) 0xED, (byte) 0x02, (byte) 0xE6, (byte) 0x1D, (byte) 0x73, (byte) 0xDA,
-        (byte) 0xD4, (byte) 0x55, (byte) 0x93, (byte) 0x54, (byte) 0x9A, (byte) 0xE6,
-        (byte) 0x2E, (byte) 0x7D, (byte) 0x5C, (byte) 0x41, (byte) 0xAF, (byte) 0xED,
-        (byte) 0xAD, (byte) 0x8E, (byte) 0x7F, (byte) 0x47, (byte) 0x3B, (byte) 0x23,
-        (byte) 0xC3, (byte) 0xB8, (byte) 0xBB, (byte) 0xCD, (byte) 0x87, (byte) 0xC4,
-        (byte) 0xA3, (byte) 0x32, (byte) 0x16, (byte) 0x57, (byte) 0xCC, (byte) 0xB8,
-        (byte) 0xB6, (byte) 0x96, (byte) 0x84, (byte) 0x1A, (byte) 0xBC, (byte) 0xF8,
-        (byte) 0x09, (byte) 0x53, (byte) 0xB0, (byte) 0x9D, (byte) 0xE1, (byte) 0x6F,
-        (byte) 0xB2, (byte) 0xEB, (byte) 0x83, (byte) 0xDC, (byte) 0x61, (byte) 0x31,
-        (byte) 0xD7, (byte) 0x02, (byte) 0xB4, (byte) 0xD1, (byte) 0xBA, (byte) 0xBD,
-        (byte) 0xF0, (byte) 0x78, (byte) 0xC6, (byte) 0xBE, (byte) 0x1F, (byte) 0xB0,
-        (byte) 0xE1, (byte) 0xCA, (byte) 0x32, (byte) 0x57, (byte) 0x9F, (byte) 0x8C,
-        (byte) 0xD3, (byte) 0xBB, (byte) 0x04, (byte) 0x1B, (byte) 0x30, (byte) 0x74,
-        (byte) 0x5D, (byte) 0xEA, (byte) 0xD3, (byte) 0x6B, (byte) 0x74, (byte) 0x31,
-        (byte) 0x6F, (byte) 0x33, (byte) 0x5A, (byte) 0x70, (byte) 0x96, (byte) 0x8B,
-        (byte) 0xCB, (byte) 0x22, (byte) 0xF3, (byte) 0xAA, (byte) 0x74, (byte) 0x82,
-        (byte) 0xB2, (byte) 0x82, (byte) 0x71, (byte) 0x4D, (byte) 0x42, (byte) 0x13,
-        (byte) 0x3F, (byte) 0xEA, (byte) 0xE3, (byte) 0x39, (byte) 0xC5, (byte) 0x03,
-        (byte) 0x27, (byte) 0xFF, (byte) 0x78, (byte) 0xB2, (byte) 0xA6, (byte) 0x71,
-        (byte) 0x07, (byte) 0x1C, (byte) 0xB3, (byte) 0x97, (byte) 0xFB, (byte) 0xE8,
-        (byte) 0x85, (byte) 0x6D, (byte) 0x14, (byte) 0xDF, (byte) 0xF9, (byte) 0x7D,
-        (byte) 0x0D, (byte) 0x0C, (byte) 0x9F, (byte) 0xC3, (byte) 0xE2, (byte) 0xDB,
-        (byte) 0xE0, (byte) 0xA5, (byte) 0x05, (byte) 0xBC, (byte) 0x47, (byte) 0x36,
-        (byte) 0xEB, (byte) 0x1E, (byte) 0xBA, (byte) 0x60, (byte) 0x12, (byte) 0x19,
-        (byte) 0xA5, (byte) 0x7E, (byte) 0x55, (byte) 0x0C, (byte) 0x9B, (byte) 0xD4,
-        (byte) 0x9A, (byte) 0xE9, (byte) 0x72, (byte) 0x5C, (byte) 0x5B, (byte) 0xF4,
-        (byte) 0xAA, (byte) 0x4A, (byte) 0x12, (byte) 0x8B, (byte) 0xC2, (byte) 0x8E,
-        (byte) 0xC2, (byte) 0x9A, (byte) 0x3E, (byte) 0x0C, (byte) 0x40, (byte) 0xA4,
-        (byte) 0x0A, (byte) 0xFF, (byte) 0xF8, (byte) 0xC1, (byte) 0x85, (byte) 0x59,
-        (byte) 0xDA, (byte) 0xC6, (byte) 0x8C, (byte) 0x83, (byte) 0x2A, (byte) 0x68,
-        (byte) 0x84, (byte) 0x53, (byte) 0x17, (byte) 0x28, (byte) 0x78, (byte) 0x3F,
-        (byte) 0x5A, (byte) 0xA4, (byte) 0x04, (byte) 0xE6, (byte) 0x23, (byte) 0x8D,
-        (byte) 0x2A, (byte) 0x71, (byte) 0xC1, (byte) 0xBC, (byte) 0x1C, (byte) 0xFD,
-        (byte) 0x75, (byte) 0x16, (byte) 0x6E, (byte) 0x85,
-    };
-    private static final PSSParameterSpec SHA1withRSAPSS_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:0 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA1withRSAPSS_NoSalt_Vector2Signature = new byte[] {
-        (byte) 0x31, (byte) 0x61, (byte) 0xA5, (byte) 0x47, (byte) 0x28, (byte) 0x44,
-        (byte) 0x48, (byte) 0x5A, (byte) 0xDA, (byte) 0x78, (byte) 0xA7, (byte) 0x85,
-        (byte) 0xE9, (byte) 0x64, (byte) 0x69, (byte) 0xCF, (byte) 0x14, (byte) 0x07,
-        (byte) 0x3F, (byte) 0xA8, (byte) 0xDB, (byte) 0xFC, (byte) 0xB7, (byte) 0x89,
-        (byte) 0x87, (byte) 0x74, (byte) 0xB9, (byte) 0x81, (byte) 0x37, (byte) 0x62,
-        (byte) 0xD1, (byte) 0x07, (byte) 0x0F, (byte) 0x3D, (byte) 0xDF, (byte) 0xA8,
-        (byte) 0x84, (byte) 0x38, (byte) 0x31, (byte) 0xEB, (byte) 0x17, (byte) 0x3F,
-        (byte) 0xE0, (byte) 0x28, (byte) 0x75, (byte) 0x1F, (byte) 0xE9, (byte) 0x4D,
-        (byte) 0xD3, (byte) 0x62, (byte) 0xFA, (byte) 0xCF, (byte) 0xCC, (byte) 0x2E,
-        (byte) 0xC7, (byte) 0x81, (byte) 0xE1, (byte) 0xEA, (byte) 0xEC, (byte) 0x78,
-        (byte) 0xFE, (byte) 0x19, (byte) 0x59, (byte) 0x54, (byte) 0x1D, (byte) 0x27,
-        (byte) 0xED, (byte) 0x0C, (byte) 0x54, (byte) 0xDF, (byte) 0xE3, (byte) 0x44,
-        (byte) 0x31, (byte) 0x21, (byte) 0x31, (byte) 0xA7, (byte) 0x23, (byte) 0xC4,
-        (byte) 0xE2, (byte) 0x69, (byte) 0x8A, (byte) 0xB3, (byte) 0x1A, (byte) 0x72,
-        (byte) 0x4F, (byte) 0x4E, (byte) 0x82, (byte) 0x86, (byte) 0x2D, (byte) 0x2B,
-        (byte) 0x85, (byte) 0xFE, (byte) 0x4A, (byte) 0x28, (byte) 0x90, (byte) 0xF7,
-        (byte) 0xDF, (byte) 0xD6, (byte) 0xB1, (byte) 0x3E, (byte) 0xC6, (byte) 0xFB,
-        (byte) 0x76, (byte) 0x7B, (byte) 0x3D, (byte) 0x12, (byte) 0x81, (byte) 0x6E,
-        (byte) 0xFD, (byte) 0x00, (byte) 0x7D, (byte) 0xD0, (byte) 0xDC, (byte) 0x25,
-        (byte) 0xD0, (byte) 0x86, (byte) 0x6C, (byte) 0xE8, (byte) 0x0F, (byte) 0x09,
-        (byte) 0x82, (byte) 0x74, (byte) 0x89, (byte) 0x79, (byte) 0x69, (byte) 0x73,
-        (byte) 0x37, (byte) 0x64, (byte) 0xEE, (byte) 0x53, (byte) 0x57, (byte) 0x20,
-        (byte) 0xFA, (byte) 0x0B, (byte) 0x4A, (byte) 0x5A, (byte) 0x4D, (byte) 0x33,
-        (byte) 0xAC, (byte) 0x8B, (byte) 0x04, (byte) 0xA5, (byte) 0x4A, (byte) 0x1A,
-        (byte) 0x9B, (byte) 0x66, (byte) 0xAA, (byte) 0x0B, (byte) 0x3D, (byte) 0x15,
-        (byte) 0xD9, (byte) 0x3E, (byte) 0x2F, (byte) 0xD2, (byte) 0xA1, (byte) 0x28,
-        (byte) 0x13, (byte) 0x59, (byte) 0x98, (byte) 0xC3, (byte) 0x45, (byte) 0x7C,
-        (byte) 0xEE, (byte) 0x60, (byte) 0xD0, (byte) 0xBD, (byte) 0x42, (byte) 0x16,
-        (byte) 0x84, (byte) 0x19, (byte) 0xF6, (byte) 0xD9, (byte) 0xF7, (byte) 0x7D,
-        (byte) 0x77, (byte) 0xAD, (byte) 0x60, (byte) 0xE2, (byte) 0xE3, (byte) 0x22,
-        (byte) 0xB9, (byte) 0xFA, (byte) 0xD5, (byte) 0xFA, (byte) 0x6E, (byte) 0x1F,
-        (byte) 0x69, (byte) 0x3F, (byte) 0xB1, (byte) 0xA7, (byte) 0x1A, (byte) 0x22,
-        (byte) 0xF7, (byte) 0x31, (byte) 0x97, (byte) 0x68, (byte) 0x62, (byte) 0x0F,
-        (byte) 0x39, (byte) 0xB0, (byte) 0xE7, (byte) 0x63, (byte) 0xAE, (byte) 0x65,
-        (byte) 0x69, (byte) 0xD0, (byte) 0xD3, (byte) 0x56, (byte) 0xC9, (byte) 0xA6,
-        (byte) 0xA4, (byte) 0xA5, (byte) 0xA4, (byte) 0x61, (byte) 0xA9, (byte) 0xC4,
-        (byte) 0x45, (byte) 0xCD, (byte) 0x49, (byte) 0x76, (byte) 0xC8, (byte) 0x53,
-        (byte) 0x46, (byte) 0xD0, (byte) 0x63, (byte) 0x35, (byte) 0x89, (byte) 0x04,
-        (byte) 0x22, (byte) 0xD7, (byte) 0xB6, (byte) 0x63, (byte) 0xAF, (byte) 0xC2,
-        (byte) 0x97, (byte) 0x10, (byte) 0xDF, (byte) 0xDE, (byte) 0xE6, (byte) 0x39,
-        (byte) 0x25, (byte) 0x2F, (byte) 0xEA, (byte) 0xD8, (byte) 0x56, (byte) 0x5A,
-        (byte) 0xC1, (byte) 0xB8, (byte) 0xCA, (byte) 0xC1, (byte) 0x8A, (byte) 0xB8,
-        (byte) 0x87, (byte) 0x2F, (byte) 0xCD, (byte) 0x21,
-    };
-    private static final PSSParameterSpec SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 0, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:234 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA1withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
-        (byte) 0x49, (byte) 0xDB, (byte) 0xAD, (byte) 0x48, (byte) 0x7C, (byte) 0x06,
-        (byte) 0x03, (byte) 0x7C, (byte) 0x58, (byte) 0xE1, (byte) 0x38, (byte) 0x20,
-        (byte) 0x46, (byte) 0x28, (byte) 0x60, (byte) 0x64, (byte) 0x94, (byte) 0x51,
-        (byte) 0xA3, (byte) 0xD1, (byte) 0xC9, (byte) 0x52, (byte) 0xC6, (byte) 0x2A,
-        (byte) 0xB3, (byte) 0xCC, (byte) 0xD6, (byte) 0x19, (byte) 0x50, (byte) 0x99,
-        (byte) 0x60, (byte) 0x58, (byte) 0xA2, (byte) 0x86, (byte) 0xA8, (byte) 0x74,
-        (byte) 0x50, (byte) 0x8C, (byte) 0x0E, (byte) 0x32, (byte) 0x58, (byte) 0x56,
-        (byte) 0x6D, (byte) 0x30, (byte) 0x38, (byte) 0xFB, (byte) 0x26, (byte) 0xC3,
-        (byte) 0xFD, (byte) 0x8E, (byte) 0x36, (byte) 0x73, (byte) 0x82, (byte) 0x9A,
-        (byte) 0xB4, (byte) 0xE5, (byte) 0x22, (byte) 0x96, (byte) 0x55, (byte) 0x3C,
-        (byte) 0x18, (byte) 0xD7, (byte) 0x46, (byte) 0xF1, (byte) 0x7C, (byte) 0xE6,
-        (byte) 0x8E, (byte) 0x0A, (byte) 0x18, (byte) 0xA7, (byte) 0x29, (byte) 0x96,
-        (byte) 0x8D, (byte) 0xFC, (byte) 0x0E, (byte) 0xBE, (byte) 0x91, (byte) 0xA0,
-        (byte) 0xF8, (byte) 0xE2, (byte) 0x70, (byte) 0x5A, (byte) 0xE3, (byte) 0x76,
-        (byte) 0xAC, (byte) 0x18, (byte) 0x10, (byte) 0xB4, (byte) 0xB1, (byte) 0xFF,
-        (byte) 0x58, (byte) 0xBC, (byte) 0x10, (byte) 0xF5, (byte) 0x88, (byte) 0x2F,
-        (byte) 0x0B, (byte) 0x10, (byte) 0x9D, (byte) 0x52, (byte) 0x2D, (byte) 0x42,
-        (byte) 0xDB, (byte) 0xFD, (byte) 0xA7, (byte) 0x23, (byte) 0x3C, (byte) 0x4B,
-        (byte) 0xB3, (byte) 0xD2, (byte) 0x96, (byte) 0x1B, (byte) 0xCE, (byte) 0xB3,
-        (byte) 0xA3, (byte) 0xC3, (byte) 0x42, (byte) 0xA4, (byte) 0x0E, (byte) 0x35,
-        (byte) 0x5C, (byte) 0xC2, (byte) 0x32, (byte) 0xC7, (byte) 0x8C, (byte) 0xFC,
-        (byte) 0x7F, (byte) 0xE0, (byte) 0xF7, (byte) 0x1D, (byte) 0x38, (byte) 0x21,
-        (byte) 0x3C, (byte) 0xDF, (byte) 0x82, (byte) 0x1A, (byte) 0xBD, (byte) 0x83,
-        (byte) 0xE9, (byte) 0x56, (byte) 0xF0, (byte) 0xF1, (byte) 0x54, (byte) 0x76,
-        (byte) 0xE3, (byte) 0xCE, (byte) 0x86, (byte) 0x69, (byte) 0xC2, (byte) 0x61,
-        (byte) 0x6D, (byte) 0x8E, (byte) 0xF5, (byte) 0xA3, (byte) 0x61, (byte) 0xCA,
-        (byte) 0x16, (byte) 0xCB, (byte) 0x7A, (byte) 0xF5, (byte) 0xBF, (byte) 0x36,
-        (byte) 0xCB, (byte) 0x7D, (byte) 0xB1, (byte) 0xE9, (byte) 0x70, (byte) 0x41,
-        (byte) 0xCF, (byte) 0x89, (byte) 0x51, (byte) 0x13, (byte) 0xCC, (byte) 0x95,
-        (byte) 0x50, (byte) 0xC8, (byte) 0xB6, (byte) 0x30, (byte) 0x35, (byte) 0xE3,
-        (byte) 0x13, (byte) 0x08, (byte) 0xF6, (byte) 0xBE, (byte) 0x20, (byte) 0xF1,
-        (byte) 0x48, (byte) 0x4D, (byte) 0x46, (byte) 0x95, (byte) 0xFE, (byte) 0x9E,
-        (byte) 0xD2, (byte) 0xD5, (byte) 0x29, (byte) 0x81, (byte) 0x2E, (byte) 0x0F,
-        (byte) 0x6F, (byte) 0xA7, (byte) 0x02, (byte) 0x15, (byte) 0xCA, (byte) 0x75,
-        (byte) 0x77, (byte) 0x29, (byte) 0x7C, (byte) 0x3A, (byte) 0xE3, (byte) 0x2B,
-        (byte) 0xD7, (byte) 0x3D, (byte) 0x5C, (byte) 0x94, (byte) 0x3B, (byte) 0x2A,
-        (byte) 0x91, (byte) 0xDB, (byte) 0xFA, (byte) 0x69, (byte) 0x47, (byte) 0x1C,
-        (byte) 0x2C, (byte) 0x46, (byte) 0x49, (byte) 0xE6, (byte) 0x37, (byte) 0x5D,
-        (byte) 0x78, (byte) 0x71, (byte) 0x76, (byte) 0xC1, (byte) 0xB6, (byte) 0x2E,
-        (byte) 0x4E, (byte) 0x3C, (byte) 0x83, (byte) 0x6F, (byte) 0x82, (byte) 0xC3,
-        (byte) 0xD8, (byte) 0x50, (byte) 0xD7, (byte) 0x1B, (byte) 0xAF, (byte) 0xF9,
-        (byte) 0xE3, (byte) 0xF1, (byte) 0x47, (byte) 0xC8, (byte) 0x12, (byte) 0x86,
-        (byte) 0x82, (byte) 0x9D, (byte) 0x3F, (byte) 0xCE,
-    };
-    private static final PSSParameterSpec SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 234, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:28 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA224withRSAPSS_Vector2Signature = new byte[] {
-        (byte) 0x86, (byte) 0x41, (byte) 0xCC, (byte) 0x4B, (byte) 0x82, (byte) 0x74,
-        (byte) 0x04, (byte) 0x43, (byte) 0x8C, (byte) 0xAB, (byte) 0xF6, (byte) 0x3B,
-        (byte) 0xFB, (byte) 0x94, (byte) 0xBC, (byte) 0x4C, (byte) 0x0A, (byte) 0xFE,
-        (byte) 0x0F, (byte) 0x4F, (byte) 0x0F, (byte) 0x9F, (byte) 0x84, (byte) 0x35,
-        (byte) 0x57, (byte) 0x8B, (byte) 0x8D, (byte) 0xC3, (byte) 0x58, (byte) 0xA6,
-        (byte) 0x70, (byte) 0xAC, (byte) 0x40, (byte) 0x6D, (byte) 0xBC, (byte) 0xC1,
-        (byte) 0x6A, (byte) 0xFA, (byte) 0x31, (byte) 0x3B, (byte) 0x7A, (byte) 0x23,
-        (byte) 0xCA, (byte) 0x1F, (byte) 0xCD, (byte) 0xA7, (byte) 0xE3, (byte) 0xD6,
-        (byte) 0x7C, (byte) 0x2C, (byte) 0xF3, (byte) 0x6F, (byte) 0xF5, (byte) 0x82,
-        (byte) 0x9E, (byte) 0x18, (byte) 0x70, (byte) 0x90, (byte) 0xE6, (byte) 0xA3,
-        (byte) 0x44, (byte) 0x61, (byte) 0xB6, (byte) 0x46, (byte) 0x9B, (byte) 0x0D,
-        (byte) 0xE5, (byte) 0x3C, (byte) 0xAE, (byte) 0x22, (byte) 0xF4, (byte) 0x87,
-        (byte) 0xB7, (byte) 0x03, (byte) 0xD8, (byte) 0x42, (byte) 0x33, (byte) 0x4E,
-        (byte) 0xCC, (byte) 0x7A, (byte) 0xDF, (byte) 0xD7, (byte) 0x57, (byte) 0xEB,
-        (byte) 0x51, (byte) 0x6C, (byte) 0xB1, (byte) 0x99, (byte) 0x4D, (byte) 0x94,
-        (byte) 0x82, (byte) 0xA7, (byte) 0x69, (byte) 0x85, (byte) 0x8D, (byte) 0x82,
-        (byte) 0x18, (byte) 0xE4, (byte) 0x53, (byte) 0xF5, (byte) 0x9F, (byte) 0x82,
-        (byte) 0x1C, (byte) 0xE1, (byte) 0x25, (byte) 0x1C, (byte) 0x8E, (byte) 0xE7,
-        (byte) 0xC1, (byte) 0xEC, (byte) 0xBE, (byte) 0x3F, (byte) 0xC3, (byte) 0xED,
-        (byte) 0x41, (byte) 0x89, (byte) 0x94, (byte) 0x13, (byte) 0x11, (byte) 0x75,
-        (byte) 0x3F, (byte) 0x38, (byte) 0x52, (byte) 0x58, (byte) 0xAB, (byte) 0x88,
-        (byte) 0x01, (byte) 0x30, (byte) 0xB4, (byte) 0xCD, (byte) 0x45, (byte) 0x3E,
-        (byte) 0x1A, (byte) 0x5F, (byte) 0x36, (byte) 0xF8, (byte) 0x51, (byte) 0x90,
-        (byte) 0x6E, (byte) 0x6F, (byte) 0x31, (byte) 0x9D, (byte) 0x40, (byte) 0x90,
-        (byte) 0x1A, (byte) 0xA8, (byte) 0x10, (byte) 0xEF, (byte) 0x9D, (byte) 0xF8,
-        (byte) 0xB0, (byte) 0x03, (byte) 0x01, (byte) 0xFB, (byte) 0xD8, (byte) 0x3D,
-        (byte) 0x83, (byte) 0x79, (byte) 0x01, (byte) 0xA7, (byte) 0x82, (byte) 0xC2,
-        (byte) 0x46, (byte) 0x35, (byte) 0x68, (byte) 0xD2, (byte) 0x08, (byte) 0x81,
-        (byte) 0x31, (byte) 0x14, (byte) 0xE8, (byte) 0x13, (byte) 0x8C, (byte) 0xD4,
-        (byte) 0xC4, (byte) 0xCB, (byte) 0xB9, (byte) 0x85, (byte) 0x25, (byte) 0x93,
-        (byte) 0x40, (byte) 0x88, (byte) 0x34, (byte) 0x11, (byte) 0xDA, (byte) 0xFF,
-        (byte) 0xEF, (byte) 0x4D, (byte) 0xDC, (byte) 0x31, (byte) 0x74, (byte) 0x7B,
-        (byte) 0x5E, (byte) 0xA7, (byte) 0x51, (byte) 0x15, (byte) 0x13, (byte) 0xB1,
-        (byte) 0x9E, (byte) 0x06, (byte) 0x51, (byte) 0xBA, (byte) 0x11, (byte) 0xDA,
-        (byte) 0x64, (byte) 0x1B, (byte) 0x78, (byte) 0x76, (byte) 0x57, (byte) 0x96,
-        (byte) 0xF3, (byte) 0x1B, (byte) 0x86, (byte) 0xB2, (byte) 0xF3, (byte) 0x66,
-        (byte) 0x64, (byte) 0x2B, (byte) 0x04, (byte) 0x81, (byte) 0x8C, (byte) 0xDC,
-        (byte) 0xE0, (byte) 0xEA, (byte) 0x66, (byte) 0x62, (byte) 0x44, (byte) 0x31,
-        (byte) 0xA2, (byte) 0x19, (byte) 0xF1, (byte) 0x77, (byte) 0x67, (byte) 0x58,
-        (byte) 0x18, (byte) 0x5B, (byte) 0xCB, (byte) 0xBA, (byte) 0x28, (byte) 0x91,
-        (byte) 0x47, (byte) 0x5B, (byte) 0x4F, (byte) 0x17, (byte) 0x23, (byte) 0x2A,
-        (byte) 0xE4, (byte) 0xB0, (byte) 0xAE, (byte) 0x82, (byte) 0x4E, (byte) 0xCA,
-        (byte) 0xA6, (byte) 0x12, (byte) 0xCA, (byte) 0x70,
-    };
-    private static final PSSParameterSpec SHA224withRSAPSS_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 28, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:0 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA224withRSAPSS_NoSalt_Vector2Signature = new byte[] {
-        (byte) 0xD8, (byte) 0x38, (byte) 0x48, (byte) 0xCD, (byte) 0xA4, (byte) 0x09,
-        (byte) 0x36, (byte) 0x35, (byte) 0x47, (byte) 0x55, (byte) 0xDB, (byte) 0x6C,
-        (byte) 0x2D, (byte) 0x83, (byte) 0x17, (byte) 0x10, (byte) 0x3E, (byte) 0xCE,
-        (byte) 0x95, (byte) 0x02, (byte) 0x58, (byte) 0xCE, (byte) 0xA8, (byte) 0x02,
-        (byte) 0x44, (byte) 0xB7, (byte) 0xE4, (byte) 0x32, (byte) 0x3D, (byte) 0x50,
-        (byte) 0xE1, (byte) 0x8C, (byte) 0xF3, (byte) 0x24, (byte) 0x6F, (byte) 0xA4,
-        (byte) 0x2D, (byte) 0xD7, (byte) 0xFB, (byte) 0x70, (byte) 0x97, (byte) 0xBE,
-        (byte) 0xED, (byte) 0x27, (byte) 0x2D, (byte) 0x22, (byte) 0xDC, (byte) 0x62,
-        (byte) 0x97, (byte) 0x66, (byte) 0x39, (byte) 0xE0, (byte) 0x36, (byte) 0x5F,
-        (byte) 0x07, (byte) 0x78, (byte) 0xAF, (byte) 0x5E, (byte) 0xDC, (byte) 0xFD,
-        (byte) 0x21, (byte) 0xA8, (byte) 0xD5, (byte) 0xA7, (byte) 0xD1, (byte) 0xBA,
-        (byte) 0x1C, (byte) 0xDA, (byte) 0xCA, (byte) 0x80, (byte) 0x72, (byte) 0x8A,
-        (byte) 0xDD, (byte) 0x5C, (byte) 0x16, (byte) 0x6A, (byte) 0x47, (byte) 0xFC,
-        (byte) 0x11, (byte) 0x42, (byte) 0x7E, (byte) 0x4E, (byte) 0x3F, (byte) 0x49,
-        (byte) 0xCF, (byte) 0x2F, (byte) 0x54, (byte) 0xD7, (byte) 0x13, (byte) 0x76,
-        (byte) 0x5D, (byte) 0xE9, (byte) 0x2A, (byte) 0x29, (byte) 0xCC, (byte) 0x73,
-        (byte) 0xDB, (byte) 0xE5, (byte) 0xDE, (byte) 0x48, (byte) 0xA2, (byte) 0xE9,
-        (byte) 0xD1, (byte) 0xD0, (byte) 0x35, (byte) 0xFE, (byte) 0xA1, (byte) 0x1C,
-        (byte) 0x13, (byte) 0x04, (byte) 0x75, (byte) 0x77, (byte) 0xF4, (byte) 0x55,
-        (byte) 0x03, (byte) 0xC4, (byte) 0x6D, (byte) 0xAC, (byte) 0x25, (byte) 0x1D,
-        (byte) 0x57, (byte) 0xFF, (byte) 0x0D, (byte) 0xE0, (byte) 0x91, (byte) 0xEA,
-        (byte) 0xF6, (byte) 0x1F, (byte) 0x3F, (byte) 0x69, (byte) 0xD6, (byte) 0x00,
-        (byte) 0xBD, (byte) 0x89, (byte) 0xEA, (byte) 0xD3, (byte) 0x31, (byte) 0x80,
-        (byte) 0x5E, (byte) 0x04, (byte) 0x4C, (byte) 0x59, (byte) 0xDE, (byte) 0xD0,
-        (byte) 0x62, (byte) 0x93, (byte) 0x3B, (byte) 0xC9, (byte) 0x9F, (byte) 0xE7,
-        (byte) 0x69, (byte) 0xC0, (byte) 0xB8, (byte) 0xED, (byte) 0xBF, (byte) 0x0D,
-        (byte) 0x60, (byte) 0x28, (byte) 0x55, (byte) 0x20, (byte) 0x0C, (byte) 0x9F,
-        (byte) 0xA2, (byte) 0x42, (byte) 0x34, (byte) 0x95, (byte) 0xAE, (byte) 0xF8,
-        (byte) 0x67, (byte) 0x7C, (byte) 0xF1, (byte) 0xA0, (byte) 0xC0, (byte) 0x74,
-        (byte) 0xF2, (byte) 0xDF, (byte) 0x75, (byte) 0x5B, (byte) 0x6E, (byte) 0x2F,
-        (byte) 0xFB, (byte) 0x1F, (byte) 0xDD, (byte) 0xC3, (byte) 0xD3, (byte) 0x90,
-        (byte) 0x0A, (byte) 0x33, (byte) 0xF6, (byte) 0x03, (byte) 0x16, (byte) 0xC4,
-        (byte) 0xF8, (byte) 0xED, (byte) 0xB7, (byte) 0x45, (byte) 0x39, (byte) 0x5D,
-        (byte) 0x7C, (byte) 0xF8, (byte) 0x82, (byte) 0xCE, (byte) 0x7D, (byte) 0xFB,
-        (byte) 0x02, (byte) 0x2D, (byte) 0xE0, (byte) 0x96, (byte) 0x35, (byte) 0x60,
-        (byte) 0x5D, (byte) 0xBC, (byte) 0x35, (byte) 0x80, (byte) 0x4C, (byte) 0x39,
-        (byte) 0x7C, (byte) 0xE7, (byte) 0xD4, (byte) 0xB4, (byte) 0x19, (byte) 0xD1,
-        (byte) 0xE5, (byte) 0x8E, (byte) 0x6D, (byte) 0x25, (byte) 0x0C, (byte) 0xB9,
-        (byte) 0x0C, (byte) 0x8D, (byte) 0x45, (byte) 0xE4, (byte) 0x67, (byte) 0x73,
-        (byte) 0xCF, (byte) 0x87, (byte) 0x7C, (byte) 0x78, (byte) 0xAA, (byte) 0xB9,
-        (byte) 0x42, (byte) 0xAE, (byte) 0x7F, (byte) 0xB8, (byte) 0xEC, (byte) 0x4F,
-        (byte) 0xD2, (byte) 0x85, (byte) 0x01, (byte) 0x80, (byte) 0x00, (byte) 0xBD,
-        (byte) 0xF5, (byte) 0xEA, (byte) 0x44, (byte) 0x6D,
-    };
-    private static final PSSParameterSpec SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 0, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:226 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA224withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
-        (byte) 0x2C, (byte) 0x19, (byte) 0x5E, (byte) 0x63, (byte) 0xC5, (byte) 0x32,
-        (byte) 0xC3, (byte) 0xC7, (byte) 0x52, (byte) 0xE9, (byte) 0x69, (byte) 0x4C,
-        (byte) 0x04, (byte) 0xE5, (byte) 0x4A, (byte) 0xF2, (byte) 0x72, (byte) 0x78,
-        (byte) 0xBF, (byte) 0xC5, (byte) 0x8D, (byte) 0x5A, (byte) 0x71, (byte) 0xEF,
-        (byte) 0xA9, (byte) 0x58, (byte) 0x77, (byte) 0x94, (byte) 0x49, (byte) 0x71,
-        (byte) 0xBF, (byte) 0x45, (byte) 0x3E, (byte) 0xA4, (byte) 0x2E, (byte) 0x33,
-        (byte) 0x9B, (byte) 0x4E, (byte) 0xA4, (byte) 0x95, (byte) 0x07, (byte) 0x9C,
-        (byte) 0xAA, (byte) 0xC4, (byte) 0xA8, (byte) 0x60, (byte) 0xBC, (byte) 0xCD,
-        (byte) 0xC3, (byte) 0x45, (byte) 0xE6, (byte) 0xBC, (byte) 0xAD, (byte) 0xB6,
-        (byte) 0xF3, (byte) 0x0E, (byte) 0xF6, (byte) 0xD5, (byte) 0xCF, (byte) 0x33,
-        (byte) 0xA3, (byte) 0x82, (byte) 0x62, (byte) 0x52, (byte) 0x95, (byte) 0xA8,
-        (byte) 0x0E, (byte) 0xD4, (byte) 0xAC, (byte) 0x1F, (byte) 0x9A, (byte) 0xDC,
-        (byte) 0x00, (byte) 0xD6, (byte) 0x78, (byte) 0xEA, (byte) 0x53, (byte) 0x00,
-        (byte) 0x19, (byte) 0xE3, (byte) 0x81, (byte) 0x7C, (byte) 0x7A, (byte) 0x8E,
-        (byte) 0x30, (byte) 0x57, (byte) 0xB7, (byte) 0x81, (byte) 0xD7, (byte) 0x4D,
-        (byte) 0x1D, (byte) 0xCB, (byte) 0x99, (byte) 0x8D, (byte) 0xE4, (byte) 0xFA,
-        (byte) 0x6E, (byte) 0x4E, (byte) 0xA6, (byte) 0xDA, (byte) 0x13, (byte) 0x92,
-        (byte) 0x31, (byte) 0x7C, (byte) 0x2B, (byte) 0x3A, (byte) 0xA0, (byte) 0xF1,
-        (byte) 0x03, (byte) 0x83, (byte) 0x12, (byte) 0xD1, (byte) 0x23, (byte) 0xED,
-        (byte) 0xC4, (byte) 0x01, (byte) 0x57, (byte) 0x63, (byte) 0xAF, (byte) 0x40,
-        (byte) 0x15, (byte) 0xEC, (byte) 0xB8, (byte) 0x5A, (byte) 0xCE, (byte) 0x3D,
-        (byte) 0x3E, (byte) 0xCD, (byte) 0xD8, (byte) 0xF3, (byte) 0x76, (byte) 0xCA,
-        (byte) 0x23, (byte) 0x20, (byte) 0x68, (byte) 0x17, (byte) 0x5B, (byte) 0x7F,
-        (byte) 0xBC, (byte) 0x22, (byte) 0x67, (byte) 0x2A, (byte) 0x91, (byte) 0x05,
-        (byte) 0xB3, (byte) 0x85, (byte) 0x60, (byte) 0xD8, (byte) 0x76, (byte) 0xD5,
-        (byte) 0x2B, (byte) 0x9C, (byte) 0x80, (byte) 0xB6, (byte) 0xEA, (byte) 0x1E,
-        (byte) 0x05, (byte) 0xC7, (byte) 0x95, (byte) 0x2C, (byte) 0x4F, (byte) 0x14,
-        (byte) 0x5F, (byte) 0xEE, (byte) 0x08, (byte) 0x32, (byte) 0xF7, (byte) 0x12,
-        (byte) 0x2B, (byte) 0xCD, (byte) 0xF3, (byte) 0x83, (byte) 0x7C, (byte) 0xCE,
-        (byte) 0x04, (byte) 0x8A, (byte) 0x36, (byte) 0x3D, (byte) 0xB2, (byte) 0x97,
-        (byte) 0x15, (byte) 0xDB, (byte) 0xD6, (byte) 0xFA, (byte) 0x53, (byte) 0x29,
-        (byte) 0xD1, (byte) 0x43, (byte) 0x55, (byte) 0xDD, (byte) 0xAE, (byte) 0xA7,
-        (byte) 0xB4, (byte) 0x2C, (byte) 0xD9, (byte) 0xA7, (byte) 0x74, (byte) 0xA8,
-        (byte) 0x08, (byte) 0xD6, (byte) 0xC2, (byte) 0x05, (byte) 0xBF, (byte) 0x67,
-        (byte) 0x3B, (byte) 0xBA, (byte) 0x8D, (byte) 0x99, (byte) 0xC1, (byte) 0x14,
-        (byte) 0x1A, (byte) 0x32, (byte) 0xCA, (byte) 0xD5, (byte) 0xCC, (byte) 0xF9,
-        (byte) 0x64, (byte) 0x07, (byte) 0x5B, (byte) 0xB8, (byte) 0xA9, (byte) 0x69,
-        (byte) 0xED, (byte) 0x01, (byte) 0xCD, (byte) 0xD2, (byte) 0x88, (byte) 0x67,
-        (byte) 0xFF, (byte) 0x92, (byte) 0xA3, (byte) 0xC6, (byte) 0x97, (byte) 0x97,
-        (byte) 0xA1, (byte) 0xC5, (byte) 0x15, (byte) 0xC8, (byte) 0xB6, (byte) 0xFE,
-        (byte) 0x4A, (byte) 0x07, (byte) 0x2E, (byte) 0x46, (byte) 0x3F, (byte) 0x27,
-        (byte) 0xB8, (byte) 0xEE, (byte) 0x69, (byte) 0xCB, (byte) 0xDC, (byte) 0x30,
-        (byte) 0x19, (byte) 0x77, (byte) 0xC5, (byte) 0xEF,
-    };
-    private static final PSSParameterSpec SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 226, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:32 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA256withRSAPSS_Vector2Signature = new byte[] {
-        (byte) 0x94, (byte) 0x33, (byte) 0xCB, (byte) 0x9E, (byte) 0x2C, (byte) 0x17,
-        (byte) 0x46, (byte) 0xB3, (byte) 0x8F, (byte) 0xB7, (byte) 0x93, (byte) 0x98,
-        (byte) 0xA3, (byte) 0x45, (byte) 0xEA, (byte) 0xD4, (byte) 0x51, (byte) 0x60,
-        (byte) 0x3E, (byte) 0x00, (byte) 0xA3, (byte) 0x93, (byte) 0x05, (byte) 0x0F,
-        (byte) 0xCB, (byte) 0x6E, (byte) 0xFF, (byte) 0xA5, (byte) 0x97, (byte) 0x18,
-        (byte) 0xF6, (byte) 0xED, (byte) 0x6B, (byte) 0x6C, (byte) 0xAD, (byte) 0x9C,
-        (byte) 0x73, (byte) 0x63, (byte) 0x9C, (byte) 0x5B, (byte) 0xA5, (byte) 0xA1,
-        (byte) 0x42, (byte) 0xA3, (byte) 0x0E, (byte) 0x32, (byte) 0xF5, (byte) 0xF0,
-        (byte) 0x55, (byte) 0xEE, (byte) 0x58, (byte) 0xC1, (byte) 0xBD, (byte) 0x99,
-        (byte) 0x0A, (byte) 0x2B, (byte) 0xFD, (byte) 0xBD, (byte) 0x1E, (byte) 0x23,
-        (byte) 0xEF, (byte) 0x99, (byte) 0x7D, (byte) 0xC1, (byte) 0xE2, (byte) 0xD5,
-        (byte) 0x71, (byte) 0x6C, (byte) 0x96, (byte) 0x70, (byte) 0xC3, (byte) 0x75,
-        (byte) 0x48, (byte) 0x83, (byte) 0x85, (byte) 0x5E, (byte) 0xC6, (byte) 0x3A,
-        (byte) 0xFF, (byte) 0xE5, (byte) 0xF1, (byte) 0x6B, (byte) 0x85, (byte) 0x7B,
-        (byte) 0x61, (byte) 0xA6, (byte) 0xB1, (byte) 0xCF, (byte) 0x60, (byte) 0x09,
-        (byte) 0x32, (byte) 0xAF, (byte) 0xEF, (byte) 0x95, (byte) 0xA4, (byte) 0x1B,
-        (byte) 0xD6, (byte) 0xFA, (byte) 0xD0, (byte) 0xD7, (byte) 0x17, (byte) 0xCA,
-        (byte) 0xB0, (byte) 0x19, (byte) 0x21, (byte) 0x7F, (byte) 0x5E, (byte) 0x9B,
-        (byte) 0xBB, (byte) 0xB8, (byte) 0xE0, (byte) 0xB1, (byte) 0x95, (byte) 0xB3,
-        (byte) 0xDA, (byte) 0x0B, (byte) 0xB8, (byte) 0xFA, (byte) 0x15, (byte) 0x75,
-        (byte) 0x73, (byte) 0x88, (byte) 0xC8, (byte) 0x45, (byte) 0x33, (byte) 0xD1,
-        (byte) 0x5C, (byte) 0xB7, (byte) 0xFB, (byte) 0x38, (byte) 0x05, (byte) 0xA0,
-        (byte) 0x85, (byte) 0x99, (byte) 0x2C, (byte) 0xB1, (byte) 0xC2, (byte) 0xFE,
-        (byte) 0xAC, (byte) 0x5D, (byte) 0x2C, (byte) 0x1B, (byte) 0xD3, (byte) 0x42,
-        (byte) 0x81, (byte) 0xC8, (byte) 0x1C, (byte) 0xB7, (byte) 0x53, (byte) 0x7E,
-        (byte) 0xC5, (byte) 0x9F, (byte) 0x84, (byte) 0x97, (byte) 0x6F, (byte) 0x00,
-        (byte) 0xC3, (byte) 0x5E, (byte) 0x8B, (byte) 0x67, (byte) 0x3D, (byte) 0x9A,
-        (byte) 0xD0, (byte) 0xE2, (byte) 0x9B, (byte) 0x2D, (byte) 0xC6, (byte) 0xD8,
-        (byte) 0xEF, (byte) 0x19, (byte) 0x14, (byte) 0x49, (byte) 0x88, (byte) 0x52,
-        (byte) 0xF7, (byte) 0x93, (byte) 0xEB, (byte) 0xDB, (byte) 0xB6, (byte) 0x55,
-        (byte) 0x05, (byte) 0xB6, (byte) 0xE7, (byte) 0x70, (byte) 0xE4, (byte) 0x5A,
-        (byte) 0x9E, (byte) 0x80, (byte) 0x78, (byte) 0x48, (byte) 0xA8, (byte) 0xE5,
-        (byte) 0x59, (byte) 0x8D, (byte) 0x1C, (byte) 0x5D, (byte) 0x95, (byte) 0x38,
-        (byte) 0x25, (byte) 0xFC, (byte) 0x38, (byte) 0xC3, (byte) 0xFF, (byte) 0xE2,
-        (byte) 0x6F, (byte) 0xE4, (byte) 0xFC, (byte) 0x64, (byte) 0x8B, (byte) 0xCA,
-        (byte) 0x91, (byte) 0x5F, (byte) 0x0B, (byte) 0x4E, (byte) 0x9A, (byte) 0xB5,
-        (byte) 0x22, (byte) 0x5D, (byte) 0xC5, (byte) 0x5A, (byte) 0x77, (byte) 0xED,
-        (byte) 0x23, (byte) 0xE0, (byte) 0x13, (byte) 0x8F, (byte) 0xAC, (byte) 0x13,
-        (byte) 0xE5, (byte) 0x81, (byte) 0xEE, (byte) 0xD1, (byte) 0xAD, (byte) 0x8A,
-        (byte) 0x0F, (byte) 0x2B, (byte) 0x4C, (byte) 0xB2, (byte) 0x13, (byte) 0x54,
-        (byte) 0x44, (byte) 0x8E, (byte) 0x53, (byte) 0xE2, (byte) 0x33, (byte) 0x14,
-        (byte) 0x7F, (byte) 0x9B, (byte) 0xA9, (byte) 0xD3, (byte) 0xBB, (byte) 0xFC,
-        (byte) 0xAC, (byte) 0xC9, (byte) 0x31, (byte) 0xB6,
-    };
-    private static final PSSParameterSpec SHA256withRSAPSS_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:0 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA256withRSAPSS_NoSalt_Vector2Signature = new byte[] {
-        (byte) 0x4C, (byte) 0xB7, (byte) 0x33, (byte) 0x78, (byte) 0x0A, (byte) 0xA7,
-        (byte) 0xEB, (byte) 0x35, (byte) 0x5E, (byte) 0x99, (byte) 0x8F, (byte) 0xE9,
-        (byte) 0x2A, (byte) 0x3D, (byte) 0x8C, (byte) 0x9B, (byte) 0x19, (byte) 0xC7,
-        (byte) 0xC8, (byte) 0xB8, (byte) 0x10, (byte) 0xC5, (byte) 0x6D, (byte) 0xA4,
-        (byte) 0x44, (byte) 0x3E, (byte) 0xAB, (byte) 0x90, (byte) 0x82, (byte) 0x70,
-        (byte) 0xFA, (byte) 0x7B, (byte) 0xE6, (byte) 0x06, (byte) 0x36, (byte) 0x06,
-        (byte) 0x93, (byte) 0x54, (byte) 0x50, (byte) 0xCD, (byte) 0x5F, (byte) 0xAA,
-        (byte) 0x01, (byte) 0x42, (byte) 0xAD, (byte) 0xB9, (byte) 0x02, (byte) 0x6E,
-        (byte) 0xAE, (byte) 0x60, (byte) 0x00, (byte) 0x60, (byte) 0x55, (byte) 0x1B,
-        (byte) 0xBB, (byte) 0x9E, (byte) 0x03, (byte) 0xB7, (byte) 0x86, (byte) 0x3D,
-        (byte) 0xCC, (byte) 0xFA, (byte) 0x6E, (byte) 0x20, (byte) 0x07, (byte) 0x61,
-        (byte) 0x8F, (byte) 0x53, (byte) 0xC6, (byte) 0x2B, (byte) 0xEF, (byte) 0x8F,
-        (byte) 0x0F, (byte) 0x8B, (byte) 0x80, (byte) 0x22, (byte) 0xDC, (byte) 0x9E,
-        (byte) 0x20, (byte) 0x4A, (byte) 0x57, (byte) 0xA1, (byte) 0x15, (byte) 0xE0,
-        (byte) 0x01, (byte) 0x95, (byte) 0xDB, (byte) 0x46, (byte) 0x85, (byte) 0x6D,
-        (byte) 0x27, (byte) 0x9F, (byte) 0x44, (byte) 0x3B, (byte) 0xB1, (byte) 0x35,
-        (byte) 0x04, (byte) 0x9D, (byte) 0xF8, (byte) 0xC6, (byte) 0xD7, (byte) 0xD7,
-        (byte) 0xEF, (byte) 0x9A, (byte) 0x53, (byte) 0x5A, (byte) 0x73, (byte) 0xB3,
-        (byte) 0xD0, (byte) 0x32, (byte) 0x39, (byte) 0xE1, (byte) 0x28, (byte) 0x3A,
-        (byte) 0x9D, (byte) 0x69, (byte) 0x4E, (byte) 0x57, (byte) 0xC1, (byte) 0xDF,
-        (byte) 0xFE, (byte) 0x5F, (byte) 0xA8, (byte) 0xFF, (byte) 0xE8, (byte) 0x75,
-        (byte) 0x85, (byte) 0x33, (byte) 0x90, (byte) 0x83, (byte) 0x3D, (byte) 0x8F,
-        (byte) 0x15, (byte) 0x47, (byte) 0x16, (byte) 0xF2, (byte) 0x32, (byte) 0xF9,
-        (byte) 0x46, (byte) 0x96, (byte) 0xCC, (byte) 0x2E, (byte) 0x8F, (byte) 0x27,
-        (byte) 0x3F, (byte) 0xCF, (byte) 0x91, (byte) 0xA6, (byte) 0x9E, (byte) 0xBF,
-        (byte) 0x42, (byte) 0x2F, (byte) 0xD6, (byte) 0x52, (byte) 0xD7, (byte) 0x3B,
-        (byte) 0xCD, (byte) 0xFE, (byte) 0x0B, (byte) 0x4A, (byte) 0x3B, (byte) 0x19,
-        (byte) 0x57, (byte) 0x47, (byte) 0x65, (byte) 0x33, (byte) 0xD9, (byte) 0xF7,
-        (byte) 0xE4, (byte) 0xC3, (byte) 0x05, (byte) 0x49, (byte) 0x3C, (byte) 0xC0,
-        (byte) 0xDF, (byte) 0xC1, (byte) 0x54, (byte) 0x18, (byte) 0x8D, (byte) 0xDA,
-        (byte) 0xE4, (byte) 0x59, (byte) 0xE9, (byte) 0x3B, (byte) 0xD6, (byte) 0x89,
-        (byte) 0x07, (byte) 0x99, (byte) 0xB0, (byte) 0xF4, (byte) 0x09, (byte) 0x0A,
-        (byte) 0x2C, (byte) 0xBA, (byte) 0x0B, (byte) 0xE4, (byte) 0x79, (byte) 0xB1,
-        (byte) 0xDB, (byte) 0xAD, (byte) 0xAB, (byte) 0x5D, (byte) 0xA2, (byte) 0x1E,
-        (byte) 0x76, (byte) 0x7F, (byte) 0x74, (byte) 0x62, (byte) 0x49, (byte) 0x07,
-        (byte) 0x7A, (byte) 0x5B, (byte) 0xD7, (byte) 0x0F, (byte) 0xA4, (byte) 0x2C,
-        (byte) 0x36, (byte) 0x13, (byte) 0x42, (byte) 0xBA, (byte) 0xCF, (byte) 0x0A,
-        (byte) 0xFC, (byte) 0xC3, (byte) 0x31, (byte) 0x5E, (byte) 0x06, (byte) 0x84,
-        (byte) 0x8A, (byte) 0x8A, (byte) 0x84, (byte) 0x0D, (byte) 0x48, (byte) 0xBD,
-        (byte) 0x67, (byte) 0xCF, (byte) 0x04, (byte) 0xB4, (byte) 0xFB, (byte) 0xBB,
-        (byte) 0x04, (byte) 0x91, (byte) 0xB1, (byte) 0x0A, (byte) 0xA4, (byte) 0x70,
-        (byte) 0x58, (byte) 0x1A, (byte) 0x9B, (byte) 0x02, (byte) 0x86, (byte) 0xBD,
-        (byte) 0xAE, (byte) 0x77, (byte) 0x97, (byte) 0x1C,
-    };
-    private static final PSSParameterSpec SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 0, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:222 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA256withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
-        (byte) 0x3B, (byte) 0x43, (byte) 0xA8, (byte) 0xB5, (byte) 0x34, (byte) 0xD8,
-        (byte) 0xF9, (byte) 0xAD, (byte) 0xDD, (byte) 0x1F, (byte) 0x7A, (byte) 0x73,
-        (byte) 0xBF, (byte) 0xFA, (byte) 0xED, (byte) 0x10, (byte) 0xF3, (byte) 0x16,
-        (byte) 0xCC, (byte) 0xE5, (byte) 0x09, (byte) 0x0F, (byte) 0x68, (byte) 0x02,
-        (byte) 0xE7, (byte) 0x55, (byte) 0x0D, (byte) 0xCF, (byte) 0x1B, (byte) 0x83,
-        (byte) 0xCD, (byte) 0xA2, (byte) 0xD6, (byte) 0x02, (byte) 0xDD, (byte) 0x72,
-        (byte) 0xA6, (byte) 0x5F, (byte) 0x05, (byte) 0x8A, (byte) 0x1E, (byte) 0xA1,
-        (byte) 0x4F, (byte) 0x92, (byte) 0xD9, (byte) 0x09, (byte) 0x19, (byte) 0x6E,
-        (byte) 0x80, (byte) 0xA0, (byte) 0x47, (byte) 0x98, (byte) 0x5C, (byte) 0xF7,
-        (byte) 0x34, (byte) 0x52, (byte) 0x7D, (byte) 0x85, (byte) 0xCF, (byte) 0x9F,
-        (byte) 0xEB, (byte) 0xAF, (byte) 0xB4, (byte) 0x53, (byte) 0xF0, (byte) 0x5D,
-        (byte) 0x28, (byte) 0x87, (byte) 0xAC, (byte) 0xA7, (byte) 0xB4, (byte) 0xCF,
-        (byte) 0xDD, (byte) 0x8B, (byte) 0xA4, (byte) 0xC9, (byte) 0xCA, (byte) 0xAA,
-        (byte) 0xF4, (byte) 0xA8, (byte) 0x25, (byte) 0x26, (byte) 0x34, (byte) 0x11,
-        (byte) 0x14, (byte) 0x24, (byte) 0x1C, (byte) 0x1C, (byte) 0x50, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x7E, (byte) 0xFF, (byte) 0x6F, (byte) 0x4F, (byte) 0x14,
-        (byte) 0xB3, (byte) 0x57, (byte) 0x48, (byte) 0x0A, (byte) 0x5A, (byte) 0x95,
-        (byte) 0x5D, (byte) 0xEB, (byte) 0x71, (byte) 0x4E, (byte) 0x86, (byte) 0xFC,
-        (byte) 0x38, (byte) 0x1B, (byte) 0x93, (byte) 0x45, (byte) 0x09, (byte) 0x15,
-        (byte) 0xD3, (byte) 0x06, (byte) 0x6B, (byte) 0x9D, (byte) 0x05, (byte) 0x5C,
-        (byte) 0x4A, (byte) 0xB3, (byte) 0x93, (byte) 0xD1, (byte) 0x01, (byte) 0x54,
-        (byte) 0xCC, (byte) 0xED, (byte) 0xBF, (byte) 0x0E, (byte) 0x7E, (byte) 0x33,
-        (byte) 0x32, (byte) 0xA6, (byte) 0xA5, (byte) 0xF7, (byte) 0x3D, (byte) 0x2E,
-        (byte) 0xCB, (byte) 0x76, (byte) 0xA7, (byte) 0x22, (byte) 0x64, (byte) 0xB8,
-        (byte) 0x19, (byte) 0x53, (byte) 0xFE, (byte) 0x8C, (byte) 0xC8, (byte) 0x1E,
-        (byte) 0x6C, (byte) 0xEE, (byte) 0x08, (byte) 0x07, (byte) 0x7E, (byte) 0x93,
-        (byte) 0x43, (byte) 0x1B, (byte) 0xCF, (byte) 0x37, (byte) 0xE4, (byte) 0xAB,
-        (byte) 0xE7, (byte) 0xD7, (byte) 0x83, (byte) 0x8E, (byte) 0x19, (byte) 0xAE,
-        (byte) 0x05, (byte) 0x51, (byte) 0x91, (byte) 0x10, (byte) 0x7B, (byte) 0x70,
-        (byte) 0xFC, (byte) 0x73, (byte) 0x12, (byte) 0x96, (byte) 0xFA, (byte) 0xD0,
-        (byte) 0xCA, (byte) 0xA3, (byte) 0x59, (byte) 0xA7, (byte) 0xDD, (byte) 0xC3,
-        (byte) 0x1D, (byte) 0x9C, (byte) 0x7B, (byte) 0x50, (byte) 0xBB, (byte) 0x57,
-        (byte) 0xB8, (byte) 0x86, (byte) 0xF2, (byte) 0xCA, (byte) 0xC4, (byte) 0x86,
-        (byte) 0x7A, (byte) 0x96, (byte) 0x90, (byte) 0x02, (byte) 0xDF, (byte) 0xA0,
-        (byte) 0x88, (byte) 0x0E, (byte) 0x89, (byte) 0x45, (byte) 0x27, (byte) 0x52,
-        (byte) 0xDA, (byte) 0x86, (byte) 0x42, (byte) 0x4B, (byte) 0x90, (byte) 0xC3,
-        (byte) 0xC1, (byte) 0x41, (byte) 0x60, (byte) 0x5C, (byte) 0x29, (byte) 0x15,
-        (byte) 0xE5, (byte) 0x5C, (byte) 0x43, (byte) 0x9B, (byte) 0x40, (byte) 0xE5,
-        (byte) 0x04, (byte) 0x1B, (byte) 0x4A, (byte) 0x93, (byte) 0xDD, (byte) 0x55,
-        (byte) 0xC4, (byte) 0xFC, (byte) 0xFE, (byte) 0x0C, (byte) 0x65, (byte) 0x96,
-        (byte) 0x98, (byte) 0xDE, (byte) 0xC5, (byte) 0x05, (byte) 0xC5, (byte) 0x3E,
-        (byte) 0xB0, (byte) 0x25, (byte) 0x4E, (byte) 0x65, (byte) 0x24, (byte) 0x8D,
-        (byte) 0x4E, (byte) 0x9D, (byte) 0x94, (byte) 0x01,
-    };
-    private static final PSSParameterSpec SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 222, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:48 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA384withRSAPSS_Vector2Signature = new byte[] {
-        (byte) 0x20, (byte) 0xCB, (byte) 0x97, (byte) 0x9C, (byte) 0x2E, (byte) 0x51,
-        (byte) 0x59, (byte) 0x56, (byte) 0x9F, (byte) 0x04, (byte) 0x47, (byte) 0x7C,
-        (byte) 0x5C, (byte) 0x57, (byte) 0x59, (byte) 0xBC, (byte) 0x43, (byte) 0xD9,
-        (byte) 0x4B, (byte) 0xEC, (byte) 0xAC, (byte) 0xB9, (byte) 0x88, (byte) 0xA2,
-        (byte) 0x30, (byte) 0x8B, (byte) 0xEE, (byte) 0x2F, (byte) 0xC1, (byte) 0x73,
-        (byte) 0xF1, (byte) 0x13, (byte) 0xB2, (byte) 0x5E, (byte) 0x1A, (byte) 0xC8,
-        (byte) 0xD2, (byte) 0xAA, (byte) 0x27, (byte) 0x16, (byte) 0xA1, (byte) 0x14,
-        (byte) 0xAB, (byte) 0x45, (byte) 0x8A, (byte) 0x7E, (byte) 0x22, (byte) 0x22,
-        (byte) 0x2A, (byte) 0x2E, (byte) 0xDA, (byte) 0x6A, (byte) 0x7E, (byte) 0x3F,
-        (byte) 0x66, (byte) 0x99, (byte) 0x55, (byte) 0xAF, (byte) 0x2B, (byte) 0x94,
-        (byte) 0xD8, (byte) 0x6B, (byte) 0xC2, (byte) 0x60, (byte) 0xB5, (byte) 0x55,
-        (byte) 0xA9, (byte) 0x26, (byte) 0x29, (byte) 0xFC, (byte) 0x17, (byte) 0x56,
-        (byte) 0x05, (byte) 0xB7, (byte) 0x48, (byte) 0x2F, (byte) 0xAB, (byte) 0x68,
-        (byte) 0xCF, (byte) 0x37, (byte) 0x62, (byte) 0x79, (byte) 0x4F, (byte) 0x32,
-        (byte) 0x04, (byte) 0xF6, (byte) 0xEA, (byte) 0xBE, (byte) 0x79, (byte) 0x84,
-        (byte) 0x73, (byte) 0xEE, (byte) 0x1C, (byte) 0xEE, (byte) 0x9F, (byte) 0x72,
-        (byte) 0x7A, (byte) 0xC6, (byte) 0x64, (byte) 0xB4, (byte) 0x4F, (byte) 0xDE,
-        (byte) 0x0B, (byte) 0x38, (byte) 0x47, (byte) 0x62, (byte) 0xA9, (byte) 0xFD,
-        (byte) 0x1B, (byte) 0x75, (byte) 0xEC, (byte) 0xFE, (byte) 0x2D, (byte) 0x04,
-        (byte) 0x2D, (byte) 0x0A, (byte) 0xCE, (byte) 0x13, (byte) 0xFA, (byte) 0xDA,
-        (byte) 0x3F, (byte) 0x4C, (byte) 0x11, (byte) 0xEA, (byte) 0x02, (byte) 0x00,
-        (byte) 0x0A, (byte) 0x93, (byte) 0x12, (byte) 0xDC, (byte) 0x60, (byte) 0xE7,
-        (byte) 0x52, (byte) 0x90, (byte) 0x8A, (byte) 0xA3, (byte) 0xAE, (byte) 0xC5,
-        (byte) 0x9A, (byte) 0xD7, (byte) 0xD5, (byte) 0x0D, (byte) 0xBC, (byte) 0x7A,
-        (byte) 0xDB, (byte) 0xF4, (byte) 0x10, (byte) 0xE0, (byte) 0xDB, (byte) 0xC0,
-        (byte) 0x97, (byte) 0xF1, (byte) 0x84, (byte) 0xCF, (byte) 0x66, (byte) 0xB2,
-        (byte) 0x04, (byte) 0x58, (byte) 0x81, (byte) 0xB5, (byte) 0x9B, (byte) 0x4A,
-        (byte) 0xF9, (byte) 0xD7, (byte) 0xCA, (byte) 0x51, (byte) 0x09, (byte) 0x67,
-        (byte) 0x48, (byte) 0x7B, (byte) 0xE5, (byte) 0xE9, (byte) 0x07, (byte) 0x4E,
-        (byte) 0x6A, (byte) 0xC1, (byte) 0xA6, (byte) 0x68, (byte) 0x90, (byte) 0x17,
-        (byte) 0xAB, (byte) 0x0E, (byte) 0xFB, (byte) 0x3E, (byte) 0x39, (byte) 0x74,
-        (byte) 0x85, (byte) 0x04, (byte) 0x42, (byte) 0x0A, (byte) 0x9E, (byte) 0x02,
-        (byte) 0xA9, (byte) 0x50, (byte) 0xFF, (byte) 0x23, (byte) 0x2D, (byte) 0x30,
-        (byte) 0xDD, (byte) 0x17, (byte) 0xC0, (byte) 0x82, (byte) 0xF7, (byte) 0xBB,
-        (byte) 0x3B, (byte) 0x03, (byte) 0xBD, (byte) 0xB1, (byte) 0x96, (byte) 0xCD,
-        (byte) 0x71, (byte) 0x3F, (byte) 0x67, (byte) 0x59, (byte) 0x5E, (byte) 0x45,
-        (byte) 0xE0, (byte) 0x1C, (byte) 0x80, (byte) 0x52, (byte) 0xD7, (byte) 0xF0,
-        (byte) 0xC1, (byte) 0xE6, (byte) 0xCF, (byte) 0x59, (byte) 0x13, (byte) 0x25,
-        (byte) 0x6F, (byte) 0x9F, (byte) 0xBB, (byte) 0xB9, (byte) 0x7F, (byte) 0x7E,
-        (byte) 0x7D, (byte) 0x93, (byte) 0xD9, (byte) 0x3F, (byte) 0x95, (byte) 0xB7,
-        (byte) 0x9A, (byte) 0xDB, (byte) 0xE2, (byte) 0x2C, (byte) 0x53, (byte) 0x83,
-        (byte) 0x9A, (byte) 0x06, (byte) 0x6D, (byte) 0x22, (byte) 0x81, (byte) 0xB5,
-        (byte) 0x63, (byte) 0xAE, (byte) 0x4A, (byte) 0xEE,
-    };
-    private static final PSSParameterSpec SHA384withRSAPSS_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 48, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:0 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA384withRSAPSS_NoSalt_Vector2Signature = new byte[] {
-        (byte) 0x41, (byte) 0x0C, (byte) 0x3A, (byte) 0xEC, (byte) 0xF6, (byte) 0xD9,
-        (byte) 0x8F, (byte) 0xA3, (byte) 0x61, (byte) 0xBB, (byte) 0x03, (byte) 0xED,
-        (byte) 0xD9, (byte) 0x69, (byte) 0x7D, (byte) 0xE1, (byte) 0xE1, (byte) 0x4E,
-        (byte) 0x5E, (byte) 0x71, (byte) 0x4E, (byte) 0x88, (byte) 0x9C, (byte) 0x79,
-        (byte) 0xD3, (byte) 0x71, (byte) 0x28, (byte) 0x07, (byte) 0x28, (byte) 0x19,
-        (byte) 0x96, (byte) 0x55, (byte) 0x30, (byte) 0x81, (byte) 0x29, (byte) 0x5C,
-        (byte) 0x4A, (byte) 0x18, (byte) 0x69, (byte) 0x36, (byte) 0x74, (byte) 0xAC,
-        (byte) 0x99, (byte) 0xB1, (byte) 0xBC, (byte) 0xA0, (byte) 0xFC, (byte) 0x17,
-        (byte) 0xA4, (byte) 0xD1, (byte) 0xAE, (byte) 0x84, (byte) 0xA6, (byte) 0x09,
-        (byte) 0x6B, (byte) 0xB3, (byte) 0x02, (byte) 0xB2, (byte) 0x81, (byte) 0x04,
-        (byte) 0x59, (byte) 0x8C, (byte) 0xCF, (byte) 0xAD, (byte) 0xFB, (byte) 0x76,
-        (byte) 0x6F, (byte) 0xE2, (byte) 0x5E, (byte) 0x09, (byte) 0xE5, (byte) 0xBC,
-        (byte) 0x54, (byte) 0xBD, (byte) 0x08, (byte) 0xA8, (byte) 0x18, (byte) 0x60,
-        (byte) 0xAF, (byte) 0x09, (byte) 0x67, (byte) 0x15, (byte) 0x03, (byte) 0xA8,
-        (byte) 0x8B, (byte) 0x3F, (byte) 0x31, (byte) 0xB7, (byte) 0x76, (byte) 0xFD,
-        (byte) 0xF6, (byte) 0x82, (byte) 0xC7, (byte) 0x89, (byte) 0xC2, (byte) 0x47,
-        (byte) 0x80, (byte) 0x06, (byte) 0x4F, (byte) 0x8C, (byte) 0x9C, (byte) 0xD7,
-        (byte) 0x4F, (byte) 0x63, (byte) 0x1E, (byte) 0xF0, (byte) 0x34, (byte) 0xD7,
-        (byte) 0x91, (byte) 0xD2, (byte) 0x96, (byte) 0x62, (byte) 0xFD, (byte) 0x68,
-        (byte) 0xE3, (byte) 0xE0, (byte) 0xFB, (byte) 0x7D, (byte) 0x0A, (byte) 0xD7,
-        (byte) 0x52, (byte) 0xFE, (byte) 0xD1, (byte) 0x95, (byte) 0x9E, (byte) 0xD2,
-        (byte) 0x84, (byte) 0xBE, (byte) 0x3D, (byte) 0x1F, (byte) 0x8C, (byte) 0xC4,
-        (byte) 0xD6, (byte) 0xE3, (byte) 0xCF, (byte) 0xE8, (byte) 0xB3, (byte) 0x82,
-        (byte) 0x2E, (byte) 0xFA, (byte) 0x39, (byte) 0xA3, (byte) 0x20, (byte) 0x3C,
-        (byte) 0xBE, (byte) 0x6A, (byte) 0xFA, (byte) 0x04, (byte) 0xD2, (byte) 0x74,
-        (byte) 0x41, (byte) 0xDC, (byte) 0xE8, (byte) 0x0E, (byte) 0xE7, (byte) 0xF2,
-        (byte) 0x36, (byte) 0xD4, (byte) 0x2E, (byte) 0x6A, (byte) 0xCF, (byte) 0xDF,
-        (byte) 0x8B, (byte) 0x4B, (byte) 0x77, (byte) 0xE8, (byte) 0x0A, (byte) 0x64,
-        (byte) 0x86, (byte) 0x2C, (byte) 0xCA, (byte) 0x92, (byte) 0x01, (byte) 0xB2,
-        (byte) 0x8A, (byte) 0xB8, (byte) 0xB2, (byte) 0x6C, (byte) 0x0B, (byte) 0x18,
-        (byte) 0x90, (byte) 0x31, (byte) 0x93, (byte) 0x29, (byte) 0xBA, (byte) 0xB1,
-        (byte) 0x88, (byte) 0x94, (byte) 0x44, (byte) 0x0B, (byte) 0x38, (byte) 0x64,
-        (byte) 0xC1, (byte) 0xDE, (byte) 0x0B, (byte) 0xD8, (byte) 0xE4, (byte) 0xBA,
-        (byte) 0x0A, (byte) 0x41, (byte) 0x24, (byte) 0x35, (byte) 0xAA, (byte) 0xE3,
-        (byte) 0x59, (byte) 0x8E, (byte) 0x57, (byte) 0x51, (byte) 0x43, (byte) 0xE1,
-        (byte) 0x9C, (byte) 0xF6, (byte) 0xF8, (byte) 0x16, (byte) 0x68, (byte) 0x83,
-        (byte) 0x08, (byte) 0x8C, (byte) 0x2D, (byte) 0x40, (byte) 0xD2, (byte) 0xEF,
-        (byte) 0xD6, (byte) 0xAE, (byte) 0x98, (byte) 0x77, (byte) 0xE8, (byte) 0xF2,
-        (byte) 0xC7, (byte) 0x19, (byte) 0x61, (byte) 0xD6, (byte) 0x43, (byte) 0xCD,
-        (byte) 0x76, (byte) 0x2E, (byte) 0x7A, (byte) 0xCB, (byte) 0x1A, (byte) 0x5D,
-        (byte) 0x73, (byte) 0x45, (byte) 0xF2, (byte) 0x7C, (byte) 0xD0, (byte) 0x88,
-        (byte) 0x83, (byte) 0x51, (byte) 0xF3, (byte) 0x19, (byte) 0x0F, (byte) 0xD5,
-        (byte) 0x40, (byte) 0x3F, (byte) 0xD9, (byte) 0xBF,
-    };
-    private static final PSSParameterSpec SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 0, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:206 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA384withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
-        (byte) 0xDE, (byte) 0xF7, (byte) 0xC3, (byte) 0x21, (byte) 0x79, (byte) 0x0F,
-        (byte) 0x55, (byte) 0xD1, (byte) 0x56, (byte) 0x9A, (byte) 0xB0, (byte) 0x08,
-        (byte) 0xA1, (byte) 0x27, (byte) 0xC9, (byte) 0x5E, (byte) 0x64, (byte) 0xF4,
-        (byte) 0xC7, (byte) 0x83, (byte) 0x94, (byte) 0xCA, (byte) 0xBD, (byte) 0x50,
-        (byte) 0xD6, (byte) 0xC5, (byte) 0x56, (byte) 0x94, (byte) 0xBD, (byte) 0x0B,
-        (byte) 0x55, (byte) 0xE6, (byte) 0x04, (byte) 0xAD, (byte) 0xAF, (byte) 0xAF,
-        (byte) 0x4F, (byte) 0x2D, (byte) 0x91, (byte) 0x7F, (byte) 0xF1, (byte) 0x60,
-        (byte) 0x0C, (byte) 0xEE, (byte) 0xE8, (byte) 0x44, (byte) 0xFC, (byte) 0x69,
-        (byte) 0x80, (byte) 0x43, (byte) 0xBC, (byte) 0xAB, (byte) 0x83, (byte) 0x35,
-        (byte) 0xB0, (byte) 0xC6, (byte) 0xCB, (byte) 0xE6, (byte) 0x92, (byte) 0x29,
-        (byte) 0x09, (byte) 0xCF, (byte) 0xDB, (byte) 0xAD, (byte) 0x16, (byte) 0x93,
-        (byte) 0xC7, (byte) 0xBE, (byte) 0x81, (byte) 0x68, (byte) 0x0F, (byte) 0x7B,
-        (byte) 0xC1, (byte) 0xC2, (byte) 0x8C, (byte) 0xBA, (byte) 0x59, (byte) 0x80,
-        (byte) 0xAE, (byte) 0xFB, (byte) 0x60, (byte) 0x22, (byte) 0x28, (byte) 0x36,
-        (byte) 0xBE, (byte) 0x37, (byte) 0x72, (byte) 0x86, (byte) 0x02, (byte) 0x4B,
-        (byte) 0xF9, (byte) 0x14, (byte) 0x5A, (byte) 0x6B, (byte) 0x32, (byte) 0x44,
-        (byte) 0x72, (byte) 0x33, (byte) 0x2E, (byte) 0x7F, (byte) 0xA1, (byte) 0xFD,
-        (byte) 0x07, (byte) 0xF2, (byte) 0xD9, (byte) 0x9D, (byte) 0x03, (byte) 0x77,
-        (byte) 0x17, (byte) 0xFB, (byte) 0x0E, (byte) 0xFF, (byte) 0xF7, (byte) 0x37,
-        (byte) 0x68, (byte) 0xF6, (byte) 0x8F, (byte) 0x9B, (byte) 0x2C, (byte) 0xEB,
-        (byte) 0xAF, (byte) 0x6C, (byte) 0x50, (byte) 0x9F, (byte) 0x34, (byte) 0xB2,
-        (byte) 0x52, (byte) 0x3B, (byte) 0x94, (byte) 0x6F, (byte) 0x60, (byte) 0x16,
-        (byte) 0x52, (byte) 0x0A, (byte) 0xBF, (byte) 0x95, (byte) 0x41, (byte) 0x44,
-        (byte) 0x83, (byte) 0x91, (byte) 0x85, (byte) 0xA1, (byte) 0xF7, (byte) 0xF9,
-        (byte) 0x17, (byte) 0x4A, (byte) 0xF7, (byte) 0xF1, (byte) 0xE8, (byte) 0x9C,
-        (byte) 0x75, (byte) 0x86, (byte) 0x12, (byte) 0x44, (byte) 0x19, (byte) 0x5C,
-        (byte) 0x65, (byte) 0x31, (byte) 0x89, (byte) 0x2A, (byte) 0xFC, (byte) 0xBE,
-        (byte) 0xE8, (byte) 0xEC, (byte) 0xC9, (byte) 0xD7, (byte) 0x41, (byte) 0xDA,
-        (byte) 0xD9, (byte) 0xC9, (byte) 0x8B, (byte) 0x90, (byte) 0x60, (byte) 0xCC,
-        (byte) 0xB2, (byte) 0x7A, (byte) 0xBA, (byte) 0xA0, (byte) 0xEE, (byte) 0xBE,
-        (byte) 0x9C, (byte) 0xE7, (byte) 0xF2, (byte) 0x27, (byte) 0x92, (byte) 0x9C,
-        (byte) 0x3C, (byte) 0x0F, (byte) 0x5C, (byte) 0xEE, (byte) 0x38, (byte) 0x48,
-        (byte) 0xCF, (byte) 0xFF, (byte) 0x33, (byte) 0x35, (byte) 0x80, (byte) 0x99,
-        (byte) 0x5D, (byte) 0xA7, (byte) 0x5A, (byte) 0x7A, (byte) 0xEA, (byte) 0x96,
-        (byte) 0x74, (byte) 0x28, (byte) 0x36, (byte) 0x7B, (byte) 0xE1, (byte) 0x33,
-        (byte) 0x7C, (byte) 0x78, (byte) 0xEC, (byte) 0x05, (byte) 0x72, (byte) 0x0E,
-        (byte) 0x5D, (byte) 0x16, (byte) 0x5C, (byte) 0x77, (byte) 0x58, (byte) 0xA7,
-        (byte) 0x31, (byte) 0x3F, (byte) 0xBA, (byte) 0x91, (byte) 0xA7, (byte) 0x16,
-        (byte) 0xFC, (byte) 0x31, (byte) 0xCA, (byte) 0x30, (byte) 0xE0, (byte) 0xF4,
-        (byte) 0x5D, (byte) 0x07, (byte) 0x4A, (byte) 0x9C, (byte) 0x1D, (byte) 0x2B,
-        (byte) 0x4E, (byte) 0xB8, (byte) 0x7C, (byte) 0x67, (byte) 0xCB, (byte) 0x34,
-        (byte) 0x69, (byte) 0x85, (byte) 0x4E, (byte) 0x99, (byte) 0x41, (byte) 0x8A,
-        (byte) 0x35, (byte) 0x85, (byte) 0xF2, (byte) 0x1A,
-    };
-    private static final PSSParameterSpec SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 206, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA512withRSAPSS_Vector2Signature = new byte[] {
-        (byte) 0x9F, (byte) 0xED, (byte) 0xF8, (byte) 0xEE, (byte) 0x30, (byte) 0x5F,
-        (byte) 0x30, (byte) 0x63, (byte) 0x1D, (byte) 0x86, (byte) 0xD3, (byte) 0xAD,
-        (byte) 0x1D, (byte) 0xD8, (byte) 0xD2, (byte) 0x67, (byte) 0xE2, (byte) 0x43,
-        (byte) 0x64, (byte) 0x71, (byte) 0x98, (byte) 0x82, (byte) 0x00, (byte) 0x84,
-        (byte) 0x2C, (byte) 0x88, (byte) 0x1A, (byte) 0x28, (byte) 0xCD, (byte) 0xA2,
-        (byte) 0x34, (byte) 0x17, (byte) 0x0F, (byte) 0x34, (byte) 0x8A, (byte) 0x10,
-        (byte) 0x79, (byte) 0x6C, (byte) 0xCB, (byte) 0xDA, (byte) 0x2F, (byte) 0xDF,
-        (byte) 0x4D, (byte) 0x98, (byte) 0x01, (byte) 0xE8, (byte) 0xB3, (byte) 0xF5,
-        (byte) 0xCD, (byte) 0x60, (byte) 0xEA, (byte) 0xDE, (byte) 0xA5, (byte) 0x0C,
-        (byte) 0x09, (byte) 0xA1, (byte) 0x4A, (byte) 0xC4, (byte) 0x6B, (byte) 0x09,
-        (byte) 0xB3, (byte) 0x37, (byte) 0x1F, (byte) 0x8A, (byte) 0x64, (byte) 0x81,
-        (byte) 0x2E, (byte) 0x22, (byte) 0x75, (byte) 0x24, (byte) 0x3B, (byte) 0xC0,
-        (byte) 0x0E, (byte) 0x1F, (byte) 0x37, (byte) 0xC9, (byte) 0x1E, (byte) 0x6F,
-        (byte) 0xAF, (byte) 0x3E, (byte) 0x9B, (byte) 0x3F, (byte) 0xA3, (byte) 0xC3,
-        (byte) 0x0B, (byte) 0xB9, (byte) 0x83, (byte) 0x60, (byte) 0x02, (byte) 0xC6,
-        (byte) 0x29, (byte) 0x83, (byte) 0x09, (byte) 0x16, (byte) 0xD9, (byte) 0x3D,
-        (byte) 0x84, (byte) 0x02, (byte) 0x81, (byte) 0x20, (byte) 0xE9, (byte) 0x01,
-        (byte) 0x5B, (byte) 0x85, (byte) 0xC8, (byte) 0x81, (byte) 0x25, (byte) 0x6B,
-        (byte) 0xCB, (byte) 0x78, (byte) 0x48, (byte) 0x65, (byte) 0x3A, (byte) 0xD6,
-        (byte) 0x95, (byte) 0x9B, (byte) 0x62, (byte) 0x2D, (byte) 0x84, (byte) 0x54,
-        (byte) 0x12, (byte) 0x94, (byte) 0xB7, (byte) 0xF0, (byte) 0x1C, (byte) 0xB6,
-        (byte) 0x59, (byte) 0xCD, (byte) 0xC3, (byte) 0x86, (byte) 0xE6, (byte) 0x63,
-        (byte) 0xD7, (byte) 0x99, (byte) 0x9A, (byte) 0xC4, (byte) 0xBF, (byte) 0x8E,
-        (byte) 0xDD, (byte) 0x46, (byte) 0x10, (byte) 0xBE, (byte) 0xAB, (byte) 0x78,
-        (byte) 0xC6, (byte) 0x30, (byte) 0x47, (byte) 0x23, (byte) 0xB6, (byte) 0x2C,
-        (byte) 0x02, (byte) 0x5E, (byte) 0x1F, (byte) 0x07, (byte) 0x96, (byte) 0x54,
-        (byte) 0xEE, (byte) 0x28, (byte) 0xC7, (byte) 0xEC, (byte) 0x57, (byte) 0xDB,
-        (byte) 0x9E, (byte) 0xEF, (byte) 0xE4, (byte) 0x11, (byte) 0xF8, (byte) 0x04,
-        (byte) 0xA9, (byte) 0x26, (byte) 0xC2, (byte) 0x61, (byte) 0xF1, (byte) 0x84,
-        (byte) 0xEB, (byte) 0x94, (byte) 0xBD, (byte) 0x48, (byte) 0xCA, (byte) 0xD1,
-        (byte) 0x84, (byte) 0xCE, (byte) 0x82, (byte) 0x2E, (byte) 0xF6, (byte) 0x4E,
-        (byte) 0x17, (byte) 0x6F, (byte) 0x78, (byte) 0xB9, (byte) 0x0B, (byte) 0xA9,
-        (byte) 0x7D, (byte) 0xBC, (byte) 0xE5, (byte) 0xF8, (byte) 0x7D, (byte) 0xA8,
-        (byte) 0x76, (byte) 0x7A, (byte) 0x8B, (byte) 0xB5, (byte) 0x05, (byte) 0x42,
-        (byte) 0x37, (byte) 0xDA, (byte) 0x15, (byte) 0xE2, (byte) 0xC4, (byte) 0x70,
-        (byte) 0x6E, (byte) 0x95, (byte) 0x60, (byte) 0x47, (byte) 0xF9, (byte) 0x0F,
-        (byte) 0xF4, (byte) 0xA2, (byte) 0x73, (byte) 0xF1, (byte) 0x73, (byte) 0xBD,
-        (byte) 0x0B, (byte) 0x9B, (byte) 0x44, (byte) 0xB6, (byte) 0xA9, (byte) 0xAF,
-        (byte) 0x50, (byte) 0x2D, (byte) 0x5C, (byte) 0xA3, (byte) 0x72, (byte) 0x6F,
-        (byte) 0x85, (byte) 0xE8, (byte) 0x0C, (byte) 0xF9, (byte) 0xE1, (byte) 0xE8,
-        (byte) 0xF7, (byte) 0xC0, (byte) 0x85, (byte) 0x14, (byte) 0x53, (byte) 0x95,
-        (byte) 0xF9, (byte) 0x9E, (byte) 0x65, (byte) 0x05, (byte) 0xF0, (byte) 0x22,
-        (byte) 0x7F, (byte) 0x4F, (byte) 0x40, (byte) 0x45,
-    };
-    private static final PSSParameterSpec SHA512withRSAPSS_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA512withRSAPSS_NoSalt_Vector2Signature = new byte[] {
-        (byte) 0x49, (byte) 0xA3, (byte) 0xBC, (byte) 0x2E, (byte) 0x67, (byte) 0x96,
-        (byte) 0xA5, (byte) 0x3E, (byte) 0x39, (byte) 0x46, (byte) 0xD6, (byte) 0xA1,
-        (byte) 0xA0, (byte) 0x4F, (byte) 0x3A, (byte) 0x03, (byte) 0x8F, (byte) 0x62,
-        (byte) 0xF2, (byte) 0xD8, (byte) 0x90, (byte) 0xAD, (byte) 0xE2, (byte) 0x3B,
-        (byte) 0x4F, (byte) 0x98, (byte) 0x88, (byte) 0x51, (byte) 0x41, (byte) 0x09,
-        (byte) 0x23, (byte) 0xEB, (byte) 0xF4, (byte) 0x5D, (byte) 0x6A, (byte) 0x22,
-        (byte) 0x12, (byte) 0x12, (byte) 0xDC, (byte) 0x27, (byte) 0xE9, (byte) 0xF7,
-        (byte) 0x64, (byte) 0xA3, (byte) 0xDE, (byte) 0x3A, (byte) 0xB0, (byte) 0xD6,
-        (byte) 0xF2, (byte) 0xC6, (byte) 0xBC, (byte) 0x0B, (byte) 0xA2, (byte) 0xA1,
-        (byte) 0xAA, (byte) 0xB0, (byte) 0x51, (byte) 0xDA, (byte) 0x4F, (byte) 0x28,
-        (byte) 0xA8, (byte) 0xEB, (byte) 0x34, (byte) 0x60, (byte) 0x37, (byte) 0xF7,
-        (byte) 0x50, (byte) 0x7D, (byte) 0xB8, (byte) 0xE7, (byte) 0x24, (byte) 0x8E,
-        (byte) 0xAC, (byte) 0x03, (byte) 0x31, (byte) 0xB8, (byte) 0xE0, (byte) 0xDB,
-        (byte) 0x97, (byte) 0xE9, (byte) 0x1B, (byte) 0x7E, (byte) 0x27, (byte) 0x99,
-        (byte) 0x93, (byte) 0x4D, (byte) 0x46, (byte) 0xB3, (byte) 0xFE, (byte) 0xD6,
-        (byte) 0x23, (byte) 0xB3, (byte) 0xAB, (byte) 0x3E, (byte) 0x33, (byte) 0xA1,
-        (byte) 0x10, (byte) 0x4E, (byte) 0x34, (byte) 0x27, (byte) 0x58, (byte) 0x25,
-        (byte) 0xB7, (byte) 0xBA, (byte) 0xEE, (byte) 0xBE, (byte) 0xE0, (byte) 0x6E,
-        (byte) 0x54, (byte) 0xF7, (byte) 0x73, (byte) 0x7B, (byte) 0x5A, (byte) 0x9C,
-        (byte) 0x74, (byte) 0xEA, (byte) 0xC7, (byte) 0x7E, (byte) 0xC6, (byte) 0xF7,
-        (byte) 0xD5, (byte) 0x32, (byte) 0x0E, (byte) 0x28, (byte) 0x99, (byte) 0xD8,
-        (byte) 0xEF, (byte) 0x97, (byte) 0x62, (byte) 0x8A, (byte) 0xE3, (byte) 0x16,
-        (byte) 0xAD, (byte) 0xE2, (byte) 0xF4, (byte) 0x11, (byte) 0x91, (byte) 0x17,
-        (byte) 0xF3, (byte) 0x32, (byte) 0x90, (byte) 0xCB, (byte) 0x3C, (byte) 0x89,
-        (byte) 0xF4, (byte) 0x20, (byte) 0xF1, (byte) 0x2D, (byte) 0x74, (byte) 0x22,
-        (byte) 0x50, (byte) 0x64, (byte) 0xC2, (byte) 0xF4, (byte) 0xC4, (byte) 0x0D,
-        (byte) 0x18, (byte) 0x6A, (byte) 0x02, (byte) 0x52, (byte) 0x14, (byte) 0x85,
-        (byte) 0x67, (byte) 0xA4, (byte) 0x08, (byte) 0xE5, (byte) 0xBF, (byte) 0x65,
-        (byte) 0x15, (byte) 0xB3, (byte) 0x5A, (byte) 0x88, (byte) 0xEB, (byte) 0xD4,
-        (byte) 0x75, (byte) 0xF9, (byte) 0x52, (byte) 0x73, (byte) 0xA0, (byte) 0x5E,
-        (byte) 0xBA, (byte) 0x37, (byte) 0x6A, (byte) 0x61, (byte) 0x2B, (byte) 0x16,
-        (byte) 0x8A, (byte) 0xA8, (byte) 0x00, (byte) 0xBB, (byte) 0x4D, (byte) 0xFA,
-        (byte) 0x04, (byte) 0xB8, (byte) 0xAB, (byte) 0x4D, (byte) 0xA4, (byte) 0xFC,
-        (byte) 0x9D, (byte) 0xCF, (byte) 0x63, (byte) 0x83, (byte) 0x34, (byte) 0xAE,
-        (byte) 0xAE, (byte) 0xA6, (byte) 0x77, (byte) 0x73, (byte) 0xA2, (byte) 0xB5,
-        (byte) 0x77, (byte) 0xAC, (byte) 0x00, (byte) 0x03, (byte) 0x06, (byte) 0xD4,
-        (byte) 0xDF, (byte) 0x81, (byte) 0x61, (byte) 0xCE, (byte) 0x8E, (byte) 0xC1,
-        (byte) 0xD5, (byte) 0x99, (byte) 0xD5, (byte) 0x2F, (byte) 0xE8, (byte) 0x27,
-        (byte) 0xFA, (byte) 0x84, (byte) 0x7E, (byte) 0x57, (byte) 0xF1, (byte) 0xC9,
-        (byte) 0xEB, (byte) 0x4F, (byte) 0xF9, (byte) 0x92, (byte) 0xC6, (byte) 0xD0,
-        (byte) 0x25, (byte) 0x8A, (byte) 0x16, (byte) 0xD0, (byte) 0xEC, (byte) 0xE5,
-        (byte) 0x33, (byte) 0xA6, (byte) 0xF9, (byte) 0xD5, (byte) 0x0C, (byte) 0x7B,
-        (byte) 0xEC, (byte) 0xC6, (byte) 0x58, (byte) 0x45,
-    };
-    private static final PSSParameterSpec SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 0, 1);
-
-    /*
-     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
-     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
-     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:190 \
-     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] SHA512withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
-        (byte) 0x90, (byte) 0x92, (byte) 0x45, (byte) 0xA1, (byte) 0x1E, (byte) 0x0F,
-        (byte) 0x5F, (byte) 0xF6, (byte) 0x8F, (byte) 0xA0, (byte) 0xBE, (byte) 0x34,
-        (byte) 0x29, (byte) 0x62, (byte) 0xBE, (byte) 0x41, (byte) 0x80, (byte) 0xF0,
-        (byte) 0xB8, (byte) 0x9F, (byte) 0x29, (byte) 0x63, (byte) 0x89, (byte) 0x26,
-        (byte) 0xC2, (byte) 0x22, (byte) 0x1F, (byte) 0x60, (byte) 0xB6, (byte) 0xFC,
-        (byte) 0x5A, (byte) 0x3E, (byte) 0x99, (byte) 0xB8, (byte) 0xC6, (byte) 0x3B,
-        (byte) 0x67, (byte) 0x33, (byte) 0x97, (byte) 0x19, (byte) 0xC6, (byte) 0xFF,
-        (byte) 0x0C, (byte) 0xA9, (byte) 0x04, (byte) 0x5A, (byte) 0xF0, (byte) 0x02,
-        (byte) 0x9A, (byte) 0x19, (byte) 0x0F, (byte) 0xEA, (byte) 0x77, (byte) 0x0D,
-        (byte) 0x56, (byte) 0x38, (byte) 0x0A, (byte) 0xED, (byte) 0x4E, (byte) 0xB7,
-        (byte) 0x57, (byte) 0xBD, (byte) 0xC9, (byte) 0xA3, (byte) 0xE8, (byte) 0xC0,
-        (byte) 0x7D, (byte) 0xF6, (byte) 0xA3, (byte) 0x4B, (byte) 0x61, (byte) 0x45,
-        (byte) 0x06, (byte) 0x5E, (byte) 0x56, (byte) 0xF5, (byte) 0xEF, (byte) 0x76,
-        (byte) 0x6B, (byte) 0xB7, (byte) 0xD4, (byte) 0xBB, (byte) 0xA4, (byte) 0x3C,
-        (byte) 0x52, (byte) 0xF8, (byte) 0x06, (byte) 0x67, (byte) 0xF7, (byte) 0xC3,
-        (byte) 0x8C, (byte) 0x5E, (byte) 0xDF, (byte) 0xFE, (byte) 0x30, (byte) 0x2E,
-        (byte) 0xF8, (byte) 0x59, (byte) 0x3C, (byte) 0x3B, (byte) 0xEA, (byte) 0xA0,
-        (byte) 0x5D, (byte) 0x8F, (byte) 0x18, (byte) 0x73, (byte) 0x1A, (byte) 0x2D,
-        (byte) 0xB1, (byte) 0x55, (byte) 0x07, (byte) 0xC8, (byte) 0x33, (byte) 0xED,
-        (byte) 0x8A, (byte) 0x5E, (byte) 0xC3, (byte) 0xAE, (byte) 0x51, (byte) 0x31,
-        (byte) 0xC4, (byte) 0xFA, (byte) 0xE8, (byte) 0xE9, (byte) 0xBE, (byte) 0x2E,
-        (byte) 0x28, (byte) 0xAA, (byte) 0xED, (byte) 0xA8, (byte) 0x4B, (byte) 0xA3,
-        (byte) 0x13, (byte) 0xB9, (byte) 0x82, (byte) 0x57, (byte) 0xD1, (byte) 0x72,
-        (byte) 0x0D, (byte) 0xA7, (byte) 0xF8, (byte) 0x67, (byte) 0xB8, (byte) 0x55,
-        (byte) 0xF3, (byte) 0x06, (byte) 0xAE, (byte) 0xA7, (byte) 0x69, (byte) 0x66,
-        (byte) 0x0B, (byte) 0x80, (byte) 0x56, (byte) 0x65, (byte) 0xC7, (byte) 0xE9,
-        (byte) 0x60, (byte) 0xDC, (byte) 0x2D, (byte) 0x4B, (byte) 0x26, (byte) 0xA9,
-        (byte) 0xED, (byte) 0x54, (byte) 0x79, (byte) 0x9E, (byte) 0x55, (byte) 0x1D,
-        (byte) 0xEE, (byte) 0x78, (byte) 0x49, (byte) 0xA1, (byte) 0x1F, (byte) 0x9B,
-        (byte) 0x37, (byte) 0xC0, (byte) 0xBA, (byte) 0xE6, (byte) 0x4B, (byte) 0x3B,
-        (byte) 0xAF, (byte) 0x12, (byte) 0x99, (byte) 0x32, (byte) 0x14, (byte) 0x8C,
-        (byte) 0x4D, (byte) 0xEB, (byte) 0x08, (byte) 0xA4, (byte) 0xE3, (byte) 0xC6,
-        (byte) 0x37, (byte) 0x8B, (byte) 0x6E, (byte) 0x7C, (byte) 0xEC, (byte) 0xA3,
-        (byte) 0x78, (byte) 0xED, (byte) 0x4E, (byte) 0x36, (byte) 0xBC, (byte) 0xA2,
-        (byte) 0x7D, (byte) 0x11, (byte) 0x0E, (byte) 0xD0, (byte) 0x53, (byte) 0x14,
-        (byte) 0x93, (byte) 0x16, (byte) 0x54, (byte) 0x45, (byte) 0x79, (byte) 0x7A,
-        (byte) 0x1A, (byte) 0xA1, (byte) 0xEC, (byte) 0xF3, (byte) 0x12, (byte) 0x3F,
-        (byte) 0xFE, (byte) 0x68, (byte) 0xFF, (byte) 0x5A, (byte) 0x3F, (byte) 0xE7,
-        (byte) 0x13, (byte) 0x37, (byte) 0xEB, (byte) 0x60, (byte) 0x0A, (byte) 0x8E,
-        (byte) 0x4F, (byte) 0x54, (byte) 0x46, (byte) 0x19, (byte) 0x82, (byte) 0xBF,
-        (byte) 0xB7, (byte) 0xD2, (byte) 0x19, (byte) 0x71, (byte) 0x78, (byte) 0x38,
-        (byte) 0x4C, (byte) 0xE3, (byte) 0xC4, (byte) 0xEA, (byte) 0x8F, (byte) 0x9B,
-        (byte) 0xE5, (byte) 0xBA, (byte) 0x06, (byte) 0xFC,
-    };
-    private static final PSSParameterSpec SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
-            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 190, 1);
-
-    public void testGetCommonInstances_Success() throws Exception {
-        assertNotNull(Signature.getInstance("SHA1withRSA"));
-        assertNotNull(Signature.getInstance("SHA256withRSA"));
-        assertNotNull(Signature.getInstance("SHA384withRSA"));
-        assertNotNull(Signature.getInstance("SHA512withRSA"));
-        assertNotNull(Signature.getInstance("NONEwithRSA"));
-        assertNotNull(Signature.getInstance("MD5withRSA"));
-        assertNotNull(Signature.getInstance("SHA1withDSA"));
-    }
-
-    public void testVerify_SHA1withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(SHA1withRSA_Vector1Signature));
-    }
-
-    public void testVerify_SHA256withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(SHA256withRSA_Vector2Signature));
-    }
-
-    public void testVerify_SHA384withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(SHA384withRSA_Vector2Signature));
-    }
-
-    public void testVerify_SHA512withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(SHA512withRSA_Vector2Signature));
-    }
-
-    public void testVerify_MD5withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("MD5withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(MD5withRSA_Vector2Signature));
-    }
-
-    public void testVerify_SHA1withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initVerify(pubKey);
-        assertPSSAlgorithmParametersEquals(
-                SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA1withRSAPSS_Vector2Signature));
-    }
-
-    public void testVerify_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA1withRSAPSS_NoSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA1withRSAPSS_MaxSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA224withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initVerify(pubKey);
-        assertPSSAlgorithmParametersEquals(
-                SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA224withRSAPSS_Vector2Signature));
-    }
-
-    public void testVerify_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA224withRSAPSS_NoSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA224withRSAPSS_MaxSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA256withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initVerify(pubKey);
-        assertPSSAlgorithmParametersEquals(
-                SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA256withRSAPSS_Vector2Signature));
-    }
-
-    public void testVerify_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA256withRSAPSS_NoSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA256withRSAPSS_MaxSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA384withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initVerify(pubKey);
-        assertPSSAlgorithmParametersEquals(
-                SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA384withRSAPSS_Vector2Signature));
-    }
-
-    public void testVerify_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA384withRSAPSS_NoSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA384withRSAPSS_MaxSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA512withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initVerify(pubKey);
-        assertPSSAlgorithmParametersEquals(
-                SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA512withRSAPSS_Vector2Signature));
-    }
-
-    public void testVerify_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA512withRSAPSS_NoSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        assertTrue("Signature must verify",
-                sig.verify(SHA512withRSAPSS_MaxSalt_Vector2Signature));
-    }
-
-    public void testVerify_SHA1withRSA_Key_InitSignThenInitVerify_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(privKeySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-
-        // Start a signing operation
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        // Switch to verify
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-
-        assertTrue("Signature must match expected signature",
-                sig.verify(SHA1withRSA_Vector1Signature));
-    }
-
-    public void testVerify_SHA1withRSA_Key_TwoMessages_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-        sig.initVerify(pubKey);
-
-        sig.update(Vector1Data);
-        assertTrue("First signature must match expected signature",
-                sig.verify(SHA1withRSA_Vector1Signature));
-
-        sig.update(Vector2Data);
-        assertTrue("Second signature must match expected signature",
-                sig.verify(SHA1withRSA_Vector2Signature));
-    }
-
-    public void testVerify_SHA1withRSA_Key_WrongExpectedSignature_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-
-        assertFalse("Signature should fail to verify", sig.verify(SHA1withRSA_Vector2Signature));
-    }
-
-    public void testSign_SHA1withRSA_CrtKeyWithPublicExponent_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent, RSA_2048_privateExponent, null, null, null, null, null);
-
-        // The RI fails on this key which is totally unreasonable.
-        final PrivateKey privKey;
-        try {
-            privKey = kf.generatePrivate(keySpec);
-        } catch (NullPointerException e) {
-            if (StandardNames.IS_RI) {
-                return;
-            } else {
-                fail("Private key should be created");
-                return;
-            }
-        }
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector1Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA1withRSA_Vector1Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA1withRSA_CrtKey_NoPrivateExponent_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent, null, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
-
-        // Failing on this key early is okay.
-        final PrivateKey privKey;
-        try {
-            privKey = kf.generatePrivate(keySpec);
-        } catch (NullPointerException e) {
-            return;
-        } catch (InvalidKeySpecException e) {
-            return;
-        }
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-
-        try {
-            sig.initSign(privKey);
-            fail("Should throw error when private exponent is not available");
-        } catch (InvalidKeyException expected) {
-        }
-    }
-
-    public void testSign_SHA1withRSA_CrtKey_NoModulus_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(null, RSA_2048_publicExponent,
-                RSA_2048_privateExponent, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
-
-        // Failing on this key early is okay.
-        final PrivateKey privKey;
-        try {
-            privKey = kf.generatePrivate(keySpec);
-        } catch (NullPointerException e) {
-            return;
-        } catch (InvalidKeySpecException e) {
-            return;
-        }
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-
-        try {
-            sig.initSign(privKey);
-            fail("Should throw error when modulus is not available");
-        } catch (InvalidKeyException expected) {
-        }
-    }
-
-    public void testSign_SHA1withRSA_Key_EmptyKey_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(null, null);
-
-        // Failing on this key early is okay.
-        final PrivateKey privKey;
-        try {
-            privKey = kf.generatePrivate(keySpec);
-        } catch (NullPointerException e) {
-            return;
-        } catch (InvalidKeySpecException e) {
-            return;
-        }
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-
-        try {
-            sig.initSign(privKey);
-            fail("Should throw error when key is empty");
-        } catch (InvalidKeyException expected) {
-        }
-    }
-
-    public void testSign_SHA1withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector1Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA1withRSA_Vector1Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA224withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-
-        final PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA224withRSA_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA256withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-
-        final PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA256withRSA_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA384withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA384withRSA_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA512withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA512withRSA_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_MD5withRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("MD5withRSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, MD5withRSA_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA1withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA1withRSAPSS_NoSalt_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig = Signature.getInstance("SHA1withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA224withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA224withRSAPSS_NoSalt_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig = Signature.getInstance("SHA224withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA256withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA256withRSAPSS_NoSalt_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig = Signature.getInstance("SHA256withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA384withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA384withRSAPSS_NoSalt_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig = Signature.getInstance("SHA384withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA512withRSAPSS_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, SHA512withRSAPSS_NoSalt_Vector2Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initSign(privKey);
-        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertPSSAlgorithmParametersEquals(
-                SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig = Signature.getInstance("SHA512withRSA/PSS");
-        sig.initVerify(pubKey);
-        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testSign_NONEwithRSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initSign(privKey);
-        sig.update(Vector1Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature should match expected",
-                Arrays.equals(signature, NONEwithRSA_Vector1Signature));
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testVerify_NONEwithRSA_Key_WrongSignature_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-        assertFalse("Invalid signature must not verify",
-                sig.verify("Invalid".getBytes(UTF_8)));
-    }
-
-    public void testSign_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initSign(privKey);
-
-        final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
-        for (int i = 0; i < oneTooBig; i++) {
-            sig.update((byte) i);
-        }
-
-        try {
-            sig.sign();
-            fail("Should throw exception when data is too large");
-        } catch (SignatureException expected) {
-        }
-    }
-
-    public void testSign_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
-                RSA_2048_privateExponent);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initSign(privKey);
-
-        // This should make it two bytes too big.
-        final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
-        for (int i = 0; i < oneTooBig; i++) {
-            sig.update((byte) i);
-        }
-
-        try {
-            sig.sign();
-            fail("Should throw exception when data is too large");
-        } catch (SignatureException expected) {
-        }
-    }
-
-    public void testVerify_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initVerify(pubKey);
-
-        // This should make it one bytes too big.
-        final int oneTooBig = RSA_2048_modulus.bitLength() + 1;
-        final byte[] vector = new byte[oneTooBig];
-        for (int i = 0; i < oneTooBig; i++) {
-            vector[i] = (byte) Vector1Data[i % Vector1Data.length];
-        }
-        sig.update(vector);
-
-        assertFalse("Should not verify when signature is too large",
-                sig.verify(NONEwithRSA_Vector1Signature));
-    }
-
-    public void testVerify_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initVerify(pubKey);
-
-        // This should make it twice as big as it should be.
-        final int tooBig = RSA_2048_modulus.bitLength() * 2;
-        for (int i = 0; i < tooBig; i++) {
-            sig.update((byte) Vector1Data[i % Vector1Data.length]);
-        }
-
-        assertFalse("Should not verify when signature is too large",
-                sig.verify(NONEwithRSA_Vector1Signature));
-    }
-
-    public void testVerify_NONEwithRSA_Key_SignatureTooSmall_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-
-        assertFalse("Invalid signature should not verify",
-                sig.verify("Invalid sig".getBytes(UTF_8)));
-    }
-
-    public void testVerify_NONEwithRSA_Key_SignatureTooLarge_Failure() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-
-        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
-                RSA_2048_publicExponent);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("NONEwithRSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector1Data);
-
-        byte[] invalidSignature = new byte[NONEwithRSA_Vector1Signature.length * 2];
-        System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature, 0,
-                NONEwithRSA_Vector1Signature.length);
-        System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature,
-                NONEwithRSA_Vector1Signature.length, NONEwithRSA_Vector1Signature.length);
-
-        try {
-            sig.verify(invalidSignature);
-            fail("Should throw exception when signature is too large");
-        } catch (SignatureException expected) {
-        }
-    }
-
-    public void testSign_NONEwithECDSA_Key_Success() throws Exception {
-        KeyPair keys = keyPair("NONEwithECDSA", null);
-        Signature sig = Signature.getInstance("NONEwithECDSA");
-
-        sig.initSign(keys.getPrivate());
-        sig.update(Vector1Data);
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-        assertTrue("Signature must not be empty", signature.length > 0);
-
-        sig.initVerify(keys.getPublic());
-        sig.update(Vector1Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testVerify_NONEwithECDSA_Key_Success() throws Exception {
-        PublicKey pub = getNamedCurveEcPublicKey();
-        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
-        Signature sig = Signature.getInstance("NONEwithECDSA");
-
-        // NAMED_CURVE_SIGNATURE was signed using SHA1withECDSA, so NONEwithECDSA should
-        // verify the digest
-        sig.initVerify(pub);
-        sig.update(sha1.digest(NAMED_CURVE_VECTOR));
-        assertTrue(sig.verify(NAMED_CURVE_SIGNATURE));
-    }
-
-    public void testVerify_NONEwithECDSA_Key_WrongData_Failure() throws Exception {
-        PublicKey pub = getNamedCurveEcPublicKey();
-        Signature sig = Signature.getInstance("NONEwithECDSA");
-
-        sig.initVerify(pub);
-        sig.update(NAMED_CURVE_VECTOR);
-        assertFalse(sig.verify(NAMED_CURVE_SIGNATURE));
-    }
-
-    public void testVerify_NONEwithECDSA_Key_SingleByte_Failure() throws Exception {
-        PublicKey pub = getNamedCurveEcPublicKey();
-        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
-        Signature sig = Signature.getInstance("NONEwithECDSA");
-
-        byte[] corrupted = new byte[NAMED_CURVE_SIGNATURE.length];
-        corrupted[0] ^= 1;
-
-        sig.initVerify(pub);
-        sig.update(sha1.digest(NAMED_CURVE_VECTOR));
-        try {
-            assertFalse(sig.verify(corrupted));
-        } catch (SignatureException expected) {
-            // It's valid to either return false or throw an exception, accept either
-        }
-    }
-
-    /*
-     * These tests were generated with this DSA private key:
-     *
-     * -----BEGIN DSA PRIVATE KEY-----
-     * MIIBugIBAAKBgQCeYcKJ73epThNnZB8JAf4kE1Pgt5CoTnb+iYJ/esU8TgwgVTCV
-     * QoXhQH0njwcN6NyZ77MHlDTWfP+cvmnT60Q3UO9J+OJb2NEQhJfq46UcwE5pynA9
-     * eLkW5f5hXYpasyxhtgE70AF8Mo3h82kOi1jGzwCU+EkqS+raAP9L0L5AIwIVAL/u
-     * qg8SNFBy+GAT2PFBARClL1dfAoGAd9R6EsyBfn7rOvvmhm1aEB2tqU+5A10hGuQw
-     * lXWOzV7RvQpF7uf3a2UCYNAurz28B90rjjPAk4DZK6dxV3a8jrng1/QjjUEal08s
-     * G9VLZuj60lANF6s0MT2kiNiOqKduFwO3D2h8ZHuSuGPkmmcYgSfUCxNI031O9qiP
-     * VhctCFECgYAz7i1DhjRGUkCdYQd5tVaI42lhXOV71MTYPbuFOIxTL/hny7Z0PZWR
-     * A1blmYE6vrArDEhzpmRvDJZSIMzMfJjUIGu1KO73zpo9siK0xY0/sw5r3QC9txP2
-     * 2Mv3BUIl5TLrs9outQJ0VMwldY2fElgCLWcSVkH44qZwWir1cq+cIwIUEGPDardb
-     * pNvWlWgTDD6a6ZTby+M=
-     * -----END DSA PRIVATE KEY-----
-     *
-     */
-
-    private static final BigInteger DSA_priv = new BigInteger(new byte[] {
-        (byte) 0x10, (byte) 0x63, (byte) 0xc3, (byte) 0x6a, (byte) 0xb7, (byte) 0x5b, (byte) 0xa4, (byte) 0xdb,
-        (byte) 0xd6, (byte) 0x95, (byte) 0x68, (byte) 0x13, (byte) 0x0c, (byte) 0x3e, (byte) 0x9a, (byte) 0xe9,
-        (byte) 0x94, (byte) 0xdb, (byte) 0xcb, (byte) 0xe3,
-    });
-
-    private static final BigInteger DSA_pub = new BigInteger(new byte[] {
-        (byte) 0x33, (byte) 0xee, (byte) 0x2d, (byte) 0x43, (byte) 0x86, (byte) 0x34, (byte) 0x46, (byte) 0x52,
-        (byte) 0x40, (byte) 0x9d, (byte) 0x61, (byte) 0x07, (byte) 0x79, (byte) 0xb5, (byte) 0x56, (byte) 0x88,
-        (byte) 0xe3, (byte) 0x69, (byte) 0x61, (byte) 0x5c, (byte) 0xe5, (byte) 0x7b, (byte) 0xd4, (byte) 0xc4,
-        (byte) 0xd8, (byte) 0x3d, (byte) 0xbb, (byte) 0x85, (byte) 0x38, (byte) 0x8c, (byte) 0x53, (byte) 0x2f,
-        (byte) 0xf8, (byte) 0x67, (byte) 0xcb, (byte) 0xb6, (byte) 0x74, (byte) 0x3d, (byte) 0x95, (byte) 0x91,
-        (byte) 0x03, (byte) 0x56, (byte) 0xe5, (byte) 0x99, (byte) 0x81, (byte) 0x3a, (byte) 0xbe, (byte) 0xb0,
-        (byte) 0x2b, (byte) 0x0c, (byte) 0x48, (byte) 0x73, (byte) 0xa6, (byte) 0x64, (byte) 0x6f, (byte) 0x0c,
-        (byte) 0x96, (byte) 0x52, (byte) 0x20, (byte) 0xcc, (byte) 0xcc, (byte) 0x7c, (byte) 0x98, (byte) 0xd4,
-        (byte) 0x20, (byte) 0x6b, (byte) 0xb5, (byte) 0x28, (byte) 0xee, (byte) 0xf7, (byte) 0xce, (byte) 0x9a,
-        (byte) 0x3d, (byte) 0xb2, (byte) 0x22, (byte) 0xb4, (byte) 0xc5, (byte) 0x8d, (byte) 0x3f, (byte) 0xb3,
-        (byte) 0x0e, (byte) 0x6b, (byte) 0xdd, (byte) 0x00, (byte) 0xbd, (byte) 0xb7, (byte) 0x13, (byte) 0xf6,
-        (byte) 0xd8, (byte) 0xcb, (byte) 0xf7, (byte) 0x05, (byte) 0x42, (byte) 0x25, (byte) 0xe5, (byte) 0x32,
-        (byte) 0xeb, (byte) 0xb3, (byte) 0xda, (byte) 0x2e, (byte) 0xb5, (byte) 0x02, (byte) 0x74, (byte) 0x54,
-        (byte) 0xcc, (byte) 0x25, (byte) 0x75, (byte) 0x8d, (byte) 0x9f, (byte) 0x12, (byte) 0x58, (byte) 0x02,
-        (byte) 0x2d, (byte) 0x67, (byte) 0x12, (byte) 0x56, (byte) 0x41, (byte) 0xf8, (byte) 0xe2, (byte) 0xa6,
-        (byte) 0x70, (byte) 0x5a, (byte) 0x2a, (byte) 0xf5, (byte) 0x72, (byte) 0xaf, (byte) 0x9c, (byte) 0x23,
-    });
-
-    private static final BigInteger DSA_P = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
-        (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
-        (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
-        (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
-        (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
-        (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
-        (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
-        (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
-        (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
-        (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
-        (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
-        (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
-        (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
-        (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
-        (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
-        (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
-        (byte) 0x23,
-    });
-
-    private static final BigInteger DSA_Q = new BigInteger(new byte[] {
-        (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
-        (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
-        (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
-    });
-
-    private static final BigInteger DSA_G = new BigInteger(new byte[] {
-        (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
-        (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
-        (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
-        (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
-        (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
-        (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
-        (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
-        (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
-        (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
-        (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
-        (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
-        (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
-        (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
-        (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
-        (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
-        (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
-    });
-
-    /**
-     * A possible signature using SHA1withDSA of Vector2Data. Note that DSS is
-     * randomized, so this won't be the exact signature you'll get out of
-     * another signing operation unless you use a fixed RNG.
-     */
-    public static final byte[] SHA1withDSA_Vector2Signature = new byte[] {
-        (byte) 0x30, (byte) 0x2d, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x88, (byte) 0xef, (byte) 0xac,
-        (byte) 0x2b, (byte) 0x8b, (byte) 0xe2, (byte) 0x61, (byte) 0xc6, (byte) 0x2b, (byte) 0xea, (byte) 0xd5,
-        (byte) 0x96, (byte) 0xbc, (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x0c, (byte) 0x1f, (byte) 0xed,
-        (byte) 0x11, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0xc4, (byte) 0xfc, (byte) 0x82, (byte) 0x6f,
-        (byte) 0x17, (byte) 0xdc, (byte) 0x87, (byte) 0x82, (byte) 0x75, (byte) 0x23, (byte) 0xd4, (byte) 0x58,
-        (byte) 0xdc, (byte) 0x73, (byte) 0x3d, (byte) 0xf3, (byte) 0x51, (byte) 0xc0, (byte) 0x57,
-    };
-
-    /**
-     * A possible signature using SHA224withDSA of Vector2Data. Note that DSS is
-     * randomized, so this won't be the exact signature you'll get out of
-     * another signing operation unless you use a fixed RNG.
-     */
-    public static final byte[] SHA224withDSA_Vector2Signature = new byte[] {
-        (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xAD, (byte) 0xE5, (byte) 0x6D,
-        (byte) 0xF5, (byte) 0x11, (byte) 0x8D, (byte) 0x2E, (byte) 0x62, (byte) 0x5D, (byte) 0x98, (byte) 0x8A,
-        (byte) 0xC4, (byte) 0x88, (byte) 0x7E, (byte) 0xE6, (byte) 0xA3, (byte) 0x44, (byte) 0x99, (byte) 0xEF,
-        (byte) 0x49, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0x3E, (byte) 0x32, (byte) 0xD6, (byte) 0xF9,
-        (byte) 0x79, (byte) 0x2C, (byte) 0x60, (byte) 0x6E, (byte) 0xF9, (byte) 0xA9, (byte) 0x78, (byte) 0xE7,
-        (byte) 0x4B, (byte) 0x87, (byte) 0x08, (byte) 0x96, (byte) 0x60, (byte) 0xDE, (byte) 0xB5
-    };
-
-    /**
-     * A possible signature using SHA256withDSA of Vector2Data. Note that DSS is
-     * randomized, so this won't be the exact signature you'll get out of
-     * another signing operation unless you use a fixed RNG.
-     */
-    public static final byte[] SHA256withDSA_Vector2Signature = new byte[] {
-        (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x14, (byte) 0x0A, (byte) 0xB1, (byte) 0x74, (byte) 0x45,
-        (byte) 0xE1, (byte) 0x63, (byte) 0x43, (byte) 0x68, (byte) 0x65, (byte) 0xBC, (byte) 0xCA, (byte) 0x45,
-        (byte) 0x27, (byte) 0x11, (byte) 0x4D, (byte) 0x52, (byte) 0xFB, (byte) 0x22, (byte) 0x93, (byte) 0xDD,
-        (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x98, (byte) 0x32, (byte) 0x1A, (byte) 0x16, (byte) 0x77,
-        (byte) 0x49, (byte) 0xA7, (byte) 0x78, (byte) 0xFD, (byte) 0xE0, (byte) 0xF7, (byte) 0x71, (byte) 0xD4,
-        (byte) 0x80, (byte) 0x50, (byte) 0xA7, (byte) 0xDD, (byte) 0x94, (byte) 0xD1, (byte) 0x6C
-    };
-
-    public void testSign_SHA1withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA1withDSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testVerify_SHA1withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("SHA1withDSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(SHA1withDSA_Vector2Signature));
-    }
-
-    public void testSign_SHA224withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA224withDSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testVerify_SHA224withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("SHA224withDSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(SHA224withDSA_Vector2Signature));
-    }
-
-    public void testSign_SHA256withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
-        PrivateKey privKey = kf.generatePrivate(keySpec);
-
-        Signature sig = Signature.getInstance("SHA256withDSA");
-        sig.initSign(privKey);
-        sig.update(Vector2Data);
-
-        byte[] signature = sig.sign();
-        assertNotNull("Signature must not be null", signature);
-
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(signature));
-    }
-
-    public void testVerify_SHA256withDSA_Key_Success() throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("DSA");
-        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
-        PublicKey pubKey = kf.generatePublic(pubKeySpec);
-
-        Signature sig = Signature.getInstance("SHA256withDSA");
-        sig.initVerify(pubKey);
-        sig.update(Vector2Data);
-        assertTrue("Signature must verify correctly", sig.verify(SHA256withDSA_Vector2Signature));
-    }
-
     // NetscapeCertRequest looks up Signature algorithms by OID from
     // BC but BC version 1.47 had registration bugs and MD5withRSA was
     // overlooked.  http://b/7453821
@@ -3321,79 +469,6 @@
         assertEquals(oid, signature.getAlgorithm());
     }
 
-    private final int THREAD_COUNT = 10;
-
-    private void testSignature_MultipleThreads_Misuse(final Signature s) throws Exception {
-        ExecutorService es = Executors.newFixedThreadPool(THREAD_COUNT);
-
-        final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
-        final byte[] message = new byte[64];
-
-        for (int i = 0; i < THREAD_COUNT; i++) {
-            es.submit(new Callable<Void>() {
-                @Override
-                public Void call() throws Exception {
-                    // Try to make sure all the threads are ready first.
-                    latch.countDown();
-                    latch.await();
-
-                    for (int j = 0; j < 100; j++) {
-                        s.update(message);
-                        s.sign();
-                    }
-
-                    return null;
-                }
-            });
-        }
-        es.shutdown();
-        assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES));
-    }
-
-    private static final byte[] NAMED_CURVE_VECTOR = "Satoshi Nakamoto".getBytes(UTF_8);
-    // $ echo -n "Satoshi Nakamoto" > signed
-    // $ openssl dgst -ecdsa-with-SHA1 -sign key.pem -out sig signed
-    private static final byte[] NAMED_CURVE_SIGNATURE = HexEncoding.decode("304402205b41ece6dcc1c5bfcfdae74658d99c08c5e783f3926c11ecc1a8bea5d95cdf27022061a7d5fc687287e2e02dd7c6723e2e27fe0555f789590a37e96b1bb0355b4df0");
-
-    private static PublicKey getNamedCurveEcPublicKey() throws Exception {
-        // These are the parameters for the BitCoin curve (secp256k1). See
-        // https://en.bitcoin.it/wiki/Secp256k1.
-        final BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
-        final BigInteger a = BigInteger.valueOf(0);
-        final BigInteger b = BigInteger.valueOf(7);
-        final BigInteger x = new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
-        final BigInteger y = new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
-        final BigInteger order = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
-        final int cofactor = 1;
-
-        final ECParameterSpec spec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(p), a, b), new ECPoint(x, y), order, cofactor);
-
-        // $ openssl ecparam -name secp256k1 -genkey > key.pem
-        // $ openssl ec -text -noout < key.pem
-        final BigInteger Px = new BigInteger("2d45572747a625db5fd23b30f97044a682f2d42d31959295043c1fa0034c8ed3", 16);
-        final BigInteger Py = new BigInteger("4d330f52e4bba00145a331041c8bbcf300c4fbfdf3d63d8de7608155b2793808", 16);
-
-        final KeyFactory factory = KeyFactory.getInstance("EC");
-        ECPublicKeySpec keySpec = new ECPublicKeySpec(new ECPoint(Px, Py), spec);
-        return factory.generatePublic(keySpec);
-    }
-
-    public void testArbitraryCurve() throws Exception {
-        final PublicKey pub = getNamedCurveEcPublicKey();
-
-        Signature ecdsaVerify = Signature.getInstance("SHA1withECDSA");
-        ecdsaVerify.initVerify(pub);
-        ecdsaVerify.update(NAMED_CURVE_VECTOR);
-        boolean result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
-        assertEquals(true, result);
-
-        ecdsaVerify = Signature.getInstance("SHA1withECDSA");
-        ecdsaVerify.initVerify(pub);
-        ecdsaVerify.update("Not Satoshi Nakamoto".getBytes(UTF_8));
-        result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
-        assertEquals(false, result);
-    }
-
     /**
      * When an instance of a Signature is obtained, it's actually wrapped in an
      * implementation that makes sure the correct SPI is selected and then calls
@@ -3441,45 +516,6 @@
         verify(signatureSpi).engineGetParameters();
     }
 
-    private static void assertPSSAlgorithmParametersEquals(
-            PSSParameterSpec expectedSpec, AlgorithmParameters actual)
-                    throws InvalidParameterSpecException {
-        assertNotNull(actual);
-        assertEqualsIgnoreCase("PSS", actual.getAlgorithm());
-        PSSParameterSpec actualSpec = actual.getParameterSpec(PSSParameterSpec.class);
-        assertPSSParameterSpecEquals(expectedSpec, actualSpec);
-    }
-
-    private static void assertPSSParameterSpecEquals(
-            PSSParameterSpec expected, PSSParameterSpec actual) {
-        assertEqualsIgnoreCase(expected.getDigestAlgorithm(), actual.getDigestAlgorithm());
-        assertEqualsIgnoreCase(expected.getMGFAlgorithm(), actual.getMGFAlgorithm());
-        if (!"MGF1".equalsIgnoreCase(expected.getMGFAlgorithm())) {
-            fail("Unsupported MGF algorithm: " + expected.getMGFAlgorithm());
-        }
-        MGF1ParameterSpec expectedMgfParams = (MGF1ParameterSpec) expected.getMGFParameters();
-        MGF1ParameterSpec actualMgfParams = (MGF1ParameterSpec) actual.getMGFParameters();
-        assertEqualsIgnoreCase(
-                expectedMgfParams.getDigestAlgorithm(), actualMgfParams.getDigestAlgorithm());
-        assertEquals(expected.getSaltLength(), actual.getSaltLength());
-        assertEquals(expected.getTrailerField(), actual.getTrailerField());
-    }
-
-    private static void assertEqualsIgnoreCase(String expected, String actual) {
-        if (expected == null) {
-            if (actual == null) {
-                return;
-            }
-            fail("Expected null, actual: <" + actual + ">");
-        } else if (actual == null) {
-            fail("Expected: <" + expected + ">, actual: null");
-        } else {
-            if (!expected.equalsIgnoreCase(actual)) {
-                fail("Expected: <" + expected + ">, actual: <" + actual + ">");
-            }
-        }
-    }
-
     public static class MockableProvider extends Provider {
         protected MockableProvider() {
             super("MockableProvider", 1.0, "Used by Mockito");
diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
deleted file mode 100644
index 1c85b83..0000000
--- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.security.cert;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.android.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
-import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
-import com.android.org.bouncycastle.asn1.x509.Extension;
-import com.android.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
-import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.List;
-import java.util.TimeZone;
-
-import javax.security.auth.x500.X500Principal;
-
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-
-import dalvik.system.VMRuntime;
-import sun.security.jca.Providers;
-
-public class CertificateFactoryTest extends TestCase {
-
-    // Allow access to deprecated BC algorithms in this test, so we can ensure they
-    // continue to work
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                VMRuntime.getRuntime().getTargetSdkVersion());
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        Providers.setMaximumAllowableApiLevelForBcDeprecation(
-                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
-        super.tearDown();
-    }
-
-    private static final String VALID_CERTIFICATE_PEM =
-            "-----BEGIN CERTIFICATE-----\n"
-            + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n"
-            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n"
-            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\n"
-            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n"
-            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n"
-            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n"
-            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\n"
-            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\n"
-            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\n"
-            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n"
-            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n"
-            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n"
-            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n"
-            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n"
-            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\n"
-            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\n"
-            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\n"
-            + "-----END CERTIFICATE-----\n";
-
-    private static final String VALID_CERTIFICATE_PEM_CRLF =
-            "-----BEGIN CERTIFICATE-----\r\n"
-            + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\r\n"
-            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\r\n"
-            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\r\n"
-            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\r\n"
-            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\r\n"
-            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\r\n"
-            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\r\n"
-            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\r\n"
-            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\r\n"
-            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\r\n"
-            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\r\n"
-            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\r\n"
-            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\r\n"
-            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\r\n"
-            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\r\n"
-            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\r\n"
-            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\r\n"
-            + "-----END CERTIFICATE-----\r\n";
-
-    private static final byte[] VALID_CERTIFICATE_PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
-            .getBytes(UTF_8);
-
-    private static final byte[] VALID_CERTIFICATE_PEM_DATA =
-             ("MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM"
-            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg"
-            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x"
-            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
-            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw"
-            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
-            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN"
-            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L"
-            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM"
-            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl"
-            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF"
-            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw"
-            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0"
-            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF"
-            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5"
-            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6"
-            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==").getBytes(UTF_8);
-
-    private static final byte[] VALID_CERTIFICATE_PEM_FOOTER = "\n-----END CERTIFICATE-----\n"
-            .getBytes(UTF_8);
-
-    private static final String INVALID_CERTIFICATE_PEM =
-            "-----BEGIN CERTIFICATE-----\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
-            + "AAAAAAAA\n"
-            + "-----END CERTIFICATE-----";
-
-    public void test_generateCertificate() throws Exception {
-        Provider[] providers = Security.getProviders("CertificateFactory.X509");
-        for (Provider p : providers) {
-            CertificateFactory cf = CertificateFactory.getInstance("X509", p);
-            try {
-                test_generateCertificate(cf);
-                test_generateCertificate_InputStream_Offset_Correct(cf);
-                test_generateCertificate_InputStream_Empty(cf);
-                test_generateCertificate_InputStream_InvalidStart_Failure(cf);
-                test_generateCertificate_AnyLineLength_Success(cf);
-            } catch (Throwable e) {
-                throw new Exception("Problem testing " + p.getName(), e);
-            }
-        }
-    }
-
-    private void test_generateCertificate(CertificateFactory cf) throws Exception {
-        {
-            byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
-            Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
-            assertNotNull(c);
-        }
-
-        {
-            byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes(UTF_8);
-            Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
-            assertNotNull(c);
-        }
-
-        try {
-            byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes(UTF_8);
-            cf.generateCertificate(new ByteArrayInputStream(invalid));
-            fail();
-        } catch (CertificateException expected) {
-        }
-    }
-
-    /*
-     * Checks all possible line lengths for PEM input data.
-     */
-    private void test_generateCertificate_AnyLineLength_Success(CertificateFactory cf)
-            throws Exception {
-        // RI barfs on this
-        if (StandardNames.IS_RI) {
-            return;
-        }
-
-        int lineLength = 1;
-        int maxLineLength = VALID_CERTIFICATE_PEM_DATA.length;
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        baos.write(VALID_CERTIFICATE_PEM_HEADER);
-        int offset = 0;
-        while (lineLength < (maxLineLength - 4)) {
-            int end = offset + lineLength;
-            if (end > VALID_CERTIFICATE_PEM_DATA.length) {
-                end = VALID_CERTIFICATE_PEM_DATA.length;
-            }
-            baos.write(Arrays.copyOfRange(VALID_CERTIFICATE_PEM_DATA, offset, end));
-            baos.write('\n');
-            offset += lineLength;
-            if (offset >= maxLineLength) {
-                baos.write(VALID_CERTIFICATE_PEM_FOOTER);
-                try {
-                    Certificate c =
-                            cf.generateCertificate(new ByteArrayInputStream(baos.toByteArray()));
-                    assertNotNull(c);
-                } catch (Exception e) {
-                    throw new Exception("Fail at line length " + lineLength, e);
-                }
-                baos.reset();
-                baos.write(VALID_CERTIFICATE_PEM_HEADER);
-                offset = 0;
-            } else {
-                lineLength++;
-            }
-        }
-
-    }
-
-    private void test_generateCertificate_InputStream_Empty(CertificateFactory cf) throws Exception {
-        try {
-            Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[0]));
-            if (!"BC".equals(cf.getProvider().getName())) {
-                fail("should throw CertificateException: " + cf.getProvider().getName());
-            }
-            assertNull(c);
-        } catch (CertificateException e) {
-            if ("BC".equals(cf.getProvider().getName())) {
-                fail("should return null: " + cf.getProvider().getName());
-            }
-        }
-    }
-
-    private void test_generateCertificate_InputStream_InvalidStart_Failure(CertificateFactory cf)
-            throws Exception {
-        try {
-            Certificate c = cf.generateCertificate(new ByteArrayInputStream(
-                    "-----BEGIN CERTIFICATE-----".getBytes(UTF_8)));
-            if (!"BC".equals(cf.getProvider().getName())) {
-                fail("should throw CertificateException: " + cf.getProvider().getName());
-            }
-            assertNull(c);
-        } catch (CertificateException expected) {
-            if ("BC".equals(cf.getProvider().getName())) {
-                fail("should return null: " + cf.getProvider().getName());
-            }
-        }
-    }
-
-    private void test_generateCertificate_InputStream_Offset_Correct(CertificateFactory cf)
-            throws Exception {
-        byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
-
-        byte[] doubleCertificateData = new byte[valid.length * 2];
-        System.arraycopy(valid, 0, doubleCertificateData, 0, valid.length);
-        System.arraycopy(valid, 0, doubleCertificateData, valid.length, valid.length);
-        MeasuredInputStream certStream = new MeasuredInputStream(new ByteArrayInputStream(
-                doubleCertificateData));
-        Certificate certificate = cf.generateCertificate(certStream);
-        assertNotNull(certificate);
-        assertEquals(valid.length, certStream.getCount());
-    }
-
-    /**
-     * Proxy that counts the number of bytes read from an InputStream.
-     */
-    private static class MeasuredInputStream extends InputStream {
-        private long mCount = 0;
-
-        private long mMarked = 0;
-
-        private InputStream mStream;
-
-        public MeasuredInputStream(InputStream is) {
-            mStream = is;
-        }
-
-        public long getCount() {
-            return mCount;
-        }
-
-        @Override
-        public int read() throws IOException {
-            int nextByte = mStream.read();
-            mCount++;
-            return nextByte;
-        }
-
-        @Override
-        public int read(byte[] buffer) throws IOException {
-            int count = mStream.read(buffer);
-            mCount += count;
-            return count;
-        }
-
-        @Override
-        public int read(byte[] buffer, int offset, int length) throws IOException {
-            int count = mStream.read(buffer, offset, length);
-            mCount += count;
-            return count;
-        }
-
-        @Override
-        public long skip(long byteCount) throws IOException {
-            long count = mStream.skip(byteCount);
-            mCount += count;
-            return count;
-        }
-
-        @Override
-        public int available() throws IOException {
-            return mStream.available();
-        }
-
-        @Override
-        public void close() throws IOException {
-            mStream.close();
-        }
-
-        @Override
-        public void mark(int readlimit) {
-            mMarked = mCount;
-            mStream.mark(readlimit);
-        }
-
-        @Override
-        public boolean markSupported() {
-            return mStream.markSupported();
-        }
-
-        @Override
-        public synchronized void reset() throws IOException {
-            mCount = mMarked;
-            mStream.reset();
-        }
-    }
-
-    /* CertPath tests */
-    public void testGenerateCertPath() throws Exception {
-        KeyHolder ca = generateCertificate(true, null);
-        KeyHolder cert1 = generateCertificate(true, ca);
-        KeyHolder cert2 = generateCertificate(false, cert1);
-        KeyHolder cert3 = generateCertificate(false, cert2);
-
-        List<X509Certificate> certs = new ArrayList<X509Certificate>();
-        certs.add(cert3.certificate);
-        certs.add(cert2.certificate);
-        certs.add(cert1.certificate);
-
-        List<X509Certificate> duplicatedCerts = new ArrayList<X509Certificate>(certs);
-        duplicatedCerts.add(cert2.certificate);
-
-        Provider[] providers = Security.getProviders("CertificateFactory.X509");
-        for (Provider p : providers) {
-            final CertificateFactory cf = CertificateFactory.getInstance("X.509", p);
-
-            // Duplicate certificates can cause an exception.
-            {
-                final CertPath duplicatedPath = cf.generateCertPath(duplicatedCerts);
-                try {
-                    duplicatedPath.getEncoded();
-                    if (StandardNames.IS_RI) {
-                        fail("duplicate certificates should cause failure: " + p.getName());
-                    }
-                } catch (CertificateEncodingException expected) {
-                    if (!StandardNames.IS_RI) {
-                        fail("duplicate certificates should pass: " + p.getName());
-                    }
-                }
-            }
-
-            testCertPathEncoding(cf, certs, null);
-
-            /* Make sure all encoding entries are the same. */
-            final Iterator<String> it1 = cf.getCertPathEncodings();
-            final Iterator<String> it2 = cf.generateCertPath(certs).getEncodings();
-            for (;;) {
-                assertEquals(p.getName(), it1.hasNext(), it2.hasNext());
-                if (!it1.hasNext()) {
-                    break;
-                }
-
-                String encoding = it1.next();
-                assertEquals(p.getName(), encoding, it2.next());
-
-                try {
-                    it1.remove();
-                    fail("Should not be able to remove from iterator");
-                } catch (UnsupportedOperationException expected) {
-                }
-
-                try {
-                    it2.remove();
-                    fail("Should not be able to remove from iterator");
-                } catch (UnsupportedOperationException expected) {
-                }
-
-                /* Now test using this encoding. */
-                testCertPathEncoding(cf, certs, encoding);
-            }
-        }
-    }
-
-    private void testCertPathEncoding(CertificateFactory cf, List<X509Certificate> expectedCerts,
-            String encoding) throws Exception {
-        final String providerName = cf.getProvider().getName() + "[" + encoding + "]";
-
-        final CertPath pathFromList = cf.generateCertPath(expectedCerts);
-
-        // Create a copy we can modify and discard.
-        final byte[] encodedCopy;
-        if (encoding == null) {
-            encodedCopy = pathFromList.getEncoded();
-            assertNotNull(providerName, encodedCopy);
-
-            // check idempotence
-            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
-                    Arrays.toString(encodedCopy));
-        } else {
-            encodedCopy = pathFromList.getEncoded(encoding);
-            assertNotNull(providerName, encodedCopy);
-
-            // check idempotence
-            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
-                    Arrays.toString(encodedCopy));
-        }
-
-        // Try to modify byte array.
-        encodedCopy[0] ^= (byte) 0xFF;
-
-        // Get a real copy we will use if the test proceeds.
-        final byte[] encoded;
-        if (encoding == null) {
-            encoded = pathFromList.getEncoded();
-            assertNotNull(providerName, encodedCopy);
-
-            // check idempotence
-            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
-                    Arrays.toString(encoded));
-        } else {
-            encoded = pathFromList.getEncoded(encoding);
-            assertNotNull(providerName, encodedCopy);
-
-            // check idempotence
-            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
-                    Arrays.toString(encoded));
-        }
-        assertFalse(providerName, Arrays.toString(encoded).equals(Arrays.toString(encodedCopy)));
-
-        encodedCopy[0] ^= (byte) 0xFF;
-        assertEquals(providerName, Arrays.toString(encoded), Arrays.toString(encodedCopy));
-
-        final CertPath actualPath;
-        if (encoding == null) {
-            actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded));
-        } else {
-            actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded), encoding);
-        }
-
-        // PKCS7 certificate bags are not guaranteed to be in order.
-        final List<? extends Certificate> actualCerts;
-        if (!"PKCS7".equals(encoding)) {
-            actualCerts = actualPath.getCertificates();
-            assertEquals(providerName, expectedCerts, actualCerts);
-        } else {
-            actualCerts = pathFromList.getCertificates();
-        }
-
-        try {
-            actualCerts.remove(0);
-            fail("List of certificate should be immutable");
-        } catch (UnsupportedOperationException expected) {
-        }
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(actualPath);
-        oos.close();
-
-        byte[] serialized = baos.toByteArray();
-        ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
-        ObjectInputStream ois = new ObjectInputStream(bais);
-        Object output = ois.readObject();
-        assertTrue(providerName, output instanceof CertPath);
-
-        assertEquals(providerName, actualPath, (CertPath) output);
-    }
-
-    public static class KeyHolder {
-        public X509Certificate certificate;
-
-        public PrivateKey privateKey;
-    }
-
-    @SuppressWarnings("deprecation")
-    private static KeyHolder generateCertificate(boolean isCa, KeyHolder issuer) throws Exception {
-        Date startDate = new Date();
-
-        GregorianCalendar cal = new GregorianCalendar();
-        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
-        cal.set(2100, 0, 1, 0, 0, 0); // Jan 1, 2100 UTC
-        Date expiryDate = cal.getTime();
-
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
-        KeyPair keyPair = kpg.generateKeyPair();
-
-        BigInteger serial;
-        X500Principal issuerPrincipal;
-        X500Principal subjectPrincipal;
-        PrivateKey caKey;
-        if (issuer != null) {
-            serial = issuer.certificate.getSerialNumber().add(BigInteger.ONE);
-            subjectPrincipal = new X500Principal("CN=Test Certificate Serial #" + serial.toString());
-            issuerPrincipal = issuer.certificate.getSubjectX500Principal();
-            caKey = issuer.privateKey;
-        } else {
-            serial = BigInteger.ONE;
-            subjectPrincipal = new X500Principal("CN=Test CA, O=Tests, C=US");
-            issuerPrincipal = subjectPrincipal;
-            caKey = keyPair.getPrivate();
-        }
-
-        BasicConstraints basicConstraints;
-        if (isCa) {
-            basicConstraints = new BasicConstraints(10 - serial.intValue());
-        } else {
-            basicConstraints = new BasicConstraints(false);
-        }
-
-        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
-
-        PublicKey pubKey = keyPair.getPublic();
-        certGen.setSerialNumber(serial);
-        certGen.setIssuerDN(issuerPrincipal);
-        certGen.setNotBefore(startDate);
-        certGen.setNotAfter(expiryDate);
-        certGen.setSubjectDN(subjectPrincipal);
-        certGen.setPublicKey(pubKey);
-        certGen.setSignatureAlgorithm("SHA1withRSA");
-
-        if (issuer != null) {
-            certGen.addExtension(Extension.authorityKeyIdentifier, false,
-                    new AuthorityKeyIdentifierStructure(issuer.certificate));
-        } else {
-            certGen.addExtension(Extension.authorityKeyIdentifier, false,
-                    new AuthorityKeyIdentifier(generatePublicKeyDigest(pubKey)));
-        }
-
-        certGen.addExtension(Extension.subjectKeyIdentifier, false,
-                new SubjectKeyIdentifier(generatePublicKeyDigest(pubKey)));
-        certGen.addExtension(Extension.basicConstraints, true, basicConstraints);
-
-        X509Certificate cert = certGen.generate(caKey);
-
-        KeyHolder holder = new KeyHolder();
-        holder.certificate = cert;
-        holder.privateKey = keyPair.getPrivate();
-
-        return holder;
-    }
-
-    /**
-     * Generates a type 1 key identifier according to RFC 3280 4.2.1.2.
-     */
-    private static byte[] generatePublicKeyDigest(PublicKey pubKey) {
-        SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
-        MessageDigest sha1digest;
-        try {
-            sha1digest = MessageDigest.getInstance("SHA-1");
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("SHA-1 not available");
-        }
-        return sha1digest.digest(spki.getPublicKeyData().getBytes());
-    }
-}
diff --git a/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java b/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
index 7c60b87..7b725bb 100644
--- a/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
+++ b/luni/src/test/java/libcore/java/security/spec/AlgorithmParametersPSSTest.java
@@ -40,15 +40,8 @@
     private static final byte[] DEFAULT_SPEC_DER_ENCODED = HexEncoding.decode("3000");
 
     private static final PSSParameterSpec WEIRD_SPEC =
-            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA384, 27, 3);
-    private static final byte[] WEIRD_SPEC_DER_ENCODED =
-            HexEncoding.decode(
-                    "3039a00f300d06096086480165030402030500a11c301a06092a864886f70d010108300d060960"
-                    + "86480165030402020500a20302011ba303020103");
-
-    private static final PSSParameterSpec WEIRD2_SPEC =
             new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
-    private static final byte[] WEIRD2_SPEC_DER_ENCODED =
+    private static final byte[] WEIRD_SPEC_DER_ENCODED =
             HexEncoding.decode(
                     "3034a00f300d06096086480165030402040500a11c301a06092a864886f70d010108300d060960"
                     + "86480165030402010500a203020120");
@@ -107,7 +100,6 @@
     public void testInitWithDerEncoded() throws Exception {
         assertInitWithDerEncoded(WEIRD_SPEC_DER_ENCODED, WEIRD_SPEC);
         assertInitWithDerEncoded(DEFAULT_SPEC_DER_ENCODED, DEFAULT_SPEC);
-        assertInitWithDerEncoded(WEIRD2_SPEC_DER_ENCODED, WEIRD2_SPEC);
     }
 
     private void assertInitWithDerEncoded(
@@ -136,7 +128,6 @@
     public void testGetEncoded() throws Exception {
         assertGetEncoded(WEIRD_SPEC, WEIRD_SPEC_DER_ENCODED);
         assertGetEncoded(DEFAULT_SPEC, DEFAULT_SPEC_DER_ENCODED);
-        assertGetEncoded(WEIRD2_SPEC, WEIRD2_SPEC_DER_ENCODED);
     }
 
     private void assertGetEncoded(PSSParameterSpec spec, byte[] expectedEncoded) throws Exception {
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index 65f566e..740e7a5 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -283,6 +283,34 @@
         assertEquals(expected, numberFormat.format(2.01));
     }
 
+    /**
+     * Test no extra spacing between currency symbol and the numeric amount
+     */
+    public void testCurrencySymbolSpacing() {
+        Currency currency = Currency.getInstance(Locale.US);
+        for (Locale locale : Locale.getAvailableLocales()) {
+            DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
+            String formattedZero = new DecimalFormat("0", dfs).format(0);
+
+            assertCurrencyFormat("USD" + formattedZero, "\u00a4\u00a40", dfs, currency, locale);
+            assertCurrencyFormat(formattedZero + "USD", "0\u00a4\u00a4", dfs, currency, locale);
+            assertCurrencyFormat(currency.getSymbol(locale) + formattedZero, "\u00a40", dfs,
+                    currency, locale);
+            assertCurrencyFormat(formattedZero + currency.getSymbol(locale), "0\u00a4", dfs,
+                    currency, locale);
+        }
+    }
+
+    private static void assertCurrencyFormat(String expected, String pattern,
+            DecimalFormatSymbols dfs,
+            Currency currency, Locale locale) {
+        DecimalFormat df = new DecimalFormat(pattern, dfs);
+        df.setCurrency(currency);
+        df.setMaximumFractionDigits(0);
+        assertEquals("Not formatted as expected with pattern " + pattern + " in locale " + locale,
+                expected, df.format(0));
+    }
+
     // http://b/27855939
     public void testBug27855939() {
         DecimalFormat df = new DecimalFormat("00");
@@ -544,6 +572,31 @@
     }
 
     /**
+     * Pattern separator should be localized. http://b/112080617
+     */
+    public void testPatternSeparator() {
+        // Test US locale
+        {
+            DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+            assertEquals(';', df.getDecimalFormatSymbols().getPatternSeparator());
+            // toLocalizedPattern() returns no pattern separator when input pattern has no prefix.
+            // Add prefixes 'AAA'/'BBB' to force pattern separator in output pattern.
+            df.applyLocalizedPattern("'AAA'+0;'BBB'-0");
+            assertEquals("'AAA'+#0;'BBB'-#0", df.toLocalizedPattern());
+            assertEquals("BBB-123", df.format(-123));
+        }
+        // Test a locale using non-ascii-semi-colon pattern separator.
+        {
+            DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(
+                Locale.forLanguageTag("ar-EG"));
+            assertEquals('\u061b', df.getDecimalFormatSymbols().getPatternSeparator());
+            df.applyLocalizedPattern("'AAA'+\u0660\u061b'BBB'-\u0660");
+            assertEquals("'AAA'+#\u0660\u061b'BBB'-#\u0660", df.toLocalizedPattern());
+            assertEquals("BBB-\u0661\u0662\u0663", df.format(-123));
+        }
+    }
+
+    /**
      * Returns DecimalFormat instances created in different ways:
      * <ol>
      * <li>Using an implicit DecimalFormatSymbols created using the default locale.</li>
@@ -602,6 +655,33 @@
         assertParseError(" 0", "1");
     }
 
+    // Test that getMaximumIntegerDigits should return value >= 309 by default, even though a
+    // leading optional digit # is provided in the input pattern. 309 is chosen because
+    // it is the upper limit of integer digits when formatting numbers other than BigInteger
+    // and BigDecimal.
+    public void testDefaultGetMaximumIntegerDigits() {
+        Locale originalLocale = Locale.getDefault();
+        try {
+            Locale.setDefault(Locale.US);
+            DecimalFormat df = new DecimalFormat();
+            int maxIntegerDigits = df.getMaximumIntegerDigits();
+            assertTrue("getMaximumIntegerDigits should be >= 309, but returns " + maxIntegerDigits,
+                    maxIntegerDigits >= 309);
+
+            String[] patterns = new String[] { "0", "#0", "#.", "#", ".#", "#.#", "#,##0.00",
+                    "#,##0.00%", "#,##0.00%", "¤#,##0.00%", "#00.00", "#,#00.00"
+            };
+            for (String pattern : patterns) {
+                df = new DecimalFormat(pattern);
+                maxIntegerDigits = df.getMaximumIntegerDigits();
+                assertTrue("getMaximumIntegerDigits should be >= 309, but returns "
+                                + maxIntegerDigits, maxIntegerDigits >= 309);
+            }
+        } finally {
+            Locale.setDefault(originalLocale);
+        }
+    }
+
 
     private void assertParseError(String pattern, String input) {
         ParsePosition pos = new ParsePosition(0);
diff --git a/luni/src/test/java/libcore/java/util/ArraysTest.java b/luni/src/test/java/libcore/java/util/ArraysTest.java
index 2c9d5c5..b48e8ea 100644
--- a/luni/src/test/java/libcore/java/util/ArraysTest.java
+++ b/luni/src/test/java/libcore/java/util/ArraysTest.java
@@ -534,4 +534,11 @@
         } catch (IllegalArgumentException expected) {
         }
     }
+
+    // http://b/74236526
+    public void test_deepEquals_nestedArraysOfDifferentTypesButEqualValues() {
+        assertTrue(Arrays.deepEquals(
+            new Object[] { new Object[] { "Hello", "world" } },
+            new Object[] { new String[] { "Hello", "world" } }));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java
index c828a08..cdeab95 100644
--- a/luni/src/test/java/libcore/java/util/CalendarTest.java
+++ b/luni/src/test/java/libcore/java/util/CalendarTest.java
@@ -48,7 +48,7 @@
         // get(Calendar.ZONE_OFFSET) returns the zone offset of the time zone passed to setTimeZone.
         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
         assertEquals(0, cal.get(Calendar.ZONE_OFFSET));
-        TimeZone tz = java.util.TimeZone.getTimeZone("GMT+7");
+        TimeZone tz = TimeZone.getTimeZone("GMT+7");
         cal.setTimeZone(tz);
         assertEquals(25200000, cal.get(Calendar.ZONE_OFFSET));
     }
@@ -418,4 +418,16 @@
 
         }
     }
+
+    /**
+     * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
+     * historic behavior on Android; this test exists to avoid unintentional regressions.
+     * http://b/80294184
+     */
+    public void testAllDefaultCalendar_Gregorian() {
+        for (Locale locale : Locale.getAvailableLocales()) {
+            assertTrue("Default calendar should be Gregorian: " + locale,
+                    Calendar.getInstance(locale) instanceof GregorianCalendar);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 969402b..33e427c 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -130,6 +130,30 @@
                 Locale.forLanguageTag("zh-Hant-CN-VARIANT").getDisplayName(Locale.US));
     }
 
+    public void testGetDisplayCountry_locale_null() {
+        assertThrowsNpe(() -> {
+            Locale.forLanguageTag("en-US").getDisplayCountry(null);
+        });
+    }
+
+    public void testGetDisplayLanguage_locale_null() {
+        assertThrowsNpe(() -> {
+            Locale.forLanguageTag("en-US").getDisplayLanguage(null);
+        });
+    }
+
+    public void testGetDisplayScript_locale_null() {
+        assertThrowsNpe(() -> {
+            Locale.forLanguageTag("sr-Cyrl-BA").getDisplayScript(null);
+        });
+    }
+
+    public void testGetDisplayVariant_locale_null() {
+        assertThrowsNpe(() -> {
+            Locale.forLanguageTag("en-US-POSIX").getDisplayVariant(null);
+        });
+    }
+
     public void test_getDisplayCountry_8870289() throws Exception {
         assertEquals("Hong Kong", new Locale("", "HK").getDisplayCountry(Locale.US));
         assertEquals("Macau", new Locale("", "MO").getDisplayCountry(Locale.US));
@@ -220,6 +244,25 @@
         assertEquals(1, count);
     }
 
+    /**
+     * Check that the straightforward ways to try to construct/obtain a Locale
+     * with null country don't work.
+     */
+    public void test_nullCountry_fails() {
+        try {
+            new Locale(/* language */ "en", /* country */ null);
+        } catch (NullPointerException expected) {
+        }
+        try {
+            new Locale(/* language */ "en", /* country */ null, /* variant */ "EN");
+        } catch (NullPointerException expected) {
+        }
+        assertNotNull(Locale.getDefault().getCountry());
+        for (Locale locale : Locale.getAvailableLocales()) {
+            assertNotNull(locale.getCountry());
+        }
+    }
+
     public void test_getISO3Country() {
         // Empty country code.
         assertEquals("", new Locale("en", "").getISO3Country());
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index bf4c8e0..058309f 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -20,17 +20,11 @@
 
 import java.text.SimpleDateFormat;
 import java.time.ZoneId;
-import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.Date;
-import java.util.List;
 import java.util.Locale;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.atomic.AtomicInteger;
 
 public class TimeZoneTest extends TestCase {
     // http://code.google.com/p/android/issues/detail?id=877
@@ -65,6 +59,14 @@
 
     // http://code.google.com/p/android/issues/detail?id=14395
     public void testPreHistoricInDaylightTime() throws Exception {
+        // Originally this test was intended to assert what happens when the first transition for a
+        // time zone was a "to DST" transition. i.e. that the (implicit) offset / DST state before
+        // the first was treated as a non-DST state. Since zic version 2014c all zones have an
+        // explicit non-DST transition at time -2^31 seconds so it is no longer possible to test.
+        // This regression test has been kept in case that changes again in future and to prove the
+        // behavior has remained consistent. The comment below in this test that assume the old
+        // transitions is now incorrect.
+
         Locale.setDefault(Locale.US);
         TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
         TimeZone.setDefault(tz);
@@ -88,33 +90,38 @@
     }
 
     public void testPreHistoricOffsets() throws Exception {
-        // "Africa/Bissau" has just a few transitions and hasn't changed in a long time.
-        // 1912-01-01 00:02:19-0100 ... 1912-01-01 00:02:20-0100
-        // 1974-12-31 23:59:59-0100 ... 1975-01-01 01:00:00+0000
+        // "Africa/Bissau" has just a few transitions and hasn't changed in a long time:
+        // Transition time         : Offset    : DST / non-DST : Comment
+        // 1901-12-13 20:45:52 GMT : -01:02:20 : non-DST       : This entry included by zic > 2014b
+        // 1912-01-01 01:00:00 GMT : -01:00:00 : non-DST       :
+        // 1975-01-01 01:00:00 GMT :  00:00:00 : non-DST       :
         TimeZone tz = TimeZone.getTimeZone("Africa/Bissau");
 
         // Times before our first transition should assume we're still following that transition.
-        assertNonDaylightOffset(-3600, parseIsoTime("1911-01-01T00:00:00.0+0000"), tz);
+        assertNonDaylightOffset(-3740, parseIsoTime("1901-12-13T00:00:00.0+0000"), tz);
 
-        assertNonDaylightOffset(-3600, parseIsoTime("1912-01-01T12:00:00.0-0100"), tz);
+        // Times just after our first transition work as you would expect.
+        assertNonDaylightOffset(-3740, parseIsoTime("1902-12-13T20:45:53.0+0000"), tz);
 
         // Times after our last transition should assume we're still following that transition.
         assertNonDaylightOffset(0, parseIsoTime("1980-01-01T00:00:00.0+0000"), tz);
     }
 
-    private static void assertNonDaylightOffset(int expectedOffsetSeconds, long epochSeconds, TimeZone tz) {
-        assertEquals(expectedOffsetSeconds, tz.getOffset(epochSeconds * 1000) / 1000);
-        assertFalse(tz.inDaylightTime(new Date(epochSeconds * 1000)));
+    private static void assertNonDaylightOffset(
+            int expectedOffsetSeconds, long epochMillis, TimeZone tz) {
+        assertEquals(expectedOffsetSeconds, tz.getOffset(epochMillis) / 1000);
+        assertFalse(tz.inDaylightTime(new Date(epochMillis)));
     }
 
     private static long parseIsoTime(String isoTime) throws Exception {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
         Date date = sdf.parse(isoTime);
-        return date.getTime() / 1000;
+        return date.getTime();
     }
 
-    public void testZeroTransitionZones() throws Exception {
-        // Zones with no transitions historical or future seem ideal for testing.
+    public void testMinimalTransitionZones() throws Exception {
+        // Zones with minimal transitions, historical or future, seem ideal for testing.
+        // UTC is also included, although it may be implemented differently from the others.
         String[] ids = new String[] { "Africa/Bujumbura", "Indian/Cocos", "Pacific/Wake", "UTC" };
         for (String id : ids) {
             TimeZone tz = TimeZone.getTimeZone(id);
@@ -288,31 +295,6 @@
         assertEquals("", failures.toString());
     }
 
-    // http://b/30527513
-    public void testDisplayNamesWithScript() throws Exception {
-        Locale latinLocale = Locale.forLanguageTag("sr-Latn-RS");
-        Locale cyrillicLocale = Locale.forLanguageTag("sr-Cyrl-RS");
-        Locale noScriptLocale = Locale.forLanguageTag("sr-RS");
-        TimeZone tz = TimeZone.getTimeZone("Europe/London");
-
-        final String latinName = "Srednje vreme po Griniču";
-        final String cyrillicName = "Средње време по Гриничу";
-
-        // Check java.util.TimeZone
-        assertEquals(latinName, tz.getDisplayName(latinLocale));
-        assertEquals(cyrillicName, tz.getDisplayName(cyrillicLocale));
-        assertEquals(cyrillicName, tz.getDisplayName(noScriptLocale));
-
-        // Check ICU TimeZoneNames
-        // The one-argument getDisplayName() override uses LONG_GENERIC style which is different
-        // from what java.util.TimeZone uses. Force the LONG style to get equivalent results.
-        final int style = android.icu.util.TimeZone.LONG;
-        android.icu.util.TimeZone utz = android.icu.util.TimeZone.getTimeZone(tz.getID());
-        assertEquals(latinName, utz.getDisplayName(false, style, latinLocale));
-        assertEquals(cyrillicName, utz.getDisplayName(false, style, cyrillicLocale));
-        assertEquals(cyrillicName, utz.getDisplayName(false, style, noScriptLocale));
-    }
-
     // http://b/7955614
     public void testApia() throws Exception {
         TimeZone tz = TimeZone.getTimeZone("Pacific/Apia");
@@ -342,16 +324,19 @@
 
     // http://b/18839557
     public void testOverflowing32BitUnixDates() {
+        // This timezone didn't have any daylight savings prior to 1917.
         final TimeZone tz = TimeZone.getTimeZone("America/New_York");
 
-        // This timezone didn't have any daylight savings prior to 1917 and this
-        // date is sometime in 1901.
-        assertFalse(tz.inDaylightTime(new Date(-2206292400000L)));
-        assertEquals(-18000000, tz.getOffset(-2206292400000L));
+        // This value is outside of the 32-bit range.
+        long upperTime = 2206292400000L; // Wed, 30 Nov 2039 19:00:00 GMT
+        long lowerTime = -upperTime; // Thu, 01 Feb 1900 05:00:00 GMT
 
-        // Nov 30th 2039, no daylight savings as per current rules.
-        assertFalse(tz.inDaylightTime(new Date(2206292400000L)));
-        assertEquals(-18000000, tz.getOffset(2206292400000L));
+        assertFalse(tz.inDaylightTime(new Date(lowerTime)));
+        assertEquals(-18000000, tz.getOffset(lowerTime));
+
+        // No daylight savings according to the rules at the time of writing.
+        assertFalse(tz.inDaylightTime(new Date(upperTime)));
+        assertEquals(-18000000, tz.getOffset(upperTime));
     }
 
     public void testTimeZoneIDLocalization() {
@@ -368,22 +353,6 @@
         }
     }
 
-    // http://b/28949992
-    public void testSetDefaultAppliesToIcuTimezone() {
-        TimeZone origTz = TimeZone.getDefault();
-        try {
-            android.icu.util.TimeZone origIcuTz = android.icu.util.TimeZone.getDefault();
-            assertEquals(origTz.getID(), origIcuTz.getID());
-
-            TimeZone tz = TimeZone.getTimeZone("GMT-05:00");
-            TimeZone.setDefault(tz);
-            android.icu.util.TimeZone icuTz = android.icu.util.TimeZone.getDefault();
-            assertEquals(tz.getID(), icuTz.getID());
-        } finally {
-            TimeZone.setDefault(origTz);
-        }
-    }
-
     // http://b/33197219
     public void testDisplayNameForNonCanonicalTimezones() {
         TimeZone canonical = TimeZone.getTimeZone("Europe/London");
@@ -395,107 +364,4 @@
         assertEquals(canonical.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH),
                 nonCanonical.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH));
     }
-
-    // http://b/30937209
-    public void testSetDefaultDeadlock() throws InterruptedException, BrokenBarrierException {
-        // Since this tests a deadlock, the test has two fundamental problems:
-        // - it is probabilistic: it's not guaranteed to fail if the problem exists
-        // - if it fails, it will effectively hang the current runtime, as no other thread will
-        //   be able to call TimeZone.getDefault()/setDefault() successfully any more.
-
-        // 10 was too low to be reliable, 100 failed more than half the time (on a bullhead).
-        final int iterations = 100;
-        TimeZone otherTimeZone = TimeZone.getTimeZone("Europe/London");
-        AtomicInteger setterCount = new AtomicInteger();
-        CyclicBarrier startBarrier = new CyclicBarrier(2);
-        Thread setter = new Thread(() -> {
-            waitFor(startBarrier);
-            for (int i = 0; i < iterations; i++) {
-                TimeZone.setDefault(otherTimeZone);
-                TimeZone.setDefault(null);
-                setterCount.set(i+1);
-            }
-        });
-        setter.setName("testSetDefaultDeadlock setter");
-
-        AtomicInteger getterCount = new AtomicInteger();
-        Thread getter = new Thread(() -> {
-            waitFor(startBarrier);
-            for (int i = 0; i < iterations; i++) {
-                android.icu.util.TimeZone.getDefault();
-                getterCount.set(i+1);
-            }
-        });
-        getter.setName("testSetDefaultDeadlock getter");
-
-        setter.start();
-        getter.start();
-
-        // 2 seconds is plenty: If successful, we usually complete much faster.
-        setter.join(1000);
-        getter.join(1000);
-        if (setter.isAlive() || getter.isAlive()) {
-            fail("Threads are still alive. Getter iteration count: " + getterCount.get()
-                    + ", setter iteration count: " + setterCount.get());
-        }
-        // Guard against unexpected uncaught exceptions.
-        assertEquals("Setter iterations", iterations, setterCount.get());
-        assertEquals("Getter iterations", iterations, getterCount.get());
-    }
-
-    // http://b/30979219
-    public void testSetDefaultRace() throws InterruptedException {
-        // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
-        // fail if the problem exists
-
-        // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
-        final int iterations = 10000;
-        List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
-        Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
-
-        CyclicBarrier startBarrier = new CyclicBarrier(2);
-        Thread clearer = new Thread(() -> {
-            waitFor(startBarrier);
-            for (int i = 0; i < iterations; i++) {
-                // This is not public API but can effectively be invoked via
-                // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
-                // involved in this test.
-                android.icu.util.TimeZone.setICUDefault(null);
-            }
-        });
-        clearer.setName("testSetDefaultRace clearer");
-        clearer.setUncaughtExceptionHandler(handler);
-
-        Thread getter = new Thread(() -> {
-            waitFor(startBarrier);
-            for (int i = 0; i < iterations; i++) {
-                android.icu.util.TimeZone.getDefault();
-            }
-        });
-        getter.setName("testSetDefaultRace getter");
-        getter.setUncaughtExceptionHandler(handler);
-
-        clearer.start();
-        getter.start();
-
-        // 20 seconds is plenty: If successful, we usually complete much faster.
-        clearer.join(10000);
-        getter.join(10000);
-
-        if (!exceptions.isEmpty()) {
-            Throwable firstException = exceptions.get(0);
-            firstException.printStackTrace();
-            fail("Threads did not succeed successfully: " + firstException);
-        }
-        assertFalse("clearer thread is still alive", clearer.isAlive());
-        assertFalse("getter thread is still alive", getter.isAlive());
-    }
-
-    private static void waitFor(CyclicBarrier barrier) {
-        try {
-            barrier.await();
-        } catch (InterruptedException | BrokenBarrierException e) {
-            throw new RuntimeException(e);
-        }
-    }
 }
diff --git a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
index 399093a..dc617c3 100644
--- a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
+++ b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
@@ -177,6 +177,20 @@
         }
     }
 
+    public void test_startI_groupIndexOutOfBounds() {
+        Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+        assertTrue(matcher.find());
+        try {
+            matcher.start(-1 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            matcher.start(2 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
     public void test_endI() {
         String testPattern = "(((abb)a)(bb))";
         String testString = "cccabbabbabbabbabb";
@@ -199,6 +213,19 @@
         }
     }
 
+    public void test_endI_groupIndexOutOfBounds() {
+        Matcher matcher = Pattern.compile("(Hello)").matcher("Hello, world!");
+        assertTrue(matcher.find());
+        try {
+            matcher.end(-1 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            matcher.end(2 /* out of bounds */);
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
 
     public void test_lookingAt() {
         String testPattern = "(((abb)a)(bb))";
diff --git a/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
index 3d5440e..9157a0c 100644
--- a/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/AbstractZipFileTest.java
@@ -484,28 +484,16 @@
     }
 
     /**
-     * RI does not allow reading of an empty zip using a {@link ZipFile}.
+     * RI does allow reading of an empty zip using a {@link ZipFile}.
      */
-    public void testConstructorFailsWhenReadingEmptyZipArchive() throws IOException {
+    public void testConstructorWorksWhenReadingEmptyZipArchive() throws IOException {
 
         File resources = Support_Resources.createTempFolder();
         File emptyZip = Support_Resources.copyFile(
                 resources, "java/util/zip", "EmptyArchive.zip");
 
-        try {
-            // The following should fail with an exception but if it doesn't then we need to clean
-            // up the resource so we need a reference to it.
-            ZipFile zipFile = new ZipFile(emptyZip);
-
-            // Clean up the resource.
-            try {
-                zipFile.close();
-            } catch (Exception e) {
-                // Ignore
-            }
-            fail();
-        } catch (ZipException expected) {
-            // expected
+        try (ZipFile zipFile = new ZipFile(emptyZip)) {
+            assertEquals(0, zipFile.size());
         }
     }
 
@@ -633,4 +621,19 @@
         is.close();
         zipFile.close();
     }
+
+    public void testReadTruncatedZipFile() throws IOException {
+        final File f = createTemporaryZipFile();
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            // Byte representation of lower 4 bytes of ZipConstants.LOCSIG in little endian order.
+            byte[] bytes = new byte[] {0x50, 0x4b, 0x03, 0x04};
+            fos.write(bytes);
+        }
+
+        try (ZipFile zipFile = new ZipFile(f)) {
+            fail("Should not be possible to open the ZipFile as it is too short");
+        } catch (ZipException e) {
+            // expected
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
index d9f3fe4..19ee2b93 100644
--- a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
@@ -202,6 +202,16 @@
         }
     }
 
+    public void testNonGzipData() {
+        byte[] data = new byte[100];
+        try (InputStream is = new GZIPInputStream(new ByteArrayInputStream(data), data.length)) {
+            fail();
+        } catch (IOException expected) {
+            // Zeroes do not match the GZIPInputStream.GZIP_MAGIC number.
+            assertEquals("Not in GZIP format", expected.getMessage());
+        }
+    }
+
     /**
      * Test a openJdk8 fix for case where GZIPInputStream.readTrailer may accidently
      * close the input stream if trailing bytes looks "close" enough. Wrapping GZIP in
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
index fa85f9a..d3d6357 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
@@ -16,10 +16,12 @@
 
 package libcore.java.util.zip;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Arrays;
@@ -72,22 +74,20 @@
     }
 
     /**
-     * Reference implementation does NOT allow writing of an empty zip using a
-     * {@link ZipOutputStream}.
+     * Reference implementation does allow writing of an empty zip using a {@link ZipOutputStream}.
+     *
+     * See JDK-6440786.
      */
-    @DisableResourceLeakageDetection(
-            why = "InflaterOutputStream.close() does not work properly if finish() throws an"
-                    + " exception; finish() throws an exception if the output is invalid.",
-            bug = "31797037")
     public void testCreateEmpty() throws IOException {
         File result = File.createTempFile("ZipFileTest", "zip");
         ZipOutputStream out =
                 new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
-        try {
-            out.close();
-            fail("Close on empty stream failed to throw exception");
-        } catch (ZipException e) {
-            // expected
+        out.close();
+
+        // Verify that the empty zip file can be read back using ZipInputStream.
+        try (ZipInputStream in = new ZipInputStream(
+            new BufferedInputStream(new FileInputStream(result)))) {
+            assertNull(in.getNextEntry());
         }
     }
 
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
deleted file mode 100644
index aed6ce8..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import tests.security.AlgorithmParameterGeneratorTest;
-import tests.security.AlgorithmParameterKeyAgreementHelper;
-
-public class AlgorithmParameterGeneratorTestDH extends
-        AlgorithmParameterGeneratorTest {
-
-    public AlgorithmParameterGeneratorTestDH() {
-        super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
-    }
-
-    @Override
-    public void testAlgorithmParameterGenerator() throws Exception {
-        super.testAlgorithmParameterGenerator();
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java
deleted file mode 100644
index 834de6c..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDSA.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.spec.DSAParameterSpec;
-import tests.security.AlgorithmParameterGeneratorTest;
-import tests.security.AlgorithmParameterSignatureHelper;
-
-public class AlgorithmParameterGeneratorTestDSA extends
-        AlgorithmParameterGeneratorTest {
-
-    public AlgorithmParameterGeneratorTestDSA() {
-        super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>("DSA", DSAParameterSpec.class));
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java
deleted file mode 100644
index ae87ca5..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestAES.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestAES extends AlgorithmParametersTest {
-
-    private static final byte[] parameterData = new byte[] {
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
-    // See README.ASN1 for how to understand and reproduce this data
-
-    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
-    private static final String ENCODED_DATA = "BBAECGjI/2Ry9QQIaMj/ZHL1";
-
-    public AlgorithmParametersTestAES() {
-        super("AES", new AlgorithmParameterSymmetricHelper("AES", "CBC/PKCS5PADDING", 128), new IvParameterSpec(parameterData));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("AES", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support AES, ignore
-                continue;
-            }
-
-            params.init(new IvParameterSpec(parameterData));
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("AES", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA));
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(parameterData,
-                            params.getParameterSpec(IvParameterSpec.class).getIV()));
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java
deleted file mode 100644
index e59ba3f..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDES.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDES extends AlgorithmParametersTest {
-
-    private static final byte[] parameterData = new byte[] {
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
-    // See README.ASN1 for how to understand and reproduce this data
-
-    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
-    private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
-
-    public AlgorithmParametersTestDES() {
-        super("DES", new AlgorithmParameterSymmetricHelper("DES", "CBC/PKCS5PADDING", 56), new IvParameterSpec(parameterData));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("DES", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support DES, ignore
-                continue;
-            }
-
-            params.init(new IvParameterSpec(parameterData));
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("DES", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA));
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(parameterData,
-                            params.getParameterSpec(IvParameterSpec.class).getIV()));
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java
deleted file mode 100644
index 9cb7c5d..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDESede.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.IvParameterSpec;
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDESede extends AlgorithmParametersTest {
-
-    private static final byte[] parameterData = new byte[] {
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
-
-    // See README.ASN1 for how to understand and reproduce this data
-
-    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
-    private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
-
-    public AlgorithmParametersTestDESede() {
-        super("DESede", new AlgorithmParameterSymmetricHelper("DESede", "CBC/PKCS5PADDING", 112), new IvParameterSpec(parameterData));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("DESede", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support DESede, ignore
-                continue;
-            }
-
-            params.init(new IvParameterSpec(parameterData));
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("DESede", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA));
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(parameterData,
-                            params.getParameterSpec(IvParameterSpec.class).getIV()));
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
deleted file mode 100644
index 6e62c03..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.math.BigInteger;
-import javax.crypto.spec.DHParameterSpec;
-import tests.security.AlgorithmParameterKeyAgreementHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDH extends AlgorithmParametersTest {
-
-    private static final byte[] P = new byte[] {
-            (byte) 0x00, (byte) 0xB8, (byte) 0xA4, (byte) 0x06, (byte) 0x10,
-            (byte) 0xA2, (byte) 0x8B, (byte) 0xD2, (byte) 0xC0, (byte) 0xB6,
-            (byte) 0x87, (byte) 0xFF, (byte) 0x15, (byte) 0xBA, (byte) 0x18,
-            (byte) 0xE9, (byte) 0x7D, (byte) 0x77, (byte) 0x9F, (byte) 0xAF,
-            (byte) 0x6F, (byte) 0x0B, (byte) 0xA4, (byte) 0xB6, (byte) 0x2B,
-            (byte) 0x35, (byte) 0xE2, (byte) 0x01, (byte) 0x66, (byte) 0x41,
-            (byte) 0x05, (byte) 0xE7, (byte) 0x6A, (byte) 0x62, (byte) 0x19,
-            (byte) 0x94, (byte) 0x18, (byte) 0x46, (byte) 0xBA, (byte) 0x60,
-            (byte) 0x2E, (byte) 0x5A, (byte) 0x48, (byte) 0x6C, (byte) 0x4B,
-            (byte) 0xBF, (byte) 0x8C, (byte) 0xBF, (byte) 0xB9, (byte) 0xEE,
-            (byte) 0xCC, (byte) 0x35, (byte) 0x89, (byte) 0x18, (byte) 0x02,
-            (byte) 0x18, (byte) 0xFE, (byte) 0xF4, (byte) 0x02, (byte) 0x3B,
-            (byte) 0x5E, (byte) 0x8A, (byte) 0x42, (byte) 0xB3, (byte) 0x39};
-
-    private static final byte[] Q = new byte[] {
-            (byte) 0x00, (byte) 0x87, (byte) 0xE2, (byte) 0xD1, (byte) 0x8A,
-            (byte) 0x23, (byte) 0x90, (byte) 0x3A, (byte) 0x0F, (byte) 0xC8,
-            (byte) 0x38, (byte) 0xA8, (byte) 0x65, (byte) 0x35, (byte) 0x89,
-            (byte) 0x4F, (byte) 0x4B, (byte) 0xB3, (byte) 0xBF, (byte) 0x18,
-            (byte) 0x3C, (byte) 0x3B, (byte) 0xD8, (byte) 0x72, (byte) 0xC3,
-            (byte) 0xCF, (byte) 0xC9, (byte) 0xA7, (byte) 0x39, (byte) 0x7E,
-            (byte) 0x9C, (byte) 0x69, (byte) 0xDA, (byte) 0xDE, (byte) 0x8E,
-            (byte) 0x96, (byte) 0x9D, (byte) 0x44, (byte) 0xC1, (byte) 0x1E,
-            (byte) 0x58, (byte) 0xC7, (byte) 0xFC, (byte) 0x40, (byte) 0x1B,
-            (byte) 0xE8, (byte) 0x23, (byte) 0xF3, (byte) 0x6B, (byte) 0x95,
-            (byte) 0x68, (byte) 0x29, (byte) 0x93, (byte) 0x35, (byte) 0x05,
-            (byte) 0xC5, (byte) 0xCB, (byte) 0xB8, (byte) 0x57, (byte) 0x8F,
-            (byte) 0xB9, (byte) 0xC3, (byte) 0x36, (byte) 0x09, (byte) 0x51};
-
-    private static final int l = 511;
-
-    public AlgorithmParametersTestDH() {
-        super("DH", new AlgorithmParameterKeyAgreementHelper("DH"),
-                new DHParameterSpec(new BigInteger(P), new BigInteger(Q), l));
-
-    }
-
-    // Broken Test: Suffers from DH slowness, disabling for now
-    @Override
-    public void testAlgorithmParameters() throws Exception {
-        super.testAlgorithmParameters();
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java
deleted file mode 100644
index b524161..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDSA.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.math.BigInteger;
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.spec.DSAParameterSpec;
-import java.util.Base64;
-
-import tests.security.AlgorithmParameterSignatureHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestDSA extends AlgorithmParametersTest {
-
-    /*
-     * Parameters generated with OpenSSL:
-     * openssl dsaparam -genkey 1024 -C
-     */
-    private static final byte[] P = new byte[] {
-            (byte) 0xE6, (byte) 0x41, (byte) 0x58, (byte) 0x77, (byte) 0x76,
-            (byte) 0x5A, (byte) 0x4A, (byte) 0x53, (byte) 0xF1, (byte) 0xD6,
-            (byte) 0xC8, (byte) 0x7D, (byte) 0x67, (byte) 0x1F, (byte) 0x2F,
-            (byte) 0xFA, (byte) 0xDE, (byte) 0xB7, (byte) 0xAA, (byte) 0xCD,
-            (byte) 0xD7, (byte) 0x5D, (byte) 0xD0, (byte) 0xE9, (byte) 0xB1,
-            (byte) 0xDA, (byte) 0xFE, (byte) 0x42, (byte) 0xBE, (byte) 0xCC,
-            (byte) 0x42, (byte) 0x52, (byte) 0x2E, (byte) 0x01, (byte) 0xD2,
-            (byte) 0x16, (byte) 0xB1, (byte) 0x5B, (byte) 0xC4, (byte) 0x42,
-            (byte) 0xF9, (byte) 0x55, (byte) 0x0F, (byte) 0xE2, (byte) 0xD5,
-            (byte) 0x01, (byte) 0xD2, (byte) 0x7E, (byte) 0x22, (byte) 0xF6,
-            (byte) 0xC1, (byte) 0xFE, (byte) 0x5C, (byte) 0x6A, (byte) 0xCF,
-            (byte) 0x82, (byte) 0x1B, (byte) 0x5C, (byte) 0x46, (byte) 0x66,
-            (byte) 0x8B, (byte) 0xAF, (byte) 0xDF, (byte) 0x44, (byte) 0xE2,
-            (byte) 0x0E, (byte) 0xA3, (byte) 0x58, (byte) 0xF7, (byte) 0xA3,
-            (byte) 0x24, (byte) 0xE3, (byte) 0x84, (byte) 0xA6, (byte) 0x16,
-            (byte) 0xE0, (byte) 0xCA, (byte) 0x72, (byte) 0x55, (byte) 0x07,
-            (byte) 0xA0, (byte) 0x99, (byte) 0x7B, (byte) 0xF8, (byte) 0xB1,
-            (byte) 0x5A, (byte) 0x84, (byte) 0x36, (byte) 0x5A, (byte) 0xC8,
-            (byte) 0x6A, (byte) 0xFE, (byte) 0xA6, (byte) 0xB4, (byte) 0x1B,
-            (byte) 0x3A, (byte) 0x0A, (byte) 0x00, (byte) 0x6B, (byte) 0x72,
-            (byte) 0xDC, (byte) 0x0C, (byte) 0xD1, (byte) 0x09, (byte) 0x25,
-            (byte) 0x11, (byte) 0x68, (byte) 0x6B, (byte) 0x75, (byte) 0xDE,
-            (byte) 0x2C, (byte) 0x1A, (byte) 0xC2, (byte) 0x3A, (byte) 0xCB,
-            (byte) 0xA0, (byte) 0x17, (byte) 0xCA, (byte) 0x2D, (byte) 0xEE,
-            (byte) 0xA2, (byte) 0x5A, (byte) 0x9D, (byte) 0x1F, (byte) 0x33,
-            (byte) 0x1B, (byte) 0x07, (byte) 0x6D,
-    };
-    private static final byte[] Q = new byte[] {
-            (byte) 0x9B, (byte) 0x39, (byte) 0xD0, (byte) 0x02, (byte) 0x0F,
-            (byte) 0xE9, (byte) 0x96, (byte) 0x16, (byte) 0xC5, (byte) 0x25,
-            (byte) 0xF7, (byte) 0x94, (byte) 0xA9, (byte) 0x2C, (byte) 0xD0,
-            (byte) 0x25, (byte) 0x5B, (byte) 0x6E, (byte) 0xE0, (byte) 0x8F,
-    };
-    private static final byte[] G = new byte[] {
-            (byte) 0x5E, (byte) 0x9C, (byte) 0x95, (byte) 0x5F, (byte) 0x7E,
-            (byte) 0x91, (byte) 0x47, (byte) 0x4D, (byte) 0x68, (byte) 0xA4,
-            (byte) 0x1C, (byte) 0x44, (byte) 0x3B, (byte) 0xEC, (byte) 0x0A,
-            (byte) 0x7E, (byte) 0x59, (byte) 0x54, (byte) 0xF7, (byte) 0xEF,
-            (byte) 0x42, (byte) 0xFB, (byte) 0x63, (byte) 0x95, (byte) 0x08,
-            (byte) 0x2F, (byte) 0x4A, (byte) 0xD3, (byte) 0xBC, (byte) 0x79,
-            (byte) 0x9D, (byte) 0xBA, (byte) 0xD8, (byte) 0x8A, (byte) 0x83,
-            (byte) 0x84, (byte) 0xAE, (byte) 0x5B, (byte) 0x26, (byte) 0x80,
-            (byte) 0xB3, (byte) 0xFB, (byte) 0x9C, (byte) 0xA3, (byte) 0xCF,
-            (byte) 0xF4, (byte) 0x0A, (byte) 0xD5, (byte) 0xB6, (byte) 0x65,
-            (byte) 0x65, (byte) 0x1A, (byte) 0x4F, (byte) 0xC0, (byte) 0x86,
-            (byte) 0x3B, (byte) 0xE6, (byte) 0xFB, (byte) 0x4E, (byte) 0x9E,
-            (byte) 0x49, (byte) 0x0A, (byte) 0x8C, (byte) 0x77, (byte) 0x2D,
-            (byte) 0x93, (byte) 0x0B, (byte) 0xCA, (byte) 0x81, (byte) 0x07,
-            (byte) 0x09, (byte) 0xC4, (byte) 0x71, (byte) 0xFD, (byte) 0xC8,
-            (byte) 0xC7, (byte) 0xD1, (byte) 0xA3, (byte) 0xD0, (byte) 0xBB,
-            (byte) 0x7D, (byte) 0x92, (byte) 0x74, (byte) 0x8B, (byte) 0x3B,
-            (byte) 0x2A, (byte) 0x45, (byte) 0x1F, (byte) 0x5D, (byte) 0x85,
-            (byte) 0x90, (byte) 0xE3, (byte) 0xFB, (byte) 0x0E, (byte) 0x16,
-            (byte) 0xBA, (byte) 0x8A, (byte) 0xDE, (byte) 0x10, (byte) 0x0F,
-            (byte) 0xE0, (byte) 0x0F, (byte) 0x37, (byte) 0xA7, (byte) 0xC1,
-            (byte) 0xDC, (byte) 0xBC, (byte) 0x00, (byte) 0xB8, (byte) 0x24,
-            (byte) 0x0F, (byte) 0xF6, (byte) 0x5F, (byte) 0xB1, (byte) 0xA8,
-            (byte) 0x9A, (byte) 0xDB, (byte) 0x9F, (byte) 0x36, (byte) 0x54,
-            (byte) 0x45, (byte) 0xBD, (byte) 0xC0, (byte) 0xE8, (byte) 0x27,
-            (byte) 0x82, (byte) 0xC9, (byte) 0x75,
-    };
-
-    // The ASN.1 module for DSA is defined in RFC 3279 section 3. See README.ASN1 for how
-    // to understand and reproduce this data.
-
-    // asn1=SEQUENCE:dsa
-    // [dsa]
-    // p=INT:0xE6415877765A4A53F1D6C87D671F2FFADEB7AACDD75DD0E9B1DAFE42BECC42522E01D216B15BC442F9550FE2D501D27E22F6C1FE5C6ACF821B5C46668BAFDF44E20EA358F7A324E384A616E0CA725507A0997BF8B15A84365AC86AFEA6B41B3A0A006B72DC0CD1092511686B75DE2C1AC23ACBA017CA2DEEA25A9D1F331B076D
-    // q=INT:0x9B39D0020FE99616C525F794A92CD0255B6EE08F
-    // g=INT:0x5E9C955F7E91474D68A41C443BEC0A7E5954F7EF42FB6395082F4AD3BC799DBAD88A8384AE5B2680B3FB9CA3CFF40AD5B665651A4FC0863BE6FB4E9E490A8C772D930BCA810709C471FDC8C7D1A3D0BB7D92748B3B2A451F5D8590E3FB0E16BA8ADE100FE00F37A7C1DCBC00B8240FF65FB1A89ADB9F365445BDC0E82782C975
-    private static final String ENCODED_DATA = "MIIBHgKBgQDmQVh3dlpKU/HWyH1nHy/63reqzddd0Omx2v5"
-            + "CvsxCUi4B0haxW8RC+VUP4tUB0n4i9sH+XGrPghtcRmaLr99E4g6jWPejJOOEphbgynJVB6CZe/ixWoQ"
-            + "2Wshq/qa0GzoKAGty3AzRCSURaGt13iwawjrLoBfKLe6iWp0fMxsHbQIVAJs50AIP6ZYWxSX3lKks0CV"
-            + "bbuCPAoGAXpyVX36RR01opBxEO+wKfllU9+9C+2OVCC9K07x5nbrYioOErlsmgLP7nKPP9ArVtmVlGk/"
-            + "Ahjvm+06eSQqMdy2TC8qBBwnEcf3Ix9Gj0Lt9knSLOypFH12FkOP7Dha6it4QD+APN6fB3LwAuCQP9l+"
-            + "xqJrbnzZURb3A6CeCyXU=";
-
-    public AlgorithmParametersTestDSA() {
-        super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>(
-                "DSA", DSAParameterSpec.class), new DSAParameterSpec(
-                new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G)));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("DSA", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support DSA, ignore
-                continue;
-            }
-
-            DSAParameterSpec spec = new DSAParameterSpec(
-                    new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G));
-
-            params.init(spec);
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA, Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("DSA", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA));
-            DSAParameterSpec derivedSpec = params.getParameterSpec(DSAParameterSpec.class);
-
-            assertEquals("Provider: " + p.getName(), new BigInteger(1, P), derivedSpec.getP());
-            assertEquals("Provider: " + p.getName(), new BigInteger(1, Q), derivedSpec.getQ());
-            assertEquals("Provider: " + p.getName(), new BigInteger(1, G), derivedSpec.getG());
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java
deleted file mode 100644
index cb99c9a..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestGCM.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.GCMParameterSpec;
-
-import tests.security.AlgorithmParameterSymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestGCM extends AlgorithmParametersTest {
-
-    private static final byte[] IV = new byte[] {
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
-        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
-        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8 };
-
-    private static final int TLEN = 96;
-
-    // The ASN.1 encoding for GCM params (specified in RFC 5084 section 3.2) specifies
-    // a default value of 12 for TLEN, so both values with and without TLEN should work.
-    // See README.ASN1 for how to understand and reproduce this data.
-
-    // asn1=SEQUENCE:gcm
-    // [gcm]
-    // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
-    private static final String ENCODED_DATA_NO_TLEN = "MA4EDAQIaMj/ZHL1BAhoyA==";
-
-    // asn1=SEQUENCE:gcm
-    // [gcm]
-    // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
-    // tlen=INT:12
-    private static final String ENCODED_DATA_TLEN = "MBEEDAQIaMj/ZHL1BAhoyAIBDA==";
-
-    public AlgorithmParametersTestGCM() {
-        super("GCM", new AlgorithmParameterSymmetricHelper("AES", "GCM/NOPADDING", 128), new GCMParameterSpec(TLEN, IV));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("GCM", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support AES/GCM, ignore
-                continue;
-            }
-
-            params.init(new GCMParameterSpec(TLEN, IV));
-            String encoded = Base64.getEncoder().encodeToString(params.getEncoded());
-            assertTrue("Provider: " + p.getName() + ", encoded: " + encoded,
-                    encoded.equals(ENCODED_DATA_TLEN) || encoded.equals(ENCODED_DATA_NO_TLEN));
-
-            params = AlgorithmParameters.getInstance("GCM", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_NO_TLEN));
-            GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
-            assertEquals("Provider: " + p.getName(), TLEN, spec.getTLen());
-            assertTrue("Provider: " + p.getName(), Arrays.equals(IV, spec.getIV()));
-
-            params = AlgorithmParameters.getInstance("GCM", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_TLEN));
-            spec = params.getParameterSpec(GCMParameterSpec.class);
-            assertEquals("Provider: " + p.getName(), TLEN, spec.getTLen());
-            assertTrue("Provider: " + p.getName(), Arrays.equals(IV, spec.getIV()));
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java
deleted file mode 100644
index 7123e42..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestOAEP.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.spec.MGF1ParameterSpec;
-import java.util.Arrays;
-import java.util.Base64;
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-import tests.security.AlgorithmParameterAsymmetricHelper;
-import tests.security.AlgorithmParametersTest;
-
-public class AlgorithmParametersTestOAEP extends AlgorithmParametersTest {
-
-    // The ASN.1 encoding for OAEP params (specified in RFC 4055 section 4.1) specifies
-    // default values for all parameters, so we need to consider encodings with those
-    // values both explicitly specified and unspecified.  When encoding values, it is required
-    // that default values are left empty, but implementations must be able to parse explicitly-
-    // specified defaults as well.
-    //
-    // See README.ASN1 for how to understand and reproduce this data.
-
-    // asn1=SEQUENCE
-    private static final String ENCODED_DATA_ALL_DEFAULTS = "MAA=";
-
-    // asn1=SEQUENCE:oaep
-    // [oaep]
-    // hashFunc=EXP:0,SEQUENCE:sha1
-    // maskGenFunc=EXP:1,SEQUENCE:mgf1
-    // pSourceFunc=EXP:2,SEQUENCE:pSpecified
-    // [mgf1]
-    // oid=OID:1.2.840.113549.1.1.8
-    // params=SEQUENCE:sha1
-    // [pSpecified]
-    // oid=OID:1.2.840.113549.1.1.9
-    // val=OCTETSTRING:
-    // [sha1]
-    // oid=OID:sha1
-    // params=NULL
-    private static final String ENCODED_DATA_EXPLICIT_DEFAULTS =
-            "MDigCzAJBgUrDgMCGgUAoRgwFgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiDzANBgkqhkiG9w0BAQkEAA==";
-
-    // Base64 version of ASN.1-encoded data with none of the default values.  Specifically:
-    // SHA-256 hashFunc, MGF1-SHA-384 maskGenFunc, and [1, 2, 3, 4] pSourceFunc
-
-    // asn1=SEQUENCE:oaep
-    // [oaep]
-    // hashFunc=EXP:0,SEQUENCE:sha256
-    // maskGenFunc=EXP:1,SEQUENCE:mgf1
-    // pSourceFunc=EXP:2,SEQUENCE:pSpecified
-    // [sha256]
-    // oid=OID:sha256
-    // params=NULL
-    // [mgf1]
-    // oid=OID:1.2.840.113549.1.1.8
-    // params=SEQUENCE:sha384
-    // [sha384]
-    // oid=OID:sha384
-    // params=NULL
-    // [pSpecified]
-    // oid=OID:1.2.840.113549.1.1.9
-    // val=FORMAT:HEX,OCTETSTRING:01020304
-    private static final String ENCODED_DATA_NON_DEFAULTS = "MESgDzANBglghkgBZQMEAgEFAKEc"
-            + "MBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKITMBEGCSqGSIb3DQEBCQQEAQIDBA==";
-
-    // Base64 version of ASN.1-encoded data with some default and some non-default values.
-    // Specifically, SHA-1 hashFunc (default), MGF1-SHA-512 maskGenFunc (non-default),
-    // empty pSourceFunc (default)
-
-    // asn1=SEQUENCE:oaep
-    // [oaep]
-    // maskGenFunc=EXP:1,SEQUENCE:mgf1
-    // [mgf1]
-    // oid=OID:1.2.840.113549.1.1.8
-    // params=SEQUENCE:sha512
-    // [sha512]
-    // oid=OID:sha512
-    // params=NULL
-    private static final String ENCODED_DATA_MIXED = "MB6hHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQA=";
-
-    public AlgorithmParametersTestOAEP() {
-        super("OAEP", new AlgorithmParameterAsymmetricHelper("RSA"), new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
-    }
-
-    public void testEncoding() throws Exception {
-        for (Provider p : Security.getProviders()) {
-            AlgorithmParameters params;
-            try {
-                params = AlgorithmParameters.getInstance("OAEP", p);
-            } catch (NoSuchAlgorithmException e) {
-                // This provider doesn't support OAEP, ignore
-                continue;
-            }
-
-            OAEPParameterSpec spec = new OAEPParameterSpec(
-                    "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
-            params.init(spec);
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA_ALL_DEFAULTS,
-                    Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            spec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA384,
-                    new PSource.PSpecified(new byte[] {1, 2, 3, 4}));
-            params.init(spec);
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA_NON_DEFAULTS,
-                    Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            spec = new OAEPParameterSpec(
-                    "SHA-1", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT);
-            params.init(spec);
-            assertEquals("Provider: " + p.getName(),
-                    ENCODED_DATA_MIXED,
-                    Base64.getEncoder().encodeToString(params.getEncoded()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_ALL_DEFAULTS));
-            OAEPParameterSpec producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
-            assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
-            assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
-            assertEquals("Provider: " + p.getName(),
-                    MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
-                    ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
-                            ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_EXPLICIT_DEFAULTS));
-            producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
-            assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
-            assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
-            assertEquals("Provider: " + p.getName(),
-                    MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
-                    ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
-                            ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_NON_DEFAULTS));
-            producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
-            assertEquals("Provider: " + p.getName(), "SHA-256", producedSpec.getDigestAlgorithm());
-            assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
-            assertEquals("Provider: " + p.getName(),
-                    MGF1ParameterSpec.SHA384.getDigestAlgorithm(),
-                    ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(new byte[] {1, 2, 3, 4},
-                            ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-
-            params = AlgorithmParameters.getInstance("OAEP", p);
-            params.init(Base64.getDecoder().decode(ENCODED_DATA_MIXED));
-            producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
-
-            assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm());
-            assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm());
-            assertEquals("Provider: " + p.getName(),
-                    MGF1ParameterSpec.SHA512.getDigestAlgorithm(),
-                    ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm());
-            assertTrue("Provider: " + p.getName(),
-                    Arrays.equals(PSource.PSpecified.DEFAULT.getValue(),
-                            ((PSource.PSpecified) producedSpec.getPSource()).getValue()));
-        }
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java
deleted file mode 100644
index 02b4395..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDH.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.KeyPair;
-import javax.crypto.spec.DHPrivateKeySpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import tests.security.KeyAgreementHelper;
-import tests.security.KeyFactoryTest;
-
-public class KeyFactoryTestDH extends KeyFactoryTest<DHPublicKeySpec, DHPrivateKeySpec> {
-
-    public KeyFactoryTestDH() {
-        super("DH", DHPublicKeySpec.class, DHPrivateKeySpec.class);
-    }
-
-    @Override
-    protected void check(KeyPair keyPair) throws Exception {
-        new KeyAgreementHelper("DH").test(keyPair);
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java
deleted file mode 100644
index 236ad72..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestDSA.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.KeyPair;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import tests.security.KeyFactoryTest;
-import tests.security.SignatureHelper;
-
-public class KeyFactoryTestDSA extends
-        KeyFactoryTest<DSAPublicKeySpec, DSAPrivateKeySpec> {
-
-    public KeyFactoryTestDSA() {
-        super("DSA", DSAPublicKeySpec.class, DSAPrivateKeySpec.class);
-    }
-
-    @Override
-    protected void check(KeyPair keyPair) throws Exception {
-        new SignatureHelper("DSA").test(keyPair);
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
deleted file mode 100644
index 5e174bd..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyFactoryTestRSA.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import tests.security.CipherAsymmetricCryptHelper;
-import tests.security.DefaultKeys;
-import tests.security.KeyFactoryTest;
-
-public class KeyFactoryTestRSA extends
-        KeyFactoryTest<RSAPublicKeySpec, RSAPrivateKeySpec> {
-
-    @SuppressWarnings("unchecked")
-    public KeyFactoryTestRSA() {
-        super("RSA", RSAPublicKeySpec.class, RSAPrivateKeySpec.class);
-    }
-
-    @Override
-    protected void check(KeyPair keyPair) throws Exception {
-        new CipherAsymmetricCryptHelper("RSA").test(keyPair);
-    }
-
-    public void testExtraBufferSpace_Private() throws Exception {
-        PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
-        byte[] encoded = privateKey.getEncoded();
-        byte[] longBuffer = new byte[encoded.length + 147];
-        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
-        KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
-    }
-
-    public void testExtraBufferSpace_Public() throws Exception {
-        PublicKey publicKey = DefaultKeys.getPublicKey("RSA");
-        byte[] encoded = publicKey.getEncoded();
-        byte[] longBuffer = new byte[encoded.length + 147];
-        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
-        KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(longBuffer));
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
deleted file mode 100644
index 5a74d68..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import java.security.NoSuchAlgorithmException;
-import tests.security.KeyAgreementHelper;
-import tests.security.KeyPairGeneratorTest;
-
-public class KeyPairGeneratorTestDH extends KeyPairGeneratorTest {
-
-    public KeyPairGeneratorTestDH() {
-        super("DH", new KeyAgreementHelper("DH"));
-    }
-
-    // Broken Test: Takes ages due to DH computations. Disabling for now.
-    @Override
-    public void testKeyPairGenerator() throws Exception {
-        super.testKeyPairGenerator();
-    }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java
deleted file mode 100644
index 387ebad..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDSA.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import tests.security.KeyPairGeneratorTest;
-import tests.security.SignatureHelper;
-
-public class KeyPairGeneratorTestDSA extends KeyPairGeneratorTest {
-
-    public KeyPairGeneratorTestDSA() {
-        super("DSA", new SignatureHelper("DSA"));
-    }
-
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java
deleted file mode 100644
index 2e928ff..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestRSA.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.javax.crypto.spec;
-
-import tests.security.CipherAsymmetricCryptHelper;
-import tests.security.KeyPairGeneratorTest;
-
-public class KeyPairGeneratorTestRSA extends KeyPairGeneratorTest {
-
-    @SuppressWarnings("unchecked")
-    public KeyPairGeneratorTestRSA() {
-        super("RSA", new CipherAsymmetricCryptHelper("RSA"));
-    }
-
-}
-
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/README b/luni/src/test/java/libcore/javax/crypto/spec/README
new file mode 100644
index 0000000..99e97e1
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/spec/README
@@ -0,0 +1,2 @@
+Most tests for javax.crypto.spec can be found in external/conscrypt.
+They should be updated at http://github.com/google/conscrypt.
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1 b/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1
deleted file mode 100644
index 67ffae3..0000000
--- a/luni/src/test/java/libcore/javax/crypto/spec/README.ASN1
+++ /dev/null
@@ -1,14 +0,0 @@
-Many tests in this package check the ASN.1 encoding for various kinds of parameters.  The openssl
-command line tool can be used to view and encode data in ASN.1.
-
-Test data for encoding tests is preceded by its definition in the OpenSSL generation string
-format described at https://wiki.openssl.org/index.php/Manual:ASN1_generate_nconf(3).  To
-reproduce the base64-encoded values in the test files, do:
-
-# Put data definition in a file, eg input.cnf
-openssl asn1parse -genconf input.cnf -out /tmp/asn1.der
-openssl base64 -in /tmp/asn1.der
-
-To view the ASN.1 data encoded in a base64-encoded string, do:
-
-echo 'BASE64-ENCODED DATA HERE' | openssl asn1parse -i
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java b/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
new file mode 100644
index 0000000..e01de4d
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.libcore.icu;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.icu.impl.ICUData;
+import android.icu.impl.ICUResourceBundle;
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.ULocale;
+
+import org.junit.Test;
+
+/**
+ * Test for Android patches in ICU's calendar.
+ */
+public class ICUCalendarTest {
+
+    /**
+     * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
+     * historic behavior on Android; this test exists to avoid unintentional regressions.
+     * http://b/80294184
+     */
+    @Test
+    public void testAllDefaultCalendar_Gregorian() {
+        for (ULocale locale : ULocale.getAvailableLocales()) {
+            assertTrue("Default calendar should be Gregorian: " + locale,
+                    Calendar.getInstance(locale) instanceof GregorianCalendar);
+        }
+
+        for (ULocale locale : ULocale.getAvailableLocales()) {
+            // Classes, e.g. RelativeDateTimeFormatter, use a different property,
+            // i.e. calendar/default, for calendar type. However, there is no direct way to obtain
+            // the calendar type via the APIs. Verify the property value directly here.
+            ICUResourceBundle bundle = (ICUResourceBundle) ICUResourceBundle.getBundleInstance(
+                    ICUData.ICU_BASE_NAME, locale);
+            String calType = bundle.getStringWithFallback("calendar/default");
+            assertEquals("calendar/default should be Gregorian: " + locale, "gregorian", calType);
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
index 54bb74b..e67e9a1 100644
--- a/luni/src/test/java/libcore/libcore/icu/ICUTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
@@ -16,18 +16,11 @@
 
 package libcore.libcore.icu;
 
-import android.icu.util.TimeZone;
-
 import java.text.BreakIterator;
 import java.text.Collator;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Locale;
-import java.util.Set;
 import libcore.icu.ICU;
-import libcore.util.TimeZoneFinder;
-import libcore.util.ZoneInfoDB;
 
 public class ICUTest extends junit.framework.TestCase {
   public void test_getISOLanguages() throws Exception {
@@ -261,63 +254,4 @@
       ICU.setDefaultLocale(initialDefaultLocale);
     }
   }
-
-  /** Confirms that ICU agrees with the rest of libcore about the version of the TZ data in use. */
-  public void testTimeZoneDataVersion() {
-    String icu4cTzVersion = ICU.getTZDataVersion();
-
-    String zoneInfoTzVersion = ZoneInfoDB.getInstance().getVersion();
-    assertEquals(icu4cTzVersion, zoneInfoTzVersion);
-
-    String icu4jTzVersion = android.icu.util.TimeZone.getTZDataVersion();
-    assertEquals(icu4jTzVersion, zoneInfoTzVersion);
-
-    String tzLookupTzVersion = TimeZoneFinder.getInstance().getIanaVersion();
-    assertEquals(icu4jTzVersion, tzLookupTzVersion);
-  }
-
-  /**
-   * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
-   * ICU's IDs may be a superset.
-   */
-  public void testTimeZoneIdLookup() {
-    String[] zoneInfoDbAvailableIds = ZoneInfoDB.getInstance().getAvailableIDs();
-
-    // ICU has a known set of IDs. We want ANY because we don't want to filter to ICU's canonical
-    // IDs only.
-    Set<String> icuAvailableIds = android.icu.util.TimeZone.getAvailableIDs(
-            TimeZone.SystemTimeZoneType.ANY, null /* region */, null /* rawOffset */);
-
-    List<String> nonIcuAvailableIds = new ArrayList<>();
-    List<String> creationFailureIds = new ArrayList<>();
-    List<String> noCanonicalLookupIds = new ArrayList<>();
-    List<String> nonSystemIds = new ArrayList<>();
-    for (String zoneInfoDbId : zoneInfoDbAvailableIds) {
-      if (!icuAvailableIds.contains(zoneInfoDbId)) {
-        nonIcuAvailableIds.add(zoneInfoDbId);
-      }
-
-      boolean[] isSystemId = new boolean[1];
-      String canonicalId = android.icu.util.TimeZone.getCanonicalID(zoneInfoDbId, isSystemId);
-      if (canonicalId == null) {
-        noCanonicalLookupIds.add(zoneInfoDbId);
-      }
-      if (!isSystemId[0]) {
-        nonSystemIds.add(zoneInfoDbId);
-      }
-
-      android.icu.util.TimeZone icuTimeZone = android.icu.util.TimeZone.getTimeZone(zoneInfoDbId);
-      if (icuTimeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
-        creationFailureIds.add(zoneInfoDbId);
-      }
-    }
-    assertTrue("Non-ICU available IDs: " + nonIcuAvailableIds
-                    + ", creation failed IDs: " + creationFailureIds
-                    + ", non-system IDs: " + nonSystemIds
-                    + ", ids without canonical IDs: " + noCanonicalLookupIds,
-            nonIcuAvailableIds.isEmpty()
-                    && creationFailureIds.isEmpty()
-                    && nonSystemIds.isEmpty()
-                    && noCanonicalLookupIds.isEmpty());
-  }
 }
diff --git a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
new file mode 100644
index 0000000..db118ba
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.libcore.icu;
+
+import org.junit.Test;
+
+import android.icu.text.TimeZoneNames;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import libcore.icu.ICU;
+import libcore.util.TimeZoneFinder;
+import libcore.util.ZoneInfoDB;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests that compare ICU and libcore time zone behavior and similar cross-cutting concerns.
+ */
+public class TimeZoneIntegrationTest {
+
+    // http://b/28949992
+    @Test
+    public void testJavaSetDefaultAppliesToIcuTimezone() {
+        java.util.TimeZone origTz = java.util.TimeZone.getDefault();
+        try {
+            android.icu.util.TimeZone origIcuTz = android.icu.util.TimeZone.getDefault();
+            assertEquals(origTz.getID(), origIcuTz.getID());
+
+            java.util.TimeZone tz = java.util.TimeZone.getTimeZone("GMT-05:00");
+            java.util.TimeZone.setDefault(tz);
+            android.icu.util.TimeZone icuTz = android.icu.util.TimeZone.getDefault();
+            assertEquals(tz.getID(), icuTz.getID());
+        } finally {
+            java.util.TimeZone.setDefault(origTz);
+        }
+    }
+
+    // http://b/30937209
+    @Test
+    public void testSetDefaultDeadlock() throws InterruptedException, BrokenBarrierException {
+        // Since this tests a deadlock, the test has two fundamental problems:
+        // - it is probabilistic: it's not guaranteed to fail if the problem exists
+        // - if it fails, it will effectively hang the current runtime, as no other thread will
+        //   be able to call TimeZone.getDefault()/setDefault() successfully any more.
+
+        // 10 was too low to be reliable, 100 failed more than half the time (on a bullhead).
+        final int iterations = 100;
+        java.util.TimeZone otherTimeZone = java.util.TimeZone.getTimeZone("Europe/London");
+        AtomicInteger setterCount = new AtomicInteger();
+        CyclicBarrier startBarrier = new CyclicBarrier(2);
+        Thread setter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                java.util.TimeZone.setDefault(otherTimeZone);
+                java.util.TimeZone.setDefault(null);
+                setterCount.set(i+1);
+            }
+        });
+        setter.setName("testSetDefaultDeadlock setter");
+
+        AtomicInteger getterCount = new AtomicInteger();
+        Thread getter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                android.icu.util.TimeZone.getDefault();
+                getterCount.set(i+1);
+            }
+        });
+        getter.setName("testSetDefaultDeadlock getter");
+
+        setter.start();
+        getter.start();
+
+        // 2 seconds is plenty: If successful, we usually complete much faster.
+        setter.join(1000);
+        getter.join(1000);
+        if (setter.isAlive() || getter.isAlive()) {
+            fail("Threads are still alive. Getter iteration count: " + getterCount.get()
+                    + ", setter iteration count: " + setterCount.get());
+        }
+        // Guard against unexpected uncaught exceptions.
+        assertEquals("Setter iterations", iterations, setterCount.get());
+        assertEquals("Getter iterations", iterations, getterCount.get());
+    }
+
+    // http://b/30979219
+    @Test
+    public void testSetDefaultRace() throws InterruptedException {
+        // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
+        // fail if the problem exists
+
+        // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
+        final int iterations = 10000;
+        List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
+        Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
+
+        CyclicBarrier startBarrier = new CyclicBarrier(2);
+        Thread clearer = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                // This is not public API but can effectively be invoked via
+                // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
+                // involved in this test.
+                android.icu.util.TimeZone.setICUDefault(null);
+            }
+        });
+        clearer.setName("testSetDefaultRace clearer");
+        clearer.setUncaughtExceptionHandler(handler);
+
+        Thread getter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                android.icu.util.TimeZone.getDefault();
+            }
+        });
+        getter.setName("testSetDefaultRace getter");
+        getter.setUncaughtExceptionHandler(handler);
+
+        clearer.start();
+        getter.start();
+
+        // 20 seconds is plenty: If successful, we usually complete much faster.
+        clearer.join(10000);
+        getter.join(10000);
+
+        if (!exceptions.isEmpty()) {
+            Throwable firstException = exceptions.get(0);
+            firstException.printStackTrace();
+            fail("Threads did not succeed successfully: " + firstException);
+        }
+        assertFalse("clearer thread is still alive", clearer.isAlive());
+        assertFalse("getter thread is still alive", getter.isAlive());
+    }
+
+    private static void waitFor(CyclicBarrier barrier) {
+        try {
+            barrier.await();
+        } catch (InterruptedException | BrokenBarrierException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Confirms that ICU agrees with the rest of libcore about the version of the TZ data in use.
+     */
+    @Test
+    public void testTimeZoneDataVersion() {
+        String icu4cTzVersion = ICU.getTZDataVersion();
+
+        String zoneInfoTzVersion = ZoneInfoDB.getInstance().getVersion();
+        assertEquals(icu4cTzVersion, zoneInfoTzVersion);
+
+        String icu4jTzVersion = android.icu.util.TimeZone.getTZDataVersion();
+        assertEquals(icu4jTzVersion, zoneInfoTzVersion);
+
+        String tzLookupTzVersion = TimeZoneFinder.getInstance().getIanaVersion();
+        assertEquals(icu4jTzVersion, tzLookupTzVersion);
+    }
+
+    /**
+     * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
+     * ICU's IDs may be a superset.
+     */
+    @Test
+    public void testTimeZoneIdLookup() {
+        String[] zoneInfoDbAvailableIds = ZoneInfoDB.getInstance().getAvailableIDs();
+
+        // ICU has a known set of IDs. We want ANY because we don't want to filter to ICU's
+        // canonical IDs only.
+        Set<String> icuAvailableIds = android.icu.util.TimeZone.getAvailableIDs(
+                android.icu.util.TimeZone.SystemTimeZoneType.ANY, null /* region */,
+                null /* rawOffset */);
+
+        List<String> nonIcuAvailableIds = new ArrayList<>();
+        List<String> creationFailureIds = new ArrayList<>();
+        List<String> noCanonicalLookupIds = new ArrayList<>();
+        List<String> nonSystemIds = new ArrayList<>();
+        for (String zoneInfoDbId : zoneInfoDbAvailableIds) {
+            if (!icuAvailableIds.contains(zoneInfoDbId)) {
+                nonIcuAvailableIds.add(zoneInfoDbId);
+            }
+
+            boolean[] isSystemId = new boolean[1];
+            String canonicalId = android.icu.util.TimeZone.getCanonicalID(zoneInfoDbId, isSystemId);
+            if (canonicalId == null) {
+                noCanonicalLookupIds.add(zoneInfoDbId);
+            }
+            if (!isSystemId[0]) {
+                nonSystemIds.add(zoneInfoDbId);
+            }
+
+            android.icu.util.TimeZone icuTimeZone =
+                    android.icu.util.TimeZone.getTimeZone(zoneInfoDbId);
+            if (icuTimeZone.getID().equals(android.icu.util.TimeZone.UNKNOWN_ZONE_ID)) {
+                creationFailureIds.add(zoneInfoDbId);
+            }
+        }
+        assertTrue("Non-ICU available IDs: " + nonIcuAvailableIds
+                        + ", creation failed IDs: " + creationFailureIds
+                        + ", non-system IDs: " + nonSystemIds
+                        + ", ids without canonical IDs: " + noCanonicalLookupIds,
+                nonIcuAvailableIds.isEmpty()
+                        && creationFailureIds.isEmpty()
+                        && nonSystemIds.isEmpty()
+                        && noCanonicalLookupIds.isEmpty());
+    }
+
+    // http://b/30527513
+    @Test
+    public void testDisplayNamesWithScript() throws Exception {
+        Locale latinLocale = Locale.forLanguageTag("sr-Latn-RS");
+        Locale cyrillicLocale = Locale.forLanguageTag("sr-Cyrl-RS");
+        Locale noScriptLocale = Locale.forLanguageTag("sr-RS");
+        java.util.TimeZone tz = java.util.TimeZone.getTimeZone("Europe/London");
+
+        final String latinName = "Srednje vreme po Griniču";
+        final String cyrillicName = "Средње време по Гриничу";
+
+        // Check java.util.TimeZone
+        assertEquals(latinName, tz.getDisplayName(latinLocale));
+        assertEquals(cyrillicName, tz.getDisplayName(cyrillicLocale));
+        assertEquals(cyrillicName, tz.getDisplayName(noScriptLocale));
+
+        // Check ICU TimeZoneNames
+        // The one-argument getDisplayName() override uses LONG_GENERIC style which is different
+        // from what java.util.TimeZone uses. Force the LONG style to get equivalent results.
+        final int style = android.icu.util.TimeZone.LONG;
+        android.icu.util.TimeZone utz = android.icu.util.TimeZone.getTimeZone(tz.getID());
+        assertEquals(latinName, utz.getDisplayName(false, style, latinLocale));
+        assertEquals(cyrillicName, utz.getDisplayName(false, style, cyrillicLocale));
+        assertEquals(cyrillicName, utz.getDisplayName(false, style, noScriptLocale));
+    }
+
+    /**
+     * This test is to catch issues with the rules update process that could let the
+     * "negative DST" scheme enter the Android data set for either java.util.TimeZone or
+     * android.icu.util.TimeZone.
+     */
+    @Test
+    public void testDstMeansSummer() {
+        // Ireland was the original example that caused the default IANA upstream tzdata to contain
+        // a zone where DST is in the Winter (since tzdata 2018e, though it was tried in 2018a
+        // first). This change was made to historical and future transitions.
+        //
+        // The upstream reasoning went like this: "Irish *Standard* Time" is summer, so the other
+        // time must be the DST. So, DST is considered to be in the winter and the associated DST
+        // adjustment is negative from the standard time. In the old scheme "Irish Standard Time" /
+        // summer was just modeled as the DST in common with all other global time zones.
+        //
+        // Unfortunately, various users of formatting APIs assume standard and DST times are
+        // consistent and (effectively) that "DST" means "summer". We likely cannot adopt the
+        // concept of a winter DST without risking app compat issues.
+        //
+        // For example, getDisplayName(boolean daylight) has always returned the winter time for
+        // false, and the summer time for true. If we change this then it should be changed on a
+        // major release boundary, with improved APIs (e.g. a version of getDisplayName() that takes
+        // a millis), existing API behavior made dependent on target API version, and after fixing
+        // any platform code that makes incorrect assumptions about DST meaning "1 hour forward".
+
+        final String timeZoneId = "Europe/Dublin";
+        final Locale locale = Locale.UK;
+        // 26 Oct 2015 01:00:00 GMT - one day after the start of "Greenwich Mean Time" in
+        // Europe/Dublin in 2015. An arbitrary historical example of winter in Ireland.
+        final long winterTimeMillis = 1445821200000L;
+        final String winterTimeName = "Greenwich Mean Time";
+        final int winterOffsetRawMillis = 0;
+        final int winterOffsetDstMillis = 0;
+
+        // 30 Mar 2015 01:00:00 GMT - one day after the start of "Irish Standard Time" in
+        // Europe/Dublin in 2015. An arbitrary historical example of summer in Ireland.
+        final long summerTimeMillis = 1427677200000L;
+        final String summerTimeName = "Irish Standard Time";
+        final int summerOffsetRawMillis = 0;
+        final int summerOffsetDstMillis = (int) TimeUnit.HOURS.toMillis(1);
+
+        // There is no common interface between java.util.TimeZone and android.icu.util.TimeZone
+        // so the tests are for each are effectively duplicated.
+
+        // java.util.TimeZone
+        {
+            java.util.TimeZone timeZone = java.util.TimeZone.getTimeZone(timeZoneId);
+            assertTrue(timeZone.useDaylightTime());
+
+            assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
+            assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));
+
+            assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
+                    timeZone.getOffset(winterTimeMillis));
+            assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
+                    timeZone.getOffset(summerTimeMillis));
+            assertEquals(winterTimeName,
+                    timeZone.getDisplayName(false /* daylight */, java.util.TimeZone.LONG,
+                            locale));
+            assertEquals(summerTimeName,
+                    timeZone.getDisplayName(true /* daylight */, java.util.TimeZone.LONG,
+                            locale));
+        }
+
+        // android.icu.util.TimeZone
+        {
+            android.icu.util.TimeZone timeZone = android.icu.util.TimeZone.getTimeZone(timeZoneId);
+            assertTrue(timeZone.useDaylightTime());
+
+            assertFalse(timeZone.inDaylightTime(new Date(winterTimeMillis)));
+            assertTrue(timeZone.inDaylightTime(new Date(summerTimeMillis)));
+
+            assertEquals(winterOffsetRawMillis + winterOffsetDstMillis,
+                    timeZone.getOffset(winterTimeMillis));
+            assertEquals(summerOffsetRawMillis + summerOffsetDstMillis,
+                    timeZone.getOffset(summerTimeMillis));
+
+            // These methods show the trouble we'd have if callers were to take the output from
+            // inDaylightTime() and pass it to getDisplayName().
+            assertEquals(winterTimeName,
+                    timeZone.getDisplayName(false /* daylight */, android.icu.util.TimeZone.LONG,
+                            locale));
+            assertEquals(summerTimeName,
+                    timeZone.getDisplayName(true /* daylight */, android.icu.util.TimeZone.LONG,
+                            locale));
+
+            // APIs not identical to java.util.TimeZone tested below.
+            int[] offsets = new int[2];
+            timeZone.getOffset(winterTimeMillis, false /* local */, offsets);
+            assertEquals(winterOffsetRawMillis, offsets[0]);
+            assertEquals(winterOffsetDstMillis, offsets[1]);
+
+            timeZone.getOffset(summerTimeMillis, false /* local */, offsets);
+            assertEquals(summerOffsetRawMillis, offsets[0]);
+            assertEquals(summerOffsetDstMillis, offsets[1]);
+        }
+
+        // icu TimeZoneNames
+        TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
+        // getDisplayName: date = winterTimeMillis
+        assertEquals(winterTimeName, timeZoneNames.getDisplayName(
+                timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, winterTimeMillis));
+        assertEquals(summerTimeName, timeZoneNames.getDisplayName(
+                timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, winterTimeMillis));
+        // getDisplayName: date = summerTimeMillis
+        assertEquals(winterTimeName, timeZoneNames.getDisplayName(
+                timeZoneId, TimeZoneNames.NameType.LONG_STANDARD, summerTimeMillis));
+        assertEquals(summerTimeName, timeZoneNames.getDisplayName(
+                timeZoneId, TimeZoneNames.NameType.LONG_DAYLIGHT, summerTimeMillis));
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 7015521..aea709f 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -119,6 +119,10 @@
     @Test
     public void test_checkNewMethodsInPosix() {
         List<String> methodsNotRequireBlockGuardChecks = Arrays.asList(
+                "android_fdsan_exchange_owner_tag(java.io.FileDescriptor,long,long)",
+                "android_fdsan_get_owner_tag(java.io.FileDescriptor)",
+                "android_fdsan_get_tag_type(long)",
+                "android_fdsan_get_tag_value(long)",
                 "bind(java.io.FileDescriptor,java.net.InetAddress,int)",
                 "bind(java.io.FileDescriptor,java.net.SocketAddress)",
                 "capget(android.system.StructCapUserHeader)",
diff --git a/luni/src/test/java/libcore/libcore/io/FdsanTest.java b/luni/src/test/java/libcore/libcore/io/FdsanTest.java
new file mode 100644
index 0000000..354ed11
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/io/FdsanTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.libcore.io;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import junit.framework.TestCase;
+
+import libcore.io.Libcore;
+
+public class FdsanTest extends TestCase {
+    public void testFileInputStream() throws Exception {
+        try (FileInputStream fis = new FileInputStream("/dev/null")) {
+            FileDescriptor fd = fis.getFD();
+            long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+            assertTrue(tag != FileDescriptor.NO_OWNER);
+            assertEquals("FileInputStream", Libcore.os.android_fdsan_get_tag_type(tag));
+            assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+        }
+    }
+
+    public void testFileOutputStream() throws Exception {
+        try (FileOutputStream fis = new FileOutputStream("/dev/null")) {
+            FileDescriptor fd = fis.getFD();
+            long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+            assertTrue(tag != FileDescriptor.NO_OWNER);
+            assertEquals("FileOutputStream", Libcore.os.android_fdsan_get_tag_type(tag));
+            assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+        }
+    }
+
+    public void testRandomAccessFile() throws Exception {
+        try (RandomAccessFile fis = new RandomAccessFile("/dev/null", "r")) {
+            FileDescriptor fd = fis.getFD();
+            long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+            assertTrue(tag != FileDescriptor.NO_OWNER);
+            assertEquals("RandomAccessFile", Libcore.os.android_fdsan_get_tag_type(tag));
+            assertEquals(System.identityHashCode(fis), Libcore.os.android_fdsan_get_tag_value(tag));
+        }
+    }
+
+    public void testParcelFileDescriptor() throws Exception {
+        Class pfdClass;
+        try {
+            pfdClass = Class.forName("android.os.ParcelFileDescriptor");
+        } catch (ClassNotFoundException ex) {
+            // Don't fail if ParcelFileDescriptor isn't on our classpath, e.g. in ART host tests.
+            return;
+        }
+
+        try (FileInputStream fis = new FileInputStream("/dev/null")) {
+            Method pfdMethodDup = pfdClass.getMethod("dup", FileDescriptor.class);
+            Method pfdMethodClose = pfdClass.getMethod("close");
+            Method pfdMethodGetFileDescriptor = pfdClass.getMethod("getFileDescriptor");
+            Field readonly = pfdClass.getField("MODE_READ_ONLY");
+
+            Object pfd = pfdMethodDup.invoke(null, fis.getFD());
+            FileDescriptor fd = (FileDescriptor)pfdMethodGetFileDescriptor.invoke(pfd);
+            long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+            assertTrue(tag != FileDescriptor.NO_OWNER);
+            assertEquals("ParcelFileDescriptor", Libcore.os.android_fdsan_get_tag_type(tag));
+            assertEquals(System.identityHashCode(pfd), Libcore.os.android_fdsan_get_tag_value(tag));
+            pfdMethodClose.invoke(pfd);
+        }
+    }
+
+    public void testDatagramSocket() throws Exception {
+        try (DatagramSocket socket = new DatagramSocket()) {
+            FileDescriptor fd = socket.getFileDescriptor$();
+            assertTrue(fd.valid());
+
+            long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+            assertTrue(tag != FileDescriptor.NO_OWNER);
+            assertEquals("DatagramSocketImpl", Libcore.os.android_fdsan_get_tag_type(tag));
+            assertTrue(Libcore.os.android_fdsan_get_tag_value(tag) != 0);
+            socket.close();
+        }
+    }
+
+    public void assertFdOwnedBySocket(FileDescriptor fd) throws Exception {
+        long tag = Libcore.os.android_fdsan_get_owner_tag(fd);
+        assertTrue(tag != FileDescriptor.NO_OWNER);
+        assertEquals("SocketImpl", Libcore.os.android_fdsan_get_tag_type(tag));
+        assertTrue(Libcore.os.android_fdsan_get_tag_value(tag) != 0);
+    }
+
+    public void testSocket() throws Exception {
+        try (Socket socket = new Socket()) {
+            assertFalse("new Socket shouldn't have an associated FileDescriptor",
+                        socket.getFileDescriptor$().valid());
+        }
+
+        int port = 0; // auto-allocate port
+        try (ServerSocket serverSocket = new ServerSocket(port, /* backlog */ 1)) {
+            assertFdOwnedBySocket(serverSocket.getFileDescriptor$());
+
+            Socket client = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
+            Socket server = serverSocket.accept();
+            assertFdOwnedBySocket(client.getFileDescriptor$());
+            assertFdOwnedBySocket(server.getFileDescriptor$());
+            client.close();
+            server.close();
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/io/OsTest.java b/luni/src/test/java/libcore/libcore/io/OsTest.java
index 5e8a691..aa0a5ba 100644
--- a/luni/src/test/java/libcore/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/OsTest.java
@@ -1014,4 +1014,36 @@
     Libcore.os.close(pipe[0]);
     Libcore.os.close(pipe[1]);
   }
+
+  public void testCloseNullFileDescriptor() throws Exception {
+    try {
+      Libcore.rawOs.close(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  public void testSocketpairNullFileDescriptor1() throws Exception {
+    try {
+      Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, null, new FileDescriptor());
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  public void testSocketpairNullFileDescriptor2() throws Exception {
+    try {
+      Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, new FileDescriptor(), null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  public void testSocketpairNullFileDescriptorBoth() throws Exception {
+    try {
+      Libcore.rawOs.socketpair(AF_UNIX, SOCK_STREAM, 0, null, null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
 }
diff --git a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
index f9ff9df..69344e2 100644
--- a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
@@ -16,78 +16,133 @@
 
 package libcore.libcore.net;
 
-import junit.framework.TestCase;
-
 import libcore.net.MimeUtils;
 
+import junit.framework.TestCase;
+
+import java.util.Objects;
+
 public class MimeUtilsTest extends TestCase {
-  public void test_15715370() {
-    assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
-    assertEquals("flac", MimeUtils.guessExtensionFromMimeType("audio/flac"));
-    assertEquals("flac", MimeUtils.guessExtensionFromMimeType("application/x-flac"));
-  }
+    public void test_15715370() {
+        assertEquals("audio/flac", MimeUtils.guessMimeTypeFromExtension("flac"));
+        assertEquals("flac", MimeUtils.guessExtensionFromMimeType("audio/flac"));
+        assertEquals("flac", MimeUtils.guessExtensionFromMimeType("application/x-flac"));
+    }
 
-  // https://code.google.com/p/android/issues/detail?id=78909
-  public void test_78909() {
-    assertEquals("mka", MimeUtils.guessExtensionFromMimeType("audio/x-matroska"));
-    assertEquals("mkv", MimeUtils.guessExtensionFromMimeType("video/x-matroska"));
-  }
+    // https://code.google.com/p/android/issues/detail?id=78909
+    public void test_78909() {
+        assertEquals("mka", MimeUtils.guessExtensionFromMimeType("audio/x-matroska"));
+        assertEquals("mkv", MimeUtils.guessExtensionFromMimeType("video/x-matroska"));
+    }
 
-  public void test_16978217() {
-    assertEquals("image/x-ms-bmp", MimeUtils.guessMimeTypeFromExtension("bmp"));
-    assertEquals("image/x-icon", MimeUtils.guessMimeTypeFromExtension("ico"));
-    assertEquals("video/mp2ts", MimeUtils.guessMimeTypeFromExtension("ts"));
-  }
+    public void test_16978217() {
+        assertEquals("image/x-ms-bmp", MimeUtils.guessMimeTypeFromExtension("bmp"));
+        assertEquals("image/x-icon", MimeUtils.guessMimeTypeFromExtension("ico"));
+        assertEquals("video/mp2ts", MimeUtils.guessMimeTypeFromExtension("ts"));
+    }
 
-  public void testCommon() {
-    assertEquals("audio/mpeg", MimeUtils.guessMimeTypeFromExtension("mp3"));
-    assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("png"));
-    assertEquals("application/zip", MimeUtils.guessMimeTypeFromExtension("zip"));
+    public void testCommon() {
+        assertEquals("audio/mpeg", MimeUtils.guessMimeTypeFromExtension("mp3"));
+        assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("png"));
+        assertEquals("application/zip", MimeUtils.guessMimeTypeFromExtension("zip"));
 
-    assertEquals("mp3", MimeUtils.guessExtensionFromMimeType("audio/mpeg"));
-    assertEquals("png", MimeUtils.guessExtensionFromMimeType("image/png"));
-    assertEquals("zip", MimeUtils.guessExtensionFromMimeType("application/zip"));
-  }
+        assertEquals("mp3", MimeUtils.guessExtensionFromMimeType("audio/mpeg"));
+        assertEquals("png", MimeUtils.guessExtensionFromMimeType("image/png"));
+        assertEquals("zip", MimeUtils.guessExtensionFromMimeType("application/zip"));
+    }
 
-  public void test_18390752() {
-    assertEquals("jpg", MimeUtils.guessExtensionFromMimeType("image/jpeg"));
-  }
+    public void test_18390752() {
+        assertEquals("jpg", MimeUtils.guessExtensionFromMimeType("image/jpeg"));
+    }
 
-  public void test_30207891() {
-    assertTrue(MimeUtils.hasMimeType("IMAGE/PNG"));
-    assertTrue(MimeUtils.hasMimeType("IMAGE/png"));
-    assertFalse(MimeUtils.hasMimeType(""));
-    assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/PNG"));
-    assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/png"));
-    assertNull(MimeUtils.guessMimeTypeFromExtension(""));
-    assertNull(MimeUtils.guessMimeTypeFromExtension("doesnotexist"));
-    assertTrue(MimeUtils.hasExtension("PNG"));
-    assertTrue(MimeUtils.hasExtension("PnG"));
-    assertFalse(MimeUtils.hasExtension(""));
-    assertFalse(MimeUtils.hasExtension(".png"));
-    assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PNG"));
-    assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PnG"));
-    assertNull(MimeUtils.guessMimeTypeFromExtension(".png"));
-    assertNull(MimeUtils.guessMimeTypeFromExtension(""));
-    assertNull(MimeUtils.guessExtensionFromMimeType("doesnotexist"));
-  }
+    public void test_30207891() {
+        assertTrue(MimeUtils.hasMimeType("IMAGE/PNG"));
+        assertTrue(MimeUtils.hasMimeType("IMAGE/png"));
+        assertFalse(MimeUtils.hasMimeType(""));
+        assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/PNG"));
+        assertEquals("png", MimeUtils.guessExtensionFromMimeType("IMAGE/png"));
+        assertNull(MimeUtils.guessMimeTypeFromExtension(""));
+        assertNull(MimeUtils.guessMimeTypeFromExtension("doesnotexist"));
+        assertTrue(MimeUtils.hasExtension("PNG"));
+        assertTrue(MimeUtils.hasExtension("PnG"));
+        assertFalse(MimeUtils.hasExtension(""));
+        assertFalse(MimeUtils.hasExtension(".png"));
+        assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PNG"));
+        assertEquals("image/png", MimeUtils.guessMimeTypeFromExtension("PnG"));
+        assertNull(MimeUtils.guessMimeTypeFromExtension(".png"));
+        assertNull(MimeUtils.guessMimeTypeFromExtension(""));
+        assertNull(MimeUtils.guessExtensionFromMimeType("doesnotexist"));
+    }
 
-  public void test_30793548() {
-    assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gpp"));
-    assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gp"));
-    assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3gpp2"));
-    assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3g2"));
-  }
+    public void test_30793548() {
+        assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gpp"));
+        assertEquals("video/3gpp", MimeUtils.guessMimeTypeFromExtension("3gp"));
+        assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3gpp2"));
+        assertEquals("video/3gpp2", MimeUtils.guessMimeTypeFromExtension("3g2"));
+    }
 
-  public void test_37167977() {
-    // https://tools.ietf.org/html/rfc5334#section-10.1
-    assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("ogg"));
-    assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("oga"));
-    assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("spx"));
-    assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
-  }
+    public void test_37167977() {
+        // https://tools.ietf.org/html/rfc5334#section-10.1
+        assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("ogg"));
+        assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("oga"));
+        assertEquals("audio/ogg", MimeUtils.guessMimeTypeFromExtension("spx"));
+        assertEquals("video/ogg", MimeUtils.guessMimeTypeFromExtension("ogv"));
+    }
 
-  public void test_70851634() {
-    assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
-  }
+    public void test_70851634() {
+        assertEquals("application/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+    }
+
+    public void test_112162449_audio() {
+        // According to https://en.wikipedia.org/wiki/M3U#Internet_media_types
+        // this is a giant mess, so we pick "audio/x-mpegurl" because a similar
+        // playlist format uses "audio/x-scpls".
+        assertMimeTypeFromExtension("audio/x-mpegurl", "m3u");
+        assertMimeTypeFromExtension("audio/x-mpegurl", "m3u8");
+        assertExtensionFromMimeType("m3u", "audio/x-mpegurl");
+
+        assertExtensionFromMimeType("m4a", "audio/mp4");
+        assertMimeTypeFromExtension("audio/mpeg", "m4a");
+
+        assertBidirectional("audio/aac", "aac");
+    }
+
+    public void test_112162449_video() {
+        assertBidirectional("video/x-flv", "flv");
+        assertBidirectional("video/quicktime", "mov");
+        assertBidirectional("video/mpeg", "mpeg");
+    }
+
+    public void test_112162449_image() {
+        assertBidirectional("image/heif", "heif");
+        assertBidirectional("image/heif-sequence", "heifs");
+        assertBidirectional("image/heic", "heic");
+        assertBidirectional("image/heic-sequence", "heics");
+        assertMimeTypeFromExtension("image/heif", "hif");
+
+        assertBidirectional("image/x-adobe-dng", "dng");
+        assertBidirectional("image/x-photoshop", "psd");
+
+        assertBidirectional("image/jp2", "jp2");
+        assertMimeTypeFromExtension("image/jp2", "jpg2");
+    }
+
+    private static void assertMimeTypeFromExtension(String mimeType, String extension) {
+        final String actual = MimeUtils.guessMimeTypeFromExtension(extension);
+        if (!Objects.equals(mimeType, actual)) {
+            fail("Expected " + mimeType + " but was " + actual + " for extension " + extension);
+        }
+    }
+
+    private static void assertExtensionFromMimeType(String extension, String mimeType) {
+        final String actual = MimeUtils.guessExtensionFromMimeType(mimeType);
+        if (!Objects.equals(extension, actual)) {
+            fail("Expected " + extension + " but was " + actual + " for type " + mimeType);
+        }
+    }
+
+    private static void assertBidirectional(String mimeType, String extension) {
+        assertMimeTypeFromExtension(mimeType, extension);
+        assertExtensionFromMimeType(extension, mimeType);
+    }
 }
diff --git a/luni/src/test/java/libcore/libcore/net/UriCodecTest.java b/luni/src/test/java/libcore/libcore/net/UriCodecTest.java
deleted file mode 100644
index ca8de89..0000000
--- a/luni/src/test/java/libcore/libcore/net/UriCodecTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package libcore.libcore.net;
-
-import junit.framework.TestCase;
-
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import libcore.net.UriCodec;
-
-/**
- * Tests for {@link UriCodec}
- */
-public class UriCodecTest extends TestCase {
-    private static final UriCodec CODEC = new UriCodec() {
-        @Override
-        protected boolean isRetained(char c) {
-            return c == '$';
-        }
-    };
-
-    private static final String VALID_ENCODED_STRING = "a0b$CD%01a%23b%45c%67%89%abd%cd%efq";
-
-    public void testValidate_stringOK_passes() throws Exception {
-        assertEquals(
-                VALID_ENCODED_STRING,
-                CODEC.validate(
-                        VALID_ENCODED_STRING, 0, VALID_ENCODED_STRING.length(), "test OK string"));
-    }
-
-    // Hex codes in upper case are valid as well.
-    public void testValidate_stringUppercaseOK_passes() throws Exception {
-        String stringOKUpperCase = VALID_ENCODED_STRING.toUpperCase();
-        CODEC.validate(stringOKUpperCase, 0, stringOKUpperCase.length(), "test OK UC string");
-    }
-
-    // Characters before the start index are ignored.
-    public void testValidate_wrongCharsBeforeStart_passes() throws Exception {
-        assertEquals(VALID_ENCODED_STRING, CODEC.validate(
-                "%p" + VALID_ENCODED_STRING,
-                2,
-                VALID_ENCODED_STRING.length() + 2,
-                "test string"));
-    }
-
-    // Fails with character 'p', invalid after '%'
-    public void testValidate_wrongCharsAtStart_fails() throws Exception {
-        try {
-            CODEC.validate(
-                    "%p" + VALID_ENCODED_STRING,
-                    0,
-                    VALID_ENCODED_STRING.length() + 2,
-                    "test string");
-            fail("Expected URISyntaxException");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    // Fails with character 'p', invalid after '%'
-    public void testValidate_wrongCharsBeyondEnd_passes() throws Exception {
-        assertEquals(VALID_ENCODED_STRING, CODEC.validate(
-                VALID_ENCODED_STRING + "%p",
-                0,
-                VALID_ENCODED_STRING.length(),
-                "test string"));
-    }
-
-    // Fails with character 'p', invalid after '%'
-    public void testValidate_wrongCharsAtEnd_fails() throws Exception {
-        try {
-            CODEC.validate(
-                    VALID_ENCODED_STRING + "%p",
-                    0,
-                    VALID_ENCODED_STRING.length() + 2,
-                    "test string");
-            fail("Expected URISyntaxException");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    public void testValidate_secondDigitWrong_fails() throws Exception {
-        try {
-            CODEC.validate(
-                    VALID_ENCODED_STRING + "%1p",
-                    0,
-                    VALID_ENCODED_STRING.length() + 2,
-                    "test string");
-            fail("Expected URISyntaxException");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    public void testValidate_emptyString_passes() throws Exception {
-        assertEquals("", CODEC.validate("", 0, 0, "empty string"));
-    }
-
-    public void testValidate_stringEndingWithPercent_fails() throws Exception {
-        try {
-            CODEC.validate("a%", 0, 0, "a% string");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    public void testValidate_stringEndingWithPercentAndSingleDigit_fails() throws Exception {
-        try {
-            CODEC.validate("a%1", 0, 0, "a%1 string");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    public void testValidateSimple_stringOK_passes() throws Exception {
-        UriCodec.validateSimple(VALID_ENCODED_STRING, "$%");
-    }
-
-    // Hex codes in upper case are valid as well.
-    public void testValidateSimple_stringUppercaseOK_passes() throws Exception {
-        UriCodec.validateSimple(VALID_ENCODED_STRING.toUpperCase(), "$%");
-    }
-
-    // Fails with character 'p', invalid after '%'
-    public void testValidateSimple_wrongCharsAtStart_fails() throws Exception {
-        try {
-            UriCodec.validateSimple("%/" + VALID_ENCODED_STRING, "$%");
-            fail("Expected URISyntaxException");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    // Fails with character 'p', invalid after '%'
-    public void testValidateSimple_wrongCharsAtEnd_fails() throws Exception {
-        try {
-            UriCodec.validateSimple(VALID_ENCODED_STRING + "%/", "$%");
-            fail("Expected URISyntaxException");
-        } catch (URISyntaxException expected) {
-            // Expected.
-        }
-    }
-
-    public void testValidateSimple_emptyString_passes() throws Exception {
-        UriCodec.validateSimple("", "$%");
-    }
-
-    public void testValidateSimple_stringEndingWithPercent_passes() throws Exception {
-        UriCodec.validateSimple("a%", "$%");
-    }
-
-    public void testValidateSimple_stringEndingWithPercentAndSingleDigit_passes() throws Exception {
-        UriCodec.validateSimple("a%1", "$%");
-    }
-
-    public void testEncode_emptyString_returnsEmptyString() {
-        assertEquals("", CODEC.encode("", StandardCharsets.UTF_8));
-    }
-
-    public void testEncode() {
-        assertEquals("ab%2F$%C4%82%2512", CODEC.encode("ab/$\u0102%12", StandardCharsets.UTF_8));
-    }
-
-    public void testEncode_convertWhitespace() {
-        // Whitespace is not retained, output %20.
-        assertEquals("ab%2F$%C4%82%2512%20",
-                CODEC.encode("ab/$\u0102%12 ", StandardCharsets.UTF_8));
-
-        UriCodec withWhitespaceRetained = new UriCodec() {
-            @Override
-            protected boolean isRetained(char c) {
-                return c == '$' || c == ' ';
-            }
-        };
-        // Whitespace is retained, convert to plus.
-        assertEquals("ab%2F$%C4%82%2512+",
-                withWhitespaceRetained.encode("ab/$\u0102%12 ", StandardCharsets.UTF_8));
-    }
-
-    /** Confirm that '%' can be retained, disabling '%' encoding. http://b/24806835 */
-    public void testEncode_percentRetained() {
-        UriCodec withPercentRetained = new UriCodec() {
-            @Override
-            protected boolean isRetained(char c) {
-                return c == '%';
-            }
-        };
-        // Percent is retained
-        assertEquals("ab%34%20", withPercentRetained.encode("ab%34 ", StandardCharsets.UTF_8));
-    }
-
-    public void testEncode_partially_returnsPercentUnchanged() {
-        StringBuilder stringBuilder = new StringBuilder();
-        // Check it's really appending instead of returning a new builder.
-        stringBuilder.append("pp");
-        CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%");
-        // Returns % at the end instead of %25.
-        assertEquals("ppab%2F$%C4%82%", stringBuilder.toString());
-    }
-
-    public void testEncode_partially_returnsCharactersAfterPercentEncoded() {
-        StringBuilder stringBuilder = new StringBuilder();
-        // Check it's really appending instead of returning a new builder.
-        stringBuilder.append("pp");
-        CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%\u0102");
-        // Returns %C4%82 at the end.
-        assertEquals("ppab%2F$%C4%82%%C4%82", stringBuilder.toString());
-    }
-
-    public void testEncode_partially_returnsDigitsAfterPercentUnchanged() {
-        StringBuilder stringBuilder = new StringBuilder();
-        // Check it's really appending instead of returning a new builder.
-        stringBuilder.append("pp");
-        CODEC.appendPartiallyEncoded(stringBuilder, "ab/$\u0102%38");
-        // Returns %38 at the end.
-        assertEquals("ppab%2F$%C4%82%38", stringBuilder.toString());
-    }
-
-    // Last character needs encoding (make sure we are flushing the buffer with chars to encode).
-    public void testEncode_lastCharacter() {
-        assertEquals("ab%2F$%C4%82%25%E0%A1%80",
-                CODEC.encode("ab/$\u0102%\u0840", StandardCharsets.UTF_8));
-    }
-
-    // Last character needs encoding (make sure we are flushing the buffer with chars to encode).
-    public void testEncode_flushBufferBeforePlusFromSpace() {
-        UriCodec withSpaceRetained = new UriCodec() {
-            @Override
-            protected boolean isRetained(char c) {
-                return c == ' ';
-            }
-        };
-        assertEquals("%2F+",
-                withSpaceRetained.encode("/ ", StandardCharsets.UTF_8));
-    }
-
-    public void testDecode_emptyString_returnsEmptyString() {
-        assertEquals("", UriCodec.decode(""));
-    }
-
-    public void testDecode_wrongHexDigit_fails() {
-        try {
-            // %p in the end.
-            UriCodec.decode("ab%2f$%C4%82%25%e0%a1%80%p");
-            fail("Expected URISyntaxException");
-        } catch (IllegalArgumentException expected) {
-            // Expected.
-        }
-    }
-
-    public void testDecode_secondHexDigitWrong_fails() {
-        try {
-            // %1p in the end.
-            UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%1p");
-            fail("Expected URISyntaxException");
-        } catch (IllegalArgumentException expected) {
-            // Expected.
-        }
-    }
-
-    public void testDecode_endsWithPercent_fails() {
-        try {
-            // % in the end.
-            UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%");
-            fail("Expected URISyntaxException");
-        } catch (IllegalArgumentException expected) {
-            // Expected.
-        }
-    }
-
-    public void testDecode_dontThrowException_appendsUnknownCharacter() {
-        assertEquals("ab/$\u0102%\u0840\ufffd",
-                UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80%",
-                        false /* convertPlus */,
-                        StandardCharsets.UTF_8,
-                        false /* throwOnFailure */));
-    }
-
-    public void testDecode_convertPlus() {
-        assertEquals("ab/$\u0102% \u0840",
-                UriCodec.decode("ab%2f$%c4%82%25+%e0%a1%80",
-                        true /* convertPlus */,
-                        StandardCharsets.UTF_8,
-                        false /* throwOnFailure */));
-    }
-
-    // Last character needs decoding (make sure we are flushing the buffer with chars to decode).
-    public void testDecode_lastCharacter() {
-        assertEquals("ab/$\u0102%\u0840",
-                UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80"));
-    }
-
-    // Check that a second row of encoded characters is decoded properly (internal buffers are
-    // reset properly).
-    public void testDecode_secondRowOfEncoded() {
-        assertEquals("ab/$\u0102%\u0840aa\u0840",
-                UriCodec.decode("ab%2f$%c4%82%25%e0%a1%80aa%e0%a1%80"));
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java b/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java
new file mode 100644
index 0000000..81f0b01
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/util/ArrayUtilsTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.libcore.util;
+
+import static libcore.util.ArrayUtils.throwsIfOutOfBounds;
+
+import org.junit.Test;
+
+public class ArrayUtilsTest {
+    @Test
+    public void testThrowsIfOutOfBounds_passesWhenRangeInsideArray() {
+        throwsIfOutOfBounds(10, 2, 6);
+    }
+
+    @Test
+    public void testThrowsIfOutOfBounds_passesWhenRangeIsWholeArray() {
+        throwsIfOutOfBounds(10, 0, 10);
+    }
+
+    @Test
+    public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtStart() {
+        throwsIfOutOfBounds(10, 0, 0);
+    }
+
+    @Test
+    public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtEnd() {
+        throwsIfOutOfBounds(10, 10, 0);
+    }
+
+    @Test
+    public void testThrowsIfOutOfBounds_passesWhenEmptyArray() {
+        throwsIfOutOfBounds(0, 0, 0);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenRangeStartNegative() {
+        throwsIfOutOfBounds(10, -1, 5);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenCountNegative() {
+        throwsIfOutOfBounds(10, 5, -1);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenRangeStartTooHigh() {
+        throwsIfOutOfBounds(10, 11, 0);
+    }
+
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenRangeEndTooHigh() {
+        throwsIfOutOfBounds(10, 5, 6);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenLengthNegative() {
+        throwsIfOutOfBounds(-1, 0, 0);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void testThrowsIfOutOfBounds_failsWhenOverflowRangeEndTooHigh() {
+        throwsIfOutOfBounds(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+}
diff --git a/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java b/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java
new file mode 100644
index 0000000..49923a5
--- /dev/null
+++ b/luni/src/test/java/libcore/sun/misc/SharedSecretsTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.sun.misc;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import sun.misc.SharedSecrets;
+
+@RunWith(JUnit4.class)
+public class SharedSecretsTest {
+
+    /**
+     * This test doesn't completely rule out race conditions such as http://b/80495283 (between
+     * FileDescriptor and UnixChannelFactory): Even if this test passes by the time it runs, the
+     * condition that it enforces may not have been true earlier in the runtime start.
+     */
+    @Test
+    public void testGetJavaIOFileDescriptorAccess_notNull() {
+        Assert.assertNotNull("SharedSecrets.getJavaIOFileDescriptorAccess can't be null",
+                SharedSecrets.getJavaIOFileDescriptorAccess());
+    }
+}
diff --git a/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
index 3175b37..0803c58 100644
--- a/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java
@@ -16,7 +16,7 @@
 
 package libcore.xml;
 
-import org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
diff --git a/luni/src/test/java/libcore/xml/KxmlPullParserTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
index 71f25e9..760668d 100644
--- a/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java
@@ -16,7 +16,7 @@
 
 package libcore.xml;
 
-import org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 
 public class KxmlPullParserTest extends PullParserTest {
diff --git a/luni/src/test/java/libcore/xml/KxmlSerializerTest.java b/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
index fffb3f1..4c4075b 100644
--- a/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
+++ b/luni/src/test/java/libcore/xml/KxmlSerializerTest.java
@@ -16,11 +16,11 @@
 
 package libcore.xml;
 
+import com.android.org.kxml2.io.KXmlSerializer;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.StringWriter;
 import junit.framework.TestCase;
-import org.kxml2.io.KXmlSerializer;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
diff --git a/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
index 7194414..0431a16 100644
--- a/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
+++ b/luni/src/test/java/libcore/xml/XmlPullParserFactoryTest.java
@@ -16,14 +16,14 @@
 
 package libcore.xml;
 
+import com.android.org.kxml2.io.KXmlParser;
+import com.android.org.kxml2.io.KXmlSerializer;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 import junit.framework.TestCase;
-import org.kxml2.io.KXmlParser;
-import org.kxml2.io.KXmlSerializer;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlPullParserFactory;
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java
deleted file mode 100644
index 0a64dce..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/Matcher2Test.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.*;
-
-/**
- * Tests Matcher methods
- *
- */
-public class Matcher2Test extends TestCase {
-
-    public void test_toString() {
-        Pattern p = Pattern.compile("foo");
-        Matcher m = p.matcher("bar");
-        assertNotNull(m.toString());
-    }
-
-    public void testErrorConditions() throws PatternSyntaxException {
-        // Test match cursors in absence of a match
-        Pattern p = Pattern.compile("foo");
-        Matcher m = p.matcher("bar");
-        assertFalse(m.matches());
-
-        try {
-            m.start();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.end();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.group();
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.start(1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.end(1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.group(1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-               // regression test for HARMONY-2418
-        try {
-            m.usePattern(null);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {
-                 // PASSED
-        }
-    }
-
-    public void testErrorConditions2() throws PatternSyntaxException {
-        // Test match cursors in absence of a match
-        Pattern p = Pattern.compile("(foo[0-9])(bar[a-z])");
-        Matcher m = p.matcher("foo1barzfoo2baryfoozbar5");
-
-        assertTrue(m.find());
-        assertEquals(0, m.start());
-        assertEquals(8, m.end());
-        assertEquals(0, m.start(1));
-        assertEquals(4, m.end(1));
-        assertEquals(4, m.start(2));
-        assertEquals(8, m.end(2));
-
-        try {
-            m.start(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.end(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.group(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.start(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.end(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.group(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        assertTrue(m.find());
-        assertEquals(8, m.start());
-        assertEquals(16, m.end());
-        assertEquals(8, m.start(1));
-        assertEquals(12, m.end(1));
-        assertEquals(12, m.start(2));
-        assertEquals(16, m.end(2));
-
-        try {
-            m.start(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.end(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.group(3);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.start(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.end(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            m.group(-1);
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        assertFalse(m.find());
-
-        try {
-            m.start(3);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.end(3);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.group(3);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.start(-1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.end(-1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            m.group(-1);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-        }
-    }
-
-    /*
-     * Regression test for HARMONY-997
-     */
-    public void testReplacementBackSlash() {
-        String str = "replace me";
-        String replacedString = "me";
-        String substitutionString = "\\";
-        Pattern pat = Pattern.compile(replacedString);
-        Matcher mat = pat.matcher(str);
-        try {
-            String res = mat.replaceAll(substitutionString);
-            fail("IndexOutOfBoundsException should be thrown - " + res);
-        } catch (Exception e) {
-        }
-    }
-}
-
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java
deleted file mode 100644
index 569d3e6..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ModeTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * Tests Pattern compilation modes and modes triggered in pattern strings
- *
- */
-public class ModeTest extends TestCase {
-
-    public void testCase() throws PatternSyntaxException {
-        Pattern p;
-        Matcher m;
-
-        p = Pattern.compile("([a-z]+)[0-9]+");
-        m = p.matcher("cAT123#dog345");
-        assertTrue(m.find());
-        assertEquals("dog", m.group(1));
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("([a-z]+)[0-9]+", Pattern.CASE_INSENSITIVE);
-        m = p.matcher("cAt123#doG345");
-        assertTrue(m.find());
-        assertEquals("cAt", m.group(1));
-        assertTrue(m.find());
-        assertEquals("doG", m.group(1));
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("(?i)([a-z]+)[0-9]+");
-        m = p.matcher("cAt123#doG345");
-        assertTrue(m.find());
-        assertEquals("cAt", m.group(1));
-        assertTrue(m.find());
-        assertEquals("doG", m.group(1));
-        assertFalse(m.find());
-    }
-    public void testMultiline() throws PatternSyntaxException {
-        Pattern p;
-        Matcher m;
-
-        p = Pattern.compile("^foo");
-        m = p.matcher("foobar");
-        assertTrue(m.find());
-        assertTrue(m.start() == 0 && m.end() == 3);
-        assertFalse(m.find());
-
-        m = p.matcher("barfoo");
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("foo$");
-        m = p.matcher("foobar");
-        assertFalse(m.find());
-
-        m = p.matcher("barfoo");
-        assertTrue(m.find());
-        assertTrue(m.start() == 3 && m.end() == 6);
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("^foo([0-9]*)", Pattern.MULTILINE);
-        m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
-        assertTrue(m.find());
-        assertEquals("1", m.group(1));
-        assertTrue(m.find());
-        assertEquals("2", m.group(1));
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("foo([0-9]*)$", Pattern.MULTILINE);
-        m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
-        assertTrue(m.find());
-        assertEquals("3", m.group(1));
-        assertTrue(m.find());
-        assertEquals("4", m.group(1));
-        assertFalse(m.find());
-
-
-        p = Pattern.compile("(?m)^foo([0-9]*)");
-        m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
-        assertTrue(m.find());
-        assertEquals("1", m.group(1));
-        assertTrue(m.find());
-        assertEquals("2", m.group(1));
-        assertFalse(m.find());
-
-        p = Pattern.compile("(?m)foo([0-9]*)$");
-        m = p.matcher("foo1bar\nfoo2foo3\nbarfoo4");
-        assertTrue(m.find());
-        assertEquals("3", m.group(1));
-        assertTrue(m.find());
-        assertEquals("4", m.group(1));
-        assertFalse(m.find());
-    }
-}
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
index 96de6c8..3a56f6a 100644
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
+++ b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
@@ -18,6 +18,7 @@
 package org.apache.harmony.regex.tests.java.util.regex;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -27,6 +28,10 @@
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
+import dalvik.system.VMRuntime;
+
+import static java.util.Arrays.asList;
+
 public class PatternTest extends TestCase {
     String[] testPatterns = {
             "(a|b)*abb",
@@ -107,7 +112,7 @@
         s = pat.split("", -1);
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe", -1);
-        assertEquals(s.length, 11);
+        assertEquals(s.length, 10);
         // zero limit
         pat = Pattern.compile("b");
         s = pat.split("abccbadfebb", 0);
@@ -118,7 +123,7 @@
         s = pat.split("", 0);
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe", 0);
-        assertEquals(s.length, 10);
+        assertEquals(s.length, 9);
         // positive limit
         pat = Pattern.compile("b");
         s = pat.split("abccbadfebb", 12);
@@ -129,7 +134,7 @@
         s = pat.split("", 11);
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe", 15);
-        assertEquals(s.length, 11);
+        assertEquals(s.length, 10);
 
         pat = Pattern.compile("b");
         s = pat.split("abccbadfebb", 5);
@@ -139,8 +144,8 @@
         pat = Pattern.compile("");
         s = pat.split("", 1);
         assertEquals(s.length, 1);
-        s = pat.split("abccbadfe", 11);
-        assertEquals(s.length, 11);
+        s = pat.split("abccbadfe", 10);
+        assertEquals(s.length, 10);
 
         pat = Pattern.compile("b");
         s = pat.split("abccbadfebb", 3);
@@ -150,6 +155,65 @@
         assertEquals(s.length, 5);
     }
 
+    public void testSplitOnEmptyPattern_apiCurrent() {
+        assertEquals(asList("t", "e", "s", "t"), asList("test".split("")));
+        assertEquals(asList(""), asList("".split("")));
+        assertEquals(asList(""), asList(Pattern.compile("").split("")));
+        assertEquals(asList(""), asList("".split("", -1)));
+    }
+
+    public void testSplitOnEmptyPattern_api28() {
+        runWithTargetSdkVersion(28, () -> {
+            assertEquals(asList("", "t", "e", "s", "t"), asList("test".split("")));
+            assertEquals(asList(""), asList("".split("")));
+            assertEquals(asList(""), asList(Pattern.compile("").split("")));
+            assertEquals(asList(""), asList("".split("", -1)));
+        });
+    }
+
+    /**
+     * Tests that a match at the beginning of the input string only produces
+     * a "" if the match is positive-width.
+     */
+    public void testMatchBeginningOfInputSequence_apiCurrent() {
+        // Positive-width match at the beginning of the input.
+        assertEquals(asList("", "", "rdv", "rk"), asList("aardvark".split("a")));
+        assertEquals(asList("", "anana"), asList("banana".split("b")));
+        // Zero-width match at the beginning of the input
+        assertEquals(asList("a", "ardv", "ark"), asList("aardvark".split("(?=a)")));
+        assertEquals(asList("banana"), asList("banana".split("(?=b)")));
+
+        // For comparison, matches in the middle of the input never yield an empty substring:
+        assertEquals(asList("aar", "vark"), asList("aardvark".split("d")));
+        assertEquals(asList("aar", "dvark"), asList("aardvark".split("(?=d)")));
+    }
+
+    public void testMatchBeginningOfInputSequence_api28() {
+        runWithTargetSdkVersion(28, () -> {
+            // Positive-width match at the beginning of the input.
+            assertEquals(asList("", "", "rdv", "rk"), asList("aardvark".split("a")));
+            assertEquals(asList("", "anana"), asList("banana".split("b")));
+            // Zero-width match at the beginning of the input
+            assertEquals(asList("", "a", "ardv", "ark"), asList("aardvark".split("(?=a)")));
+            assertEquals(asList("banana"), asList("banana".split("(?=b)")));
+
+            // For comparison, matches in the middle of the input never yield an empty substring:
+            assertEquals(asList("aar", "vark"), asList("aardvark".split("d")));
+            assertEquals(asList("aar", "dvark"), asList("aardvark".split("(?=d)")));
+        });
+    }
+
+    private static void runWithTargetSdkVersion(int targetSdkVersion, Runnable runnable) {
+        VMRuntime vmRuntime = VMRuntime.getRuntime();
+        int oldVersion = vmRuntime.getTargetSdkVersion();
+        vmRuntime.setTargetSdkVersion(targetSdkVersion);
+        try {
+            runnable.run();
+        } finally {
+            vmRuntime.setTargetSdkVersion(oldVersion);
+        }
+    }
+
     public void testSplitCharSequence() {
         String s[];
         Pattern pat = Pattern.compile("b");
@@ -161,7 +225,7 @@
         s = pat.split("");
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe");
-        assertEquals(s.length, 10);
+        assertEquals(s.length, 9);
         // bug6544
         String s1 = "";
         String[] arr = s1.split(":");
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java
deleted file mode 100644
index e609bb2..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/ReplaceTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.util.regex.PatternSyntaxException;
-
-public class ReplaceTest extends TestCase {
-    public void testSimpleReplace() throws PatternSyntaxException {
-        String target, pattern, repl;
-
-        target = "foobarfobarfoofo1barfort";
-        pattern = "fo[^o]";
-        repl = "xxx";
-
-        Pattern p = Pattern.compile(pattern);
-        Matcher m = p.matcher(target);
-
-        assertEquals("foobarxxxarfoofo1barfort", m.replaceFirst(repl));
-        assertEquals("foobarxxxarfooxxxbarxxxt", m.replaceAll(repl));
-    }
-
-    public void testCaptureReplace() {
-        String target, pattern, repl, s;
-        Pattern p = null;
-        Matcher m;
-
-        target = "[31]foo;bar[42];[99]xyz";
-        pattern = "\\[([0-9]+)\\]([a-z]+)";
-        repl = "$2[$1]";
-
-        p = Pattern.compile(pattern);
-        m = p.matcher(target);
-        s = m.replaceFirst(repl);
-        assertEquals("foo[31];bar[42];[99]xyz", s);
-        s = m.replaceAll(repl);
-        assertEquals("foo[31];bar[42];xyz[99]", s);
-
-        target = "[31]foo(42)bar{63}zoo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;";
-        pattern = "\\[([0-9]+)\\]([a-z]+)\\(([0-9]+)\\)([a-z]+)\\{([0-9]+)\\}([a-z]+)";
-        repl = "[$5]$6($3)$4{$1}$2";
-        p = Pattern.compile(pattern);
-        m = p.matcher(target);
-        s = m.replaceFirst(repl);
-        // System.out.println(s);
-        assertEquals("[63]zoo(42)bar{31}foo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;", s
-                );
-        s = m.replaceAll(repl);
-        // System.out.println(s);
-        assertEquals("[63]zoo(42)bar{31}foo;[56]ghi(34)def{12}abc;{99}xyz[88]xyz(77)xyz;", s
-                );
-    }
-
-    public void testEscapeReplace() {
-        String target, pattern, repl, s;
-
-        target = "foo'bar''foo";
-        pattern = "'";
-        repl = "\\'";
-        s = target.replaceAll(pattern, repl);
-        assertEquals("foo'bar''foo", s);
-        repl = "\\\\'";
-        s = target.replaceAll(pattern, repl);
-        assertEquals("foo\\'bar\\'\\'foo", s);
-        repl = "\\$3";
-        s = target.replaceAll(pattern, repl);
-        assertEquals("foo$3bar$3$3foo", s);
-    }
-}
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java
deleted file mode 100644
index 5c8996a..0000000
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package org.apache.harmony.regex.tests.java.util.regex;
-
-import junit.framework.TestCase;
-import java.util.regex.*;
-
-/**
- * TODO Type description
- *
- */
-public class SplitTest extends TestCase {
-    public void testSimple() {
-        Pattern p = Pattern.compile("/");
-        String[] results = p.split("have/you/done/it/right");
-        String[] expected = new String[] { "have", "you", "done", "it", "right" };
-        assertArraysEqual(expected, results);
-    }
-
-    @SuppressWarnings("InvalidPatternSyntax")
-    public void testEmptySplits() {
-        // Trailing empty matches are removed.
-        assertArraysEqual(new String[0], "hello".split("."));
-        assertArraysEqual(new String[] { "1", "2" }, "1:2:".split(":"));
-        // ...including when that results in an empty result.
-        assertArraysEqual(new String[0], ":".split(":"));
-        // ...but not when limit < 0.
-        assertArraysEqual(new String[] { "1", "2", "" }, "1:2:".split(":", -1));
-
-        // Leading empty matches are retained.
-        assertArraysEqual(new String[] { "", "", "o" }, "hello".split(".."));
-
-        // A separator that doesn't occur in the input gets you the input.
-        assertArraysEqual(new String[] { "hello" }, "hello".split("not-present-in-test"));
-        // ...including when the input is the empty string.
-        // (Perl returns an empty list instead.)
-        assertArraysEqual(new String[] { "" }, "".split("not-present-in-test"));
-        assertArraysEqual(new String[] { "" }, "".split("A?"));
-
-        // The limit argument controls the size of the result.
-        // If l == 0, the result is as long as needed, except trailing empty matches are dropped.
-        // If l < 0, the result is as long as needed, and trailing empty matches are retained.
-        // If l > 0, the result contains the first l matches, plus one string containing the remaining input.
-        // Examples without a trailing separator (and hence without a trailing empty match):
-        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 0));
-        assertArraysEqual(new String[] { "a,b,c" }, "a,b,c".split(",", 1));
-        assertArraysEqual(new String[] { "a", "b,c" }, "a,b,c".split(",", 2));
-        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 3));
-        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", Integer.MAX_VALUE));
-        // Examples with a trailing separator (and hence possibly with a trailing empty match):
-        assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c,".split(",", 0));
-        assertArraysEqual(new String[] { "a,b,c," }, "a,b,c,".split(",", 1));
-        assertArraysEqual(new String[] { "a", "b,c," }, "a,b,c,".split(",", 2));
-        assertArraysEqual(new String[] { "a", "b", "c," }, "a,b,c,".split(",", 3));
-        assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", Integer.MAX_VALUE));
-        assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", -1));
-    }
-
-    private void assertArraysEqual(String[] expected, String[] actual) {
-        assertEquals(expected.length, actual.length);
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(Integer.toString(i), expected[i], actual[i]);
-        }
-    }
-
-    public void testSplit1() throws PatternSyntaxException {
-        Pattern p = Pattern.compile(" ");
-
-        String input = "poodle zoo";
-        String tokens[];
-
-        tokens = p.split(input, 1);
-        assertEquals(1, tokens.length);
-        assertTrue(tokens[0].equals(input));
-        tokens = p.split(input, 2);
-        assertEquals(2, tokens.length);
-        assertEquals("poodle", tokens[0]);
-        assertEquals("zoo", tokens[1]);
-        tokens = p.split(input, 5);
-        assertEquals(2, tokens.length);
-        assertEquals("poodle", tokens[0]);
-        assertEquals("zoo", tokens[1]);
-        tokens = p.split(input, -2);
-        assertEquals(2, tokens.length);
-        assertEquals("poodle", tokens[0]);
-        assertEquals("zoo", tokens[1]);
-        tokens = p.split(input, 0);
-        assertEquals(2, tokens.length);
-        assertEquals("poodle", tokens[0]);
-        assertEquals("zoo", tokens[1]);
-        tokens = p.split(input);
-        assertEquals(2, tokens.length);
-        assertEquals("poodle", tokens[0]);
-        assertEquals("zoo", tokens[1]);
-
-        p = Pattern.compile("d");
-
-        tokens = p.split(input, 1);
-        assertEquals(1, tokens.length);
-        assertTrue(tokens[0].equals(input));
-        tokens = p.split(input, 2);
-        assertEquals(2, tokens.length);
-        assertEquals("poo", tokens[0]);
-        assertEquals("le zoo", tokens[1]);
-        tokens = p.split(input, 5);
-        assertEquals(2, tokens.length);
-        assertEquals("poo", tokens[0]);
-        assertEquals("le zoo", tokens[1]);
-        tokens = p.split(input, -2);
-        assertEquals(2, tokens.length);
-        assertEquals("poo", tokens[0]);
-        assertEquals("le zoo", tokens[1]);
-        tokens = p.split(input, 0);
-        assertEquals(2, tokens.length);
-        assertEquals("poo", tokens[0]);
-        assertEquals("le zoo", tokens[1]);
-        tokens = p.split(input);
-        assertEquals(2, tokens.length);
-        assertEquals("poo", tokens[0]);
-        assertEquals("le zoo", tokens[1]);
-
-        p = Pattern.compile("o");
-
-        tokens = p.split(input, 1);
-        assertEquals(1, tokens.length);
-        assertTrue(tokens[0].equals(input));
-        tokens = p.split(input, 2);
-        assertEquals(2, tokens.length);
-        assertEquals("p", tokens[0]);
-        assertEquals("odle zoo", tokens[1]);
-        tokens = p.split(input, 5);
-        assertEquals(5, tokens.length);
-        assertEquals("p", tokens[0]);
-        assertTrue(tokens[1].equals(""));
-        assertEquals("dle z", tokens[2]);
-        assertTrue(tokens[3].equals(""));
-        assertTrue(tokens[4].equals(""));
-        tokens = p.split(input, -2);
-        assertEquals(5, tokens.length);
-        assertEquals("p", tokens[0]);
-        assertTrue(tokens[1].equals(""));
-        assertEquals("dle z", tokens[2]);
-        assertTrue(tokens[3].equals(""));
-        assertTrue(tokens[4].equals(""));
-        tokens = p.split(input, 0);
-        assertEquals(3, tokens.length);
-        assertEquals("p", tokens[0]);
-        assertTrue(tokens[1].equals(""));
-        assertEquals("dle z", tokens[2]);
-        tokens = p.split(input);
-        assertEquals(3, tokens.length);
-        assertEquals("p", tokens[0]);
-        assertTrue(tokens[1].equals(""));
-        assertEquals("dle z", tokens[2]);
-    }
-
-    public void testSplit2() {
-        Pattern p = Pattern.compile("");
-        String s[];
-        s = p.split("a", -1);
-        assertEquals(3, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("", s[2]);
-
-        s = p.split("", -1);
-        assertEquals(1, s.length);
-        assertEquals("", s[0]);
-
-        s = p.split("abcd", -1);
-        assertEquals(6, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("b", s[2]);
-        assertEquals("c", s[3]);
-        assertEquals("d", s[4]);
-        assertEquals("", s[5]);
-
-        // Regression test for Android
-        assertEquals("GOOG,23,500".split("|").length, 12);
-    }
-
-
-    public void testSplitSupplementaryWithEmptyString() {
-
-        /*
-         * See http://www.unicode.org/reports/tr18/#Supplementary_Characters
-         * We have to treat text as code points not code units.
-         */
-        Pattern p = Pattern.compile("");
-        String s[];
-        s = p.split("a\ud869\uded6b", -1);
-        assertEquals(5, s.length);
-        assertEquals("", s[0]);
-        assertEquals("a", s[1]);
-        assertEquals("\ud869\uded6", s[2]);
-        assertEquals("b", s[3]);
-        assertEquals("", s[4]);
-    }
-}
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
new file mode 100644
index 0000000..523601d
--- /dev/null
+++ b/mmodules/core_platform_api/Android.bp
@@ -0,0 +1,79 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Build rules for the APIs that various core libraries provide to other parts
+// of the Android software stack: these include the public SDK APIs plus some
+// "core platform APIs" that only the Android software stack can use.
+
+// Generates stub source files for the {public SDK + core platform} API of the
+// core jars.
+droidstubs {
+    name: "core-platform-api-stubs",
+    srcs: [":core_api_files"],
+    no_framework_libs: true,
+
+    installable: false,
+    args: "--show-single-annotation libcore.api.CorePlatformApi",
+
+    api_filename: "api.txt",
+    removed_api_filename: "removed.txt",
+    previous_api: "previous.txt",
+    check_api: {
+        current: {
+            api_file: "api/platform/current-api.txt",
+            removed_api_file: "api/platform/current-removed.txt",
+        },
+        last_released: {
+            api_file: "api/platform/last-api.txt",
+            removed_api_file: "api/platform/last-removed.txt",
+        },
+    },
+}
+
+// A library containing the {public SDK + core platform} API stubs for the core jars.
+java_library {
+    name: "core.platform.api.stubs",
+    srcs: [":core-platform-api-stubs"],
+
+    no_standard_libs: true,
+    libs: ["core-all"],
+    system_modules: "core-all-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
+// Used when compiling higher-level code against core.platform.api.stubs.
+java_system_modules {
+    name: "core-platform-api-stubs-system-modules",
+    libs: ["core.platform.api.stubs"],
+}
+
+// Tests associated with the core platform APIs.
+java_test {
+    name: "core-platform-api-test",
+    srcs: [ "src/test/java/**/*.java" ],
+
+    no_standard_libs: true,
+    libs: [
+          // We depend on stubs not the impl code. We do not test
+          // internals, just the {public SDK + core platform} APIs.
+          "core.platform.api.stubs",
+          // Other deps needed for tests.
+          "junit",
+    ],
+    system_modules: "core-platform-api-stubs-system-modules",
+}
+
+
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
new file mode 100644
index 0000000..1a9d8bf
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -0,0 +1,8 @@
+package libcore.mmodule.libart {
+
+  public class DemoLibartClass {
+    method public static java.lang.String corePlatformApiMethod();
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/mmodules/core_platform_api/api/platform/current-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-removed.txt
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/platform/last-api.txt
new file mode 100644
index 0000000..1a9d8bf
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/last-api.txt
@@ -0,0 +1,8 @@
+package libcore.mmodule.libart {
+
+  public class DemoLibartClass {
+    method public static java.lang.String corePlatformApiMethod();
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/last-removed.txt b/mmodules/core_platform_api/api/platform/last-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/last-removed.txt
diff --git a/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java b/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java
new file mode 100644
index 0000000..bc4265c
--- /dev/null
+++ b/mmodules/core_platform_api/src/test/java/libcore/test/coreplatformapi/DemoLibartCorePlatformApiTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.test.coreplatformapi;
+
+import static org.junit.Assert.assertEquals;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+import org.junit.Test;
+
+/**
+ * A test of the behavior of {@link DemoLibartClass} core platform API methods.
+ */
+public class DemoLibartCorePlatformApiTest {
+
+    @Test
+    public void corePlatformApiMethod() {
+        assertEquals("Hello World", DemoLibartClass.corePlatformApiMethod());
+    }
+}
diff --git a/mmodules/core_platform_api_client_demo/Android.bp b/mmodules/core_platform_api_client_demo/Android.bp
new file mode 100644
index 0000000..c5d5015
--- /dev/null
+++ b/mmodules/core_platform_api_client_demo/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// A demo library that depends on core internals and acts as a stand-in
+// for rules like "framework" until we have the full Core platform API marked
+// out.
+java_library {
+    name: "core_platform_api_client_demo",
+    srcs: ["src/main/java/**/*.java"],
+    sdk_version: "core_platform_current",
+}
+
diff --git a/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java b/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java
new file mode 100644
index 0000000..6e6d83b
--- /dev/null
+++ b/mmodules/core_platform_api_client_demo/src/main/java/com/android/coreplatformapiclient/DemoCorePlatformApiClientClass.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.coreplatformapiclient;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+/**
+ * A class that uses "core API" and can be used to test framework build rule changes.
+ */
+public class DemoCorePlatformApiClientClass {
+
+    public static void callingPublicApi() {
+        new Object();
+    }
+
+    public static void callingCorePlatformApi() {
+        DemoLibartClass.corePlatformApiMethod();
+
+        // This is an example of a method that is not in the public SDK or core API so will fail
+        // compilation if the build is doing things correctly.
+        // Byte.toHexString((byte) 8, true);
+    }
+}
diff --git a/mmodules/intracoreapi/Android.bp b/mmodules/intracoreapi/Android.bp
new file mode 100644
index 0000000..d67af36
--- /dev/null
+++ b/mmodules/intracoreapi/Android.bp
@@ -0,0 +1,50 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Build rules for the APIs that the various core libraries can depend on from
+// each other: public SDK APIs and "intra-core" APIs. Intra-core APIs are not
+// for use by other parts of the Android software stack.
+
+// Generates stub source files for the {public SDK + intra-core} API
+// of the core jars.
+droidstubs {
+    name: "core-intra-stubs",
+    srcs: [":core_api_files"],
+    no_framework_libs: true,
+
+    api_filename: "api.txt",
+    installable: false,
+    args: "--show-single-annotation libcore.api.IntraCoreApi",
+}
+
+// A library containing the {public SDK + intra-core} API stubs for the
+// core jars.
+java_library {
+    name: "core.intra.stubs",
+    srcs: [":core-intra-stubs"],
+
+    no_standard_libs: true,
+    libs: ["core-all"],
+    system_modules: "core-all-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
+// Used when compiling against core.intra.stubs.
+java_system_modules {
+    name: "core-intra-stubs-system-modules",
+    libs: ["core.intra.stubs"],
+}
+
diff --git a/mmodules/libart_oj/Android.bp b/mmodules/libart_oj/Android.bp
new file mode 100644
index 0000000..807f255
--- /dev/null
+++ b/mmodules/libart_oj/Android.bp
@@ -0,0 +1,91 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This build file handles the logical unit that is the combined "core-libart"
+// + "core-oj" jars. These two jars will always be shipped as a unit but are
+// kept separate on device for licensing reasons. Because they will be shipped
+// together we can consider them as a unit and we don't need a well-defined
+// intra-core API between them.
+
+// A rule that checks we can build core-libart and core-oj using only the source
+// for core-libart and core-oj and the APIs in core-intra-stubs.
+java_library {
+    name: "core-libart-oj.depscheck",
+    srcs: [
+        ":core_libart_java_files",
+        ":core_oj_java_files",
+    ],
+    errorprone: {
+        javacflags: [
+            "-Xep:MissingOverride:OFF",  // Ignore missing @Override.
+            "-Xep:ConstantOverflow:WARN",  // Known constant overflow in SplittableRandom
+        ],
+    },
+
+    installable: false,
+
+    no_standard_libs: true,
+    libs: ["core.intra.stubs"],
+    system_modules: "core-intra-stubs-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
+// Tests associated with the {core-libart + core-oj} intra-core APIs.
+java_test {
+    name: "core-libart+oj-intra-test",
+    srcs: [ "src/test/java/**/*.java" ],
+
+    no_standard_libs: true,
+    libs: [
+          // We depend on stubs not the impl code. We do not test
+          // internals, just the {public SDK + intra-core} APIs.
+          "core.intra.stubs",
+          // Other deps needed for tests.
+          "junit",
+    ],
+    system_modules: "core-intra-stubs-system-modules",
+}
+
+// Generates stub source files for the {public SDK + intra-core} APIs
+// of core-libart.
+droidstubs {
+    name: "core-libart+oj-intra-stubs",
+    srcs: [
+        ":core_libart_api_files",
+        ":core_oj_api_files",
+    ],
+    no_framework_libs: true,
+
+    installable: false,
+    args: "--show-single-annotation libcore.api.IntraCoreApi",
+}
+
+// A library containing the {public SDK + intra-core} API stubs for
+// core-libart.
+java_library {
+    name: "core-libart+oj.intra.stubs",
+    srcs: [":core-libart+oj-intra-stubs"],
+
+    no_standard_libs: true,
+    // We use core.intra.stubs here to prove that we have all the dependencies
+    // needed to compile the libart intra stubs within the intra stubs, i.e.
+    // there are no non-API references.
+    libs: ["core.intra.stubs"],
+    system_modules: "core-intra-stubs-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
diff --git a/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java b/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
new file mode 100644
index 0000000..76c28d8
--- /dev/null
+++ b/mmodules/libart_oj/src/test/java/libcore/test/mmodule/libart/DemoLibartClassTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.test.mmodule.libart;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+import org.junit.Test;
+
+/**
+ * A test for the presence and behavior of {@link DemoLibartClass}.
+ */
+public class DemoLibartClassTest {
+
+    @Test
+    public void classLoader() {
+        Class<?> clazz = DemoLibartClass.class;
+        ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
+
+        // The DemoLibartClass must be loaded by the boot classloader.
+        assertSame(bootClassLoader, clazz.getClassLoader());
+    }
+
+    @Test
+    public void simpleMethod() {
+        assertEquals("Hello World", DemoLibartClass.simpleMethod());
+    }
+
+    @Test
+    public void intraCoreDependencyMethod() {
+        assertEquals("Hello World", DemoLibartClass.intraCoreDependencyMethod());
+    }
+}
diff --git a/mmodules/simple/Android.bp b/mmodules/simple/Android.bp
new file mode 100644
index 0000000..fae8e14
--- /dev/null
+++ b/mmodules/simple/Android.bp
@@ -0,0 +1,128 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+filegroup {
+    name: "core_simple_java_files",
+    srcs: ["src/main/java/**/*.java"]
+}
+
+java_defaults {
+    name: "core-simple-defaults",
+    srcs: [":core_simple_java_files"],
+    installable: true,
+
+    // As a logical part of the set of core libs we cannot use
+    // no_standard_libs: false here because this core jar is one of the
+    // default standard libs and that leads to a cycle.
+    // So, we deliberately compile against core-all to avoid cycles.
+    no_standard_libs: true,
+    libs: ["core-all"],
+    system_modules: "core-all-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+
+    dxflags: ["--core-library"],
+}
+
+// A library containing the implementation of core-simple.
+java_library {
+    name: "core-simple",
+    hostdex: true,
+    defaults: ["core-simple-defaults"],
+}
+
+// A guaranteed unstripped version of core-simple.
+// The build system may or may not strip the core-simple jar
+// but this will not be stripped. See b/24535627.
+java_library {
+    name: "core-simple-testdex",
+    defaults: ["core-simple-defaults"],
+    dex_preopt: {
+        enabled: false,
+    },
+}
+
+// A rule that checks we can build core-simple using only the source for
+// core-simple and the APIs in the core.intra.stubs.
+java_library {
+    name: "core-simple.depscheck",
+    srcs: [":core_simple_java_files"],
+    installable: false,
+
+    no_standard_libs: true,
+    libs: ["core.intra.stubs"],
+    system_modules: "core-intra-stubs-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
+// Tests associated with the core-simple intra-core APIs.
+java_test {
+    name: "core-simple-intra-test",
+    srcs: [ "src/test/java/**/*.java" ],
+
+    no_standard_libs: true,
+    libs: [
+          // We depend on stubs not the impl code. We do not test
+          // internals, just the {public SDK + intra-core} APIs.
+          "core.intra.stubs",
+          // Other deps needed for tests.
+          "junit",
+    ],
+    system_modules: "core-intra-stubs-system-modules",
+}
+
+// Generates stub source files for the {public SDK + intra-core} APIs
+// of core-simple.
+droidstubs {
+    name: "core-simple-intra-stubs",
+    srcs: [":core_simple_java_files"],
+    no_framework_libs: true,
+
+    installable: false,
+    args: "--show-single-annotation libcore.api.IntraCoreApi",
+
+    api_filename: "api.txt",
+    removed_api_filename: "removed.txt",
+    previous_api: "previous.txt",
+    check_api: {
+        current: {
+            api_file: "api/intra/current-api.txt",
+            removed_api_file: "api/intra/current-removed.txt",
+        },
+        last_released: {
+            api_file: "api/intra/last-api.txt",
+            removed_api_file: "api/intra/last-removed.txt",
+        },
+    },
+}
+
+// A library containing the {public SDK + intra-core} API stubs for
+// core-simple.
+java_library {
+    name: "core-simple.intra.stubs",
+    srcs: [":core-simple-intra-stubs"],
+
+    no_standard_libs: true,
+    // We use core.intra.stubs here to prove that we have all the dependencies
+    // needed to compile the simple intra stubs within the intra stubs, i.e.
+    // there are no non-API references.
+    libs: ["core.intra.stubs"],
+    system_modules: "core-intra-stubs-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
diff --git a/mmodules/simple/api/intra/current-api.txt b/mmodules/simple/api/intra/current-api.txt
new file mode 100644
index 0000000..6aa0d7a
--- /dev/null
+++ b/mmodules/simple/api/intra/current-api.txt
@@ -0,0 +1,9 @@
+package libcore.mmodule.simple {
+
+  public class DemoSimpleClass {
+    method public static java.lang.String intraCoreDependencyMethod();
+    method public static java.lang.String simpleMethod();
+  }
+
+}
+
diff --git a/mmodules/simple/api/intra/current-removed.txt b/mmodules/simple/api/intra/current-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/simple/api/intra/current-removed.txt
diff --git a/mmodules/simple/api/intra/last-api.txt b/mmodules/simple/api/intra/last-api.txt
new file mode 100644
index 0000000..6aa0d7a
--- /dev/null
+++ b/mmodules/simple/api/intra/last-api.txt
@@ -0,0 +1,9 @@
+package libcore.mmodule.simple {
+
+  public class DemoSimpleClass {
+    method public static java.lang.String intraCoreDependencyMethod();
+    method public static java.lang.String simpleMethod();
+  }
+
+}
+
diff --git a/mmodules/simple/api/intra/last-removed.txt b/mmodules/simple/api/intra/last-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/simple/api/intra/last-removed.txt
diff --git a/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
new file mode 100644
index 0000000..a6bf475
--- /dev/null
+++ b/mmodules/simple/src/main/java/libcore/mmodule/simple/DemoSimpleClass.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.mmodule.simple;
+
+import libcore.mmodule.libart.DemoLibartClass;
+
+/**
+ * A class that nothing in libcore or the Android framework depends on to provide public SDK
+ * behavior. It is intended for use in a fake installable mmodule. Its presence can be tested for,
+ * the classloader identified and its behavior modified over time to simulate real mmodule code,
+ * without touching any "real" platform logic.
+ *
+ * @hide
+ */
+@libcore.api.IntraCoreApi
+public class DemoSimpleClass {
+
+    private DemoSimpleClass() {}
+
+    /**
+     * A simple method that has no native or data file dependencies but is part of the simple
+     * mmodule's API contract.
+     */
+    @libcore.api.IntraCoreApi
+    public static String simpleMethod() {
+        return "Hello World";
+    }
+
+    /**
+     * A method that depends on another part of the core libraries to work.
+     */
+    @libcore.api.IntraCoreApi // Exposed for tests
+    public static String intraCoreDependencyMethod() {
+        // Delegate to core-libart code to implement the method.
+        return DemoLibartClass.simpleMethod();
+    }
+
+    /**
+     * A method that is public but not part of the simple mmodule's API contract.
+     */
+    public static String hiddenMethod() {
+        return "Hello World";
+    }
+}
diff --git a/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
new file mode 100644
index 0000000..523eed5
--- /dev/null
+++ b/mmodules/simple/src/test/java/libcore/test/mmodule/simple/DemoSimpleClassTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.test.mmodule.simple;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import libcore.mmodule.simple.DemoSimpleClass;
+
+import org.junit.Test;
+
+/**
+ * A test for the presence and behavior of {@link DemoSimpleClass}.
+ */
+public class DemoSimpleClassTest {
+
+    @Test
+    public void classLoader() {
+        Class<?> clazz = DemoSimpleClass.class;
+        ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
+
+        // The DemoSimpleClass must be loaded by the boot classloader.
+        assertSame(bootClassLoader, clazz.getClassLoader());
+    }
+
+    @Test
+    public void simpleMethod() {
+        assertEquals("Hello World", DemoSimpleClass.simpleMethod());
+    }
+
+    @Test
+    public void intraCoreDependencyMethod() {
+        assertEquals("Hello World", DemoSimpleClass.intraCoreDependencyMethod());
+    }
+}
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 929b411..d0b6d3d 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -38,6 +38,7 @@
         "dalvik/src/main/java/dalvik/annotation/TestTarget.java",
         "dalvik/src/main/java/dalvik/annotation/TestTargetClass.java",
         "dalvik/src/main/java/dalvik/annotation/Throws.java",
+        "dalvik/src/main/java/dalvik/annotation/codegen/CovariantReturnType.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java",
@@ -60,6 +61,7 @@
         "dalvik/src/main/java/dalvik/system/NativeStart.java",
         "dalvik/src/main/java/dalvik/system/PathClassLoader.java",
         "dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java",
+        "dalvik/src/main/java/dalvik/system/RuntimeHooks.java",
         "dalvik/src/main/java/dalvik/system/SocketTagger.java",
         "dalvik/src/main/java/dalvik/system/TemporaryDirectory.java",
         "libart/src/main/java/dalvik/system/TransactionAbortError.java",
@@ -154,6 +156,9 @@
         "luni/src/main/java/javax/xml/xpath/XPathFunctionException.java",
         "luni/src/main/java/javax/xml/xpath/XPathFunctionResolver.java",
         "luni/src/main/java/javax/xml/xpath/XPathVariableResolver.java",
+        "luni/src/main/java/libcore/api/CorePlatformApi.java",
+        "luni/src/main/java/libcore/api/IntraCoreApi.java",
+        "luni/src/main/java/libcore/mmodule/libart/DemoLibartClass.java",
         "json/src/main/java/org/json/JSON.java",
         "json/src/main/java/org/json/JSONArray.java",
         "json/src/main/java/org/json/JSONException.java",
@@ -280,7 +285,6 @@
         "luni/src/main/java/libcore/math/MathUtils.java",
         "luni/src/main/java/libcore/net/MimeUtils.java",
         "luni/src/main/java/libcore/net/NetworkSecurityPolicy.java",
-        "luni/src/main/java/libcore/net/UriCodec.java",
         "luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java",
         "luni/src/main/java/libcore/net/event/NetworkEventListener.java",
         "luni/src/main/java/libcore/net/http/HttpDate.java",
@@ -297,6 +301,7 @@
         "luni/src/main/java/libcore/reflect/TypeVariableImpl.java",
         "luni/src/main/java/libcore/reflect/Types.java",
         "luni/src/main/java/libcore/reflect/WildcardTypeImpl.java",
+        "luni/src/main/java/libcore/util/ArrayUtils.java",
         "luni/src/main/java/libcore/util/CharsetUtils.java",
         "luni/src/main/java/libcore/util/EmptyArray.java",
         "luni/src/main/java/libcore/util/BasicLruCache.java",
@@ -304,24 +309,23 @@
         "luni/src/main/java/libcore/util/CountryTimeZones.java",
         "luni/src/main/java/libcore/util/CountryZonesFinder.java",
         "luni/src/main/java/libcore/util/EmptyArray.java",
+        "luni/src/main/java/libcore/util/HexEncoding.java",
         "luni/src/main/java/libcore/util/NativeAllocationRegistry.java",
         "luni/src/main/java/libcore/util/NonNull.java",
         "luni/src/main/java/libcore/util/Nullable.java",
         "luni/src/main/java/libcore/util/NullFromTypeParam.java",
         "luni/src/main/java/libcore/util/Objects.java",
-        "luni/src/main/java/libcore/util/RecoverySystem.java",
         "luni/src/main/java/libcore/util/SneakyThrow.java",
         "luni/src/main/java/libcore/util/TimeZoneDataFiles.java",
         "luni/src/main/java/libcore/util/TimeZoneFinder.java",
+        "luni/src/main/java/libcore/util/XmlObjectFactory.java",
         "luni/src/main/java/libcore/util/ZoneInfo.java",
         "luni/src/main/java/libcore/util/ZoneInfoDB.java",
-        "luni/src/main/java/libcore/util/HexEncoding.java",
         "dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java",
         "dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java",
         "dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java",
         "dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java",
         "dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java",
-        "luni/src/main/java/org/apache/harmony/luni/internal/util/TimezoneGetter.java",
         "luni/src/main/java/org/apache/harmony/xml/ExpatAttributes.java",
         "luni/src/main/java/org/apache/harmony/xml/ExpatException.java",
         "luni/src/main/java/org/apache/harmony/xml/ExpatParser.java",
@@ -352,8 +356,8 @@
         "luni/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java",
         "libart/src/main/java/java/lang/CaseMapper.java",
         "libart/src/main/java/java/lang/StringFactory.java",
-        "xml/src/main/java/org/kxml2/io/KXmlParser.java",
-        "xml/src/main/java/org/kxml2/io/KXmlSerializer.java",
+        "xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java",
+        "xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java",
         ":non_openjdk_javadoc_files",
     ],
 }
diff --git a/ojluni/annotations/README b/ojluni/annotations/README
new file mode 100644
index 0000000..aa7c781
--- /dev/null
+++ b/ojluni/annotations/README
@@ -0,0 +1,16 @@
+This directory contains annotated stub files which can be merged into
+the main source files by metalava when it is producing API stubs. This
+mechanism is used instead of adding the annotations to the main source
+files, to avoid carrying patches against the upstream sources.
+
+Directory structure
+===================
+
+libcore/ojluni/annotations/sdk:
+ - Contains annotations to be included in the public SDK, for example
+   annotations specifying additional details about method contracts.
+
+libcore/ojluni/annotations/sdk/nullability:
+ - Contains annotations to be included in the public SDK specifically
+   relating to nullability. Adding an annotated stub file to this subdirectory
+   will cause the annotations to be validated for correctness and completeness.
diff --git a/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java b/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java
new file mode 100644
index 0000000..531dfb0
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/io/PrintWriter.annotated.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.io;
+
+import java.nio.charset.Charset;
+import java.util.Formatter;
+import java.util.Locale;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PrintWriter extends java.io.Writer {
+
+public PrintWriter(@libcore.util.NonNull java.io.Writer out) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.Writer out, boolean autoFlush) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.OutputStream out) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.OutputStream out, boolean autoFlush) { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.lang.String fileName) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.lang.String fileName, @libcore.util.NonNull java.lang.String csn) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.File file) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public PrintWriter(@libcore.util.NonNull java.io.File file, @libcore.util.NonNull java.lang.String csn) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public void flush() { throw new RuntimeException("Stub!"); }
+
+public void close() { throw new RuntimeException("Stub!"); }
+
+public boolean checkError() { throw new RuntimeException("Stub!"); }
+
+protected void setError() { throw new RuntimeException("Stub!"); }
+
+protected void clearError() { throw new RuntimeException("Stub!"); }
+
+public void write(int c) { throw new RuntimeException("Stub!"); }
+
+public void write(char[] buf, int off, int len) { throw new RuntimeException("Stub!"); }
+
+public void write(char[] buf) { throw new RuntimeException("Stub!"); }
+
+public void write(@libcore.util.NonNull java.lang.String s, int off, int len) { throw new RuntimeException("Stub!"); }
+
+public void write(@libcore.util.NonNull java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public void print(boolean b) { throw new RuntimeException("Stub!"); }
+
+public void print(char c) { throw new RuntimeException("Stub!"); }
+
+public void print(int i) { throw new RuntimeException("Stub!"); }
+
+public void print(long l) { throw new RuntimeException("Stub!"); }
+
+public void print(float f) { throw new RuntimeException("Stub!"); }
+
+public void print(double d) { throw new RuntimeException("Stub!"); }
+
+public void print(char[] s) { throw new RuntimeException("Stub!"); }
+
+public void print(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public void print(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public void println() { throw new RuntimeException("Stub!"); }
+
+public void println(boolean x) { throw new RuntimeException("Stub!"); }
+
+public void println(char x) { throw new RuntimeException("Stub!"); }
+
+public void println(int x) { throw new RuntimeException("Stub!"); }
+
+public void println(long x) { throw new RuntimeException("Stub!"); }
+
+public void println(float x) { throw new RuntimeException("Stub!"); }
+
+public void println(double x) { throw new RuntimeException("Stub!"); }
+
+public void println(char[] x) { throw new RuntimeException("Stub!"); }
+
+public void println(@libcore.util.Nullable java.lang.String x) { throw new RuntimeException("Stub!"); }
+
+public void println(@libcore.util.Nullable java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter printf(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter printf(@libcore.util.Nullable java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter format(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter format(@libcore.util.Nullable java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(@libcore.util.Nullable java.lang.CharSequence csq) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.PrintWriter append(char c) { throw new RuntimeException("Stub!"); }
+
+protected java.io.Writer out;
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
index 011089d..0ef58db 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,18 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang;
 
+import java.io.IOException;
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Appendable {
+
+@libcore.util.NonNull public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq) throws java.io.IOException;
+
+@libcore.util.NonNull public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) throws java.io.IOException;
+
+@libcore.util.NonNull public java.lang.Appendable append(char c) throws java.io.IOException;
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java
new file mode 100644
index 0000000..8022814
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Boolean.annotated.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Boolean implements java.io.Serializable, java.lang.Comparable<java.lang.Boolean> {
+
+public Boolean(boolean value) { throw new RuntimeException("Stub!"); }
+
+public Boolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean parseBoolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public boolean booleanValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Boolean valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Boolean valueOf(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(boolean value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Boolean b) { throw new RuntimeException("Stub!"); }
+
+public static int compare(boolean x, boolean y) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalAnd(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalOr(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalXor(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Boolean FALSE;
+static { FALSE = null; }
+
+public static final java.lang.Boolean TRUE;
+static { TRUE = null; }
+
+public static final java.lang.Class<java.lang.Boolean> TYPE;
+static { TYPE = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java
new file mode 100644
index 0000000..b64ca1e
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Byte.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+
+public Byte(byte value) { throw new RuntimeException("Stub!"); }
+
+public Byte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Byte decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
+
+public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
+
+public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 1; // 0x1
+
+public static final byte MAX_VALUE = 127; // 0x7f
+
+public static final byte MIN_VALUE = -128; // 0xffffff80
+
+public static final int SIZE = 8; // 0x8
+
+public static final java.lang.Class<java.lang.Byte> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
index 011089d..4c82aa8 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,24 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang;
 
+import java.util.stream.IntStream;
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface CharSequence {
+
+public int length();
+
+public char charAt(int index);
+
+public java.lang.CharSequence subSequence(int start, int end);
+
+@libcore.util.NonNull public java.lang.String toString();
+
+public default java.util.stream.IntStream chars() { throw new RuntimeException("Stub!"); }
+
+public default java.util.stream.IntStream codePoints() { throw new RuntimeException("Stub!"); }
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java
new file mode 100644
index 0000000..d50474f
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Character.annotated.java
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.util.Locale;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Character implements java.io.Serializable, java.lang.Comparable<java.lang.Character> {
+
+public Character(char value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+public char charValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(char value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isValidCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isBmpCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSupplementaryCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isHighSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogatePair(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int charCount(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toCodePoint(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index, int limit) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index, int start) { throw new RuntimeException("Stub!"); }
+
+public static char highSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char lowSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toChars(int codePoint, char[] dst, int dstIndex) { throw new RuntimeException("Stub!"); }
+
+public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(@libcore.util.NonNull java.lang.CharSequence seq, int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(char[] a, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(@libcore.util.NonNull java.lang.CharSequence seq, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isAlphabetic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdeographic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int digit(char ch, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int digit(int codePoint, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isSpace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int getType(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getType(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char forDigit(int digit, int radix) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(char ch) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Character anotherCharacter) { throw new RuntimeException("Stub!"); }
+
+public static int compare(char x, char y) { throw new RuntimeException("Stub!"); }
+
+public static char reverseBytes(char ch) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getName(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 2; // 0x2
+
+public static final byte COMBINING_SPACING_MARK = 8; // 0x8
+
+public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
+
+public static final byte CONTROL = 15; // 0xf
+
+public static final byte CURRENCY_SYMBOL = 26; // 0x1a
+
+public static final byte DASH_PUNCTUATION = 20; // 0x14
+
+public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
+
+public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
+
+public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
+
+public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
+
+public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
+
+public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
+
+public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
+
+public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
+
+public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
+
+public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
+
+public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
+
+public static final byte ENCLOSING_MARK = 7; // 0x7
+
+public static final byte END_PUNCTUATION = 22; // 0x16
+
+public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
+
+public static final byte FORMAT = 16; // 0x10
+
+public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
+
+public static final byte LETTER_NUMBER = 10; // 0xa
+
+public static final byte LINE_SEPARATOR = 13; // 0xd
+
+public static final byte LOWERCASE_LETTER = 2; // 0x2
+
+public static final byte MATH_SYMBOL = 25; // 0x19
+
+public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
+
+public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
+
+public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final int MAX_RADIX = 36; // 0x24
+
+public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
+
+public static final int MIN_CODE_POINT = 0; // 0x0
+
+public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
+
+public static final int MIN_RADIX = 2; // 0x2
+
+public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
+
+public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
+
+public static final byte MODIFIER_LETTER = 4; // 0x4
+
+public static final byte MODIFIER_SYMBOL = 27; // 0x1b
+
+public static final byte NON_SPACING_MARK = 6; // 0x6
+
+public static final byte OTHER_LETTER = 5; // 0x5
+
+public static final byte OTHER_NUMBER = 11; // 0xb
+
+public static final byte OTHER_PUNCTUATION = 24; // 0x18
+
+public static final byte OTHER_SYMBOL = 28; // 0x1c
+
+public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
+
+public static final byte PRIVATE_USE = 18; // 0x12
+
+public static final int SIZE = 16; // 0x10
+
+public static final byte SPACE_SEPARATOR = 12; // 0xc
+
+public static final byte START_PUNCTUATION = 21; // 0x15
+
+public static final byte SURROGATE = 19; // 0x13
+
+public static final byte TITLECASE_LETTER = 3; // 0x3
+
+public static final java.lang.Class<java.lang.Character> TYPE;
+static { TYPE = null; }
+
+public static final byte UNASSIGNED = 0; // 0x0
+
+public static final byte UPPERCASE_LETTER = 1; // 0x1
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Subset {
+
+protected Subset(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class UnicodeBlock extends java.lang.Character.Subset {
+
+UnicodeBlock(java.lang.String idName) { super(null); throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Character.UnicodeBlock of(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Character.UnicodeBlock of(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeBlock forName(@libcore.util.NonNull java.lang.String blockName) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+static { AEGEAN_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
+static { ALCHEMICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+static { ALPHABETIC_PRESENTATION_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+static { ANCIENT_GREEK_MUSICAL_NOTATION = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+static { ANCIENT_GREEK_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
+static { ANCIENT_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC;
+static { ARABIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
+static { ARABIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
+static { ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
+static { ARABIC_PRESENTATION_FORMS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+static { ARABIC_PRESENTATION_FORMS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
+static { ARABIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ARMENIAN;
+static { ARMENIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock ARROWS;
+static { ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock AVESTAN;
+static { AVESTAN = null; }
+
+public static final java.lang.Character.UnicodeBlock BALINESE;
+static { BALINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM;
+static { BAMUM = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
+static { BAMUM_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+static { BASIC_LATIN = null; }
+
+public static final java.lang.Character.UnicodeBlock BATAK;
+static { BATAK = null; }
+
+public static final java.lang.Character.UnicodeBlock BENGALI;
+static { BENGALI = null; }
+
+public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
+static { BLOCK_ELEMENTS = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO;
+static { BOPOMOFO = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
+static { BOPOMOFO_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+static { BOX_DRAWING = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAHMI;
+static { BRAHMI = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+static { BRAILLE_PATTERNS = null; }
+
+public static final java.lang.Character.UnicodeBlock BUGINESE;
+static { BUGINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BUHID;
+static { BUHID = null; }
+
+public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+static { BYZANTINE_MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CARIAN;
+static { CARIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAKMA;
+static { CHAKMA = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAM;
+static { CHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock CHEROKEE;
+static { CHEROKEE = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
+static { CJK_COMPATIBILITY = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
+static { CJK_COMPATIBILITY_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
+static { CJK_COMPATIBILITY_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+static { CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+static { CJK_RADICALS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_STROKES;
+static { CJK_STROKES = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
+static { CJK_SYMBOLS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
+static { CJK_UNIFIED_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+static { COMBINING_DIACRITICAL_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
+static { COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
+static { COMBINING_HALF_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+static { COMBINING_MARKS_FOR_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
+static { COMMON_INDIC_NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+static { CONTROL_PICTURES = null; }
+
+public static final java.lang.Character.UnicodeBlock COPTIC;
+static { COPTIC = null; }
+
+public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+static { COUNTING_ROD_NUMERALS = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+static { CUNEIFORM = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
+static { CUNEIFORM_NUMBERS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
+static { CURRENCY_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
+static { CYPRIOT_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC;
+static { CYRILLIC = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+static { CYRILLIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
+static { CYRILLIC_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
+static { CYRILLIC_SUPPLEMENTARY = null; }
+
+public static final java.lang.Character.UnicodeBlock DESERET;
+static { DESERET = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+static { DEVANAGARI = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
+static { DEVANAGARI_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock DINGBATS;
+static { DINGBATS = null; }
+
+public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+static { DOMINO_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+static { EGYPTIAN_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock EMOTICONS;
+static { EMOTICONS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+static { ENCLOSED_ALPHANUMERICS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
+static { ENCLOSED_ALPHANUMERIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+static { ENCLOSED_CJK_LETTERS_AND_MONTHS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
+static { ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+static { ETHIOPIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+static { ETHIOPIC_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+static { ETHIOPIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
+static { ETHIOPIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
+static { GENERAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
+static { GEOMETRIC_SHAPES = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN;
+static { GEORGIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+static { GEORGIAN_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
+static { GLAGOLITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GOTHIC;
+static { GOTHIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK;
+static { GREEK = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
+static { GREEK_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock GUJARATI;
+static { GUJARATI = null; }
+
+public static final java.lang.Character.UnicodeBlock GURMUKHI;
+static { GURMUKHI = null; }
+
+public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
+static { HALFWIDTH_AND_FULLWIDTH_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
+static { HANGUL_COMPATIBILITY_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+static { HANGUL_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+static { HANGUL_JAMO_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
+static { HANGUL_JAMO_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
+static { HANGUL_SYLLABLES = null; }
+
+public static final java.lang.Character.UnicodeBlock HANUNOO;
+static { HANUNOO = null; }
+
+public static final java.lang.Character.UnicodeBlock HEBREW;
+static { HEBREW = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
+static { HIGH_PRIVATE_USE_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
+static { HIGH_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIRAGANA;
+static { HIRAGANA = null; }
+
+public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+static { IDEOGRAPHIC_DESCRIPTION_CHARACTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+static { IMPERIAL_ARAMAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+static { INSCRIPTIONAL_PAHLAVI = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
+static { INSCRIPTIONAL_PARTHIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+static { IPA_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock JAVANESE;
+static { JAVANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock KAITHI;
+static { KAITHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
+static { KANA_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock KANBUN;
+static { KANBUN = null; }
+
+public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
+static { KANGXI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock KANNADA;
+static { KANNADA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA;
+static { KATAKANA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+static { KATAKANA_PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+static { KAYAH_LI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
+static { KHAROSHTHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER;
+static { KHMER = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
+static { KHMER_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LAO;
+static { LAO = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
+static { LATIN_1_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
+static { LATIN_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
+static { LATIN_EXTENDED_ADDITIONAL = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+static { LATIN_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+static { LATIN_EXTENDED_C = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+static { LATIN_EXTENDED_D = null; }
+
+public static final java.lang.Character.UnicodeBlock LEPCHA;
+static { LEPCHA = null; }
+
+public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
+static { LETTERLIKE_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LIMBU;
+static { LIMBU = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
+static { LINEAR_B_IDEOGRAMS = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+static { LINEAR_B_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock LISU;
+static { LISU = null; }
+
+public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+static { LOW_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock LYCIAN;
+static { LYCIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock LYDIAN;
+static { LYDIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
+static { MAHJONG_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock MALAYALAM;
+static { MALAYALAM = null; }
+
+public static final java.lang.Character.UnicodeBlock MANDAIC;
+static { MANDAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+static { MATHEMATICAL_ALPHANUMERIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+static { MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
+static { MEETEI_MAYEK = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
+static { MEETEI_MAYEK_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
+static { MEROITIC_CURSIVE = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
+static { MEROITIC_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MIAO;
+static { MIAO = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
+static { MISCELLANEOUS_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+static { MISCELLANEOUS_SYMBOLS_AND_ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
+static { MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+static { MISCELLANEOUS_TECHNICAL = null; }
+
+public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
+static { MODIFIER_TONE_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock MONGOLIAN;
+static { MONGOLIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
+static { MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR;
+static { MYANMAR = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+static { MYANMAR_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+static { NEW_TAI_LUE = null; }
+
+public static final java.lang.Character.UnicodeBlock NKO;
+static { NKO = null; }
+
+public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
+static { NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock OGHAM;
+static { OGHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+static { OLD_ITALIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+static { OLD_PERSIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+static { OLD_SOUTH_ARABIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+static { OLD_TURKIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OL_CHIKI;
+static { OL_CHIKI = null; }
+
+public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
+static { OPTICAL_CHARACTER_RECOGNITION = null; }
+
+public static final java.lang.Character.UnicodeBlock ORIYA;
+static { ORIYA = null; }
+
+public static final java.lang.Character.UnicodeBlock OSMANYA;
+static { OSMANYA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+static { PHAGS_PA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+static { PHAISTOS_DISC = null; }
+
+public static final java.lang.Character.UnicodeBlock PHOENICIAN;
+static { PHOENICIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+static { PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+static { PHONETIC_EXTENSIONS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
+static { PLAYING_CARDS = null; }
+
+public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+static { PRIVATE_USE_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock REJANG;
+static { REJANG = null; }
+
+public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
+static { RUMI_NUMERAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock RUNIC;
+static { RUNIC = null; }
+
+public static final java.lang.Character.UnicodeBlock SAMARITAN;
+static { SAMARITAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SAURASHTRA;
+static { SAURASHTRA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHARADA;
+static { SHARADA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHAVIAN;
+static { SHAVIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SINHALA;
+static { SINHALA = null; }
+
+public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
+static { SMALL_FORM_VARIANTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
+static { SORA_SOMPENG = null; }
+
+public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
+static { SPACING_MODIFIER_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock SPECIALS;
+static { SPECIALS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE;
+static { SUNDANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
+static { SUNDANESE_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
+static { SUPERSCRIPTS_AND_SUBSCRIPTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
+static { SUPPLEMENTAL_ARROWS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
+static { SUPPLEMENTAL_ARROWS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+static { SUPPLEMENTAL_MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
+static { SUPPLEMENTAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_B = null; }
+
+@Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
+static { SURROGATES_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
+static { SYLOTI_NAGRI = null; }
+
+public static final java.lang.Character.UnicodeBlock SYRIAC;
+static { SYRIAC = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGALOG;
+static { TAGALOG = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGBANWA;
+static { TAGBANWA = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGS;
+static { TAGS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_LE;
+static { TAI_LE = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_THAM;
+static { TAI_THAM = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_VIET;
+static { TAI_VIET = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
+static { TAI_XUAN_JING_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAKRI;
+static { TAKRI = null; }
+
+public static final java.lang.Character.UnicodeBlock TAMIL;
+static { TAMIL = null; }
+
+public static final java.lang.Character.UnicodeBlock TELUGU;
+static { TELUGU = null; }
+
+public static final java.lang.Character.UnicodeBlock THAANA;
+static { THAANA = null; }
+
+public static final java.lang.Character.UnicodeBlock THAI;
+static { THAI = null; }
+
+public static final java.lang.Character.UnicodeBlock TIBETAN;
+static { TIBETAN = null; }
+
+public static final java.lang.Character.UnicodeBlock TIFINAGH;
+static { TIFINAGH = null; }
+
+public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
+static { TRANSPORT_AND_MAP_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock UGARITIC;
+static { UGARITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock VAI;
+static { VAI = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
+static { VARIATION_SELECTORS = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+static { VARIATION_SELECTORS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+static { VEDIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
+static { VERTICAL_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
+static { YIJING_HEXAGRAM_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_RADICALS;
+static { YI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
+static { YI_SYLLABLES = null; }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum UnicodeScript {
+COMMON,
+LATIN,
+GREEK,
+CYRILLIC,
+ARMENIAN,
+HEBREW,
+ARABIC,
+SYRIAC,
+THAANA,
+DEVANAGARI,
+BENGALI,
+GURMUKHI,
+GUJARATI,
+ORIYA,
+TAMIL,
+TELUGU,
+KANNADA,
+MALAYALAM,
+SINHALA,
+THAI,
+LAO,
+TIBETAN,
+MYANMAR,
+GEORGIAN,
+HANGUL,
+ETHIOPIC,
+CHEROKEE,
+CANADIAN_ABORIGINAL,
+OGHAM,
+RUNIC,
+KHMER,
+MONGOLIAN,
+HIRAGANA,
+KATAKANA,
+BOPOMOFO,
+HAN,
+YI,
+OLD_ITALIC,
+GOTHIC,
+DESERET,
+INHERITED,
+TAGALOG,
+HANUNOO,
+BUHID,
+TAGBANWA,
+LIMBU,
+TAI_LE,
+LINEAR_B,
+UGARITIC,
+SHAVIAN,
+OSMANYA,
+CYPRIOT,
+BRAILLE,
+BUGINESE,
+COPTIC,
+NEW_TAI_LUE,
+GLAGOLITIC,
+TIFINAGH,
+SYLOTI_NAGRI,
+OLD_PERSIAN,
+KHAROSHTHI,
+BALINESE,
+CUNEIFORM,
+PHOENICIAN,
+PHAGS_PA,
+NKO,
+SUNDANESE,
+BATAK,
+LEPCHA,
+OL_CHIKI,
+VAI,
+SAURASHTRA,
+KAYAH_LI,
+REJANG,
+LYCIAN,
+CARIAN,
+LYDIAN,
+CHAM,
+TAI_THAM,
+TAI_VIET,
+AVESTAN,
+EGYPTIAN_HIEROGLYPHS,
+SAMARITAN,
+MANDAIC,
+LISU,
+BAMUM,
+JAVANESE,
+MEETEI_MAYEK,
+IMPERIAL_ARAMAIC,
+OLD_SOUTH_ARABIAN,
+INSCRIPTIONAL_PARTHIAN,
+INSCRIPTIONAL_PAHLAVI,
+OLD_TURKIC,
+BRAHMI,
+KAITHI,
+MEROITIC_HIEROGLYPHS,
+MEROITIC_CURSIVE,
+SORA_SOMPENG,
+CHAKMA,
+SHARADA,
+TAKRI,
+MIAO,
+UNKNOWN;
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeScript of(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Character.UnicodeScript forName(@libcore.util.NonNull java.lang.String scriptName) { throw new RuntimeException("Stub!"); }
+}
+
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
new file mode 100644
index 0000000..dfbbd9b
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.TypeVariable;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.io.InputStream;
+import java.util.HashMap;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Class<T> implements java.io.Serializable, java.lang.reflect.GenericDeclaration, java.lang.reflect.Type, java.lang.reflect.AnnotatedElement {
+
+Class() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> forName(@libcore.util.NonNull java.lang.String className) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> forName(@libcore.util.NonNull java.lang.String name, boolean initialize, @libcore.util.Nullable java.lang.ClassLoader loader) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+public boolean isInstance(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isAssignableFrom(@libcore.util.NonNull java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); }
+
+public boolean isInterface() { throw new RuntimeException("Stub!"); }
+
+public boolean isArray() { throw new RuntimeException("Stub!"); }
+
+public boolean isPrimitive() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotation() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.ClassLoader getClassLoader() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.reflect.@libcore.util.NonNull TypeVariable<java.lang.@libcore.util.NonNull Class<T>> @libcore.util.NonNull [] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Class<? super T> getSuperclass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Type getGenericSuperclass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericInterfaces() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Class<?> getComponentType() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Object @libcore.util.Nullable [] getSigners() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Method getEnclosingMethod() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.reflect.Constructor<?> getEnclosingConstructor() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public native java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.Nullable public native java.lang.Class<?> getEnclosingClass();
+
+@libcore.util.NonNull public java.lang.String getSimpleName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getCanonicalName() { throw new RuntimeException("Stub!"); }
+
+public native boolean isAnonymousClass();
+
+public boolean isLocalClass() { throw new RuntimeException("Stub!"); }
+
+public boolean isMemberClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getClasses() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Field @libcore.util.NonNull [] getFields() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Method @libcore.util.NonNull [] getMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Constructor<?> @libcore.util.NonNull [] getConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Field getField(@libcore.util.NonNull java.lang.String name) throws java.lang.NoSuchFieldException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Method getMethod(@libcore.util.NonNull java.lang.String name, java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Constructor<T> getConstructor(java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getDeclaredClasses();
+
+public native java.lang.reflect.@libcore.util.NonNull Field @libcore.util.NonNull [] getDeclaredFields();
+
+public java.lang.reflect.@libcore.util.NonNull Method @libcore.util.NonNull [] getDeclaredMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Constructor<?> @libcore.util.NonNull [] getDeclaredConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.reflect.Field getDeclaredField(@libcore.util.NonNull java.lang.String name) throws java.lang.NoSuchFieldException;
+
+@libcore.util.NonNull public java.lang.reflect.Method getDeclaredMethod(@libcore.util.NonNull java.lang.String name, java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(java.lang.@libcore.util.NonNull Class<?> @libcore.util.Nullable ... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.io.InputStream getResourceAsStream(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.net.URL getResource(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.security.ProtectionDomain getProtectionDomain() { throw new RuntimeException("Stub!"); }
+
+public boolean desiredAssertionStatus() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnum() { throw new RuntimeException("Stub!"); }
+
+// TODO: Make return type @NonNull T @Nullable [] once metalava supports TYPE_USE.
+public T @libcore.util.Nullable [] getEnumConstants() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public T cast(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public <U> java.lang.Class<? extends U> asSubclass(@libcore.util.NonNull java.lang.Class<U> clazz) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A getAnnotation(@libcore.util.NonNull java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> @libcore.util.NonNull A @libcore.util.NonNull [] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public native <A extends java.lang.annotation.Annotation> @libcore.util.Nullable A getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<A> annotationClass);
+
+public native java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java
new file mode 100644
index 0000000..8f565fc
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Double.annotated.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
+
+public Double(double value) { throw new RuntimeException("Stub!"); }
+
+public Double(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Double valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Double valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+public static double parseDouble(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(double d) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(double value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static long doubleToLongBits(double value) { throw new RuntimeException("Stub!"); }
+
+public static native long doubleToRawLongBits(double value);
+
+public static native double longBitsToDouble(long bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Double anotherDouble) { throw new RuntimeException("Stub!"); }
+
+public static int compare(double d1, double d2) { throw new RuntimeException("Stub!"); }
+
+public static double sum(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final int MAX_EXPONENT = 1023; // 0x3ff
+
+public static final double MAX_VALUE = 1.7976931348623157E308;
+
+public static final int MIN_EXPONENT = -1022; // 0xfffffc02
+
+public static final double MIN_NORMAL = 2.2250738585072014E-308;
+
+public static final double MIN_VALUE = 4.9E-324;
+
+public static final double NEGATIVE_INFINITY = (-1.0/0.0);
+
+public static final double NaN = (0.0/0.0);
+
+public static final double POSITIVE_INFINITY = (1.0/0.0);
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Double> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java
new file mode 100644
index 0000000..75c7662
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E>, java.io.Serializable {
+
+protected Enum(java.lang.String name, int ordinal) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String name() { throw new RuntimeException("Stub!"); }
+
+public final int ordinal() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(java.lang.Object other) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
+protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public final int compareTo(E o) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.Class<E> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+public static <T extends java.lang.Enum<T>> T valueOf(java.lang.Class<T> enumType, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+protected final void finalize() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java
new file mode 100644
index 0000000..a459ec1
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Float.annotated.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
+
+public Float(float value) { throw new RuntimeException("Stub!"); }
+
+public Float(double value) { throw new RuntimeException("Stub!"); }
+
+public Float(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Float valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Float valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+public static float parseFloat(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(float f) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(float value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static int floatToIntBits(float value) { throw new RuntimeException("Stub!"); }
+
+public static native int floatToRawIntBits(float value);
+
+public static native float intBitsToFloat(int bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Float anotherFloat) { throw new RuntimeException("Stub!"); }
+
+public static int compare(float f1, float f2) { throw new RuntimeException("Stub!"); }
+
+public static float sum(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_EXPONENT = 127; // 0x7f
+
+public static final float MAX_VALUE = 3.4028235E38f;
+
+public static final int MIN_EXPONENT = -126; // 0xffffff82
+
+public static final float MIN_NORMAL = 1.17549435E-38f;
+
+public static final float MIN_VALUE = 1.4E-45f;
+
+public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
+
+public static final float NaN = (0.0f/0.0f);
+
+public static final float POSITIVE_INFINITY = (1.0f/0.0f);
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Float> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java
new file mode 100644
index 0000000..d3f6753
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Integer.annotated.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
+
+public Integer(int value) { throw new RuntimeException("Stub!"); }
+
+public Integer(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toOctalString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toBinaryString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(int i) { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(int value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, int val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Integer val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Integer decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Integer anotherInteger) { throw new RuntimeException("Stub!"); }
+
+public static int compare(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(int x) { throw new RuntimeException("Stub!"); }
+
+public static int divideUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int remainderUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int highestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int lowestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(int i) { throw new RuntimeException("Stub!"); }
+
+public static int rotateLeft(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int rotateRight(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int reverse(int i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(int i) { throw new RuntimeException("Stub!"); }
+
+public static int reverseBytes(int i) { throw new RuntimeException("Stub!"); }
+
+public static int sum(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+
+public static final int MIN_VALUE = -2147483648; // 0x80000000
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Integer> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
index 011089d..b331a7a 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,23 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+package java.lang;
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import libcore.util.NonNull;
+import libcore.util.NullFromTypeParam;
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+public interface Iterable<T> {
 
-
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+  public @NonNull Iterator<@NullFromTypeParam T> iterator();
+  public default void forEach(Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+  public default Spliterator<T> spliterator() { throw new RuntimeException("Stub!"); }
 }
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java
new file mode 100644
index 0000000..b077ef5
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Long.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.math.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
+
+public Long(long value) { throw new RuntimeException("Stub!"); }
+
+public Long(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toHexString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toOctalString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toBinaryString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(long i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toUnsignedString(long i) { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long valueOf(long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Long decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(long value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, long val) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Long val) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Long anotherLong) { throw new RuntimeException("Stub!"); }
+
+public static int compare(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static long divideUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long remainderUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long highestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static long lowestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(long i) { throw new RuntimeException("Stub!"); }
+
+public static long rotateLeft(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long rotateRight(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long reverse(long i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(long i) { throw new RuntimeException("Stub!"); }
+
+public static long reverseBytes(long i) { throw new RuntimeException("Stub!"); }
+
+public static long sum(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
+
+public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Long> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java
new file mode 100644
index 0000000..61c4fd1
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Object {
+
+public Object() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.Class<?> getClass() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final native void notify();
+
+public final native void notifyAll();
+
+public final void wait(long timeout) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final native void wait(long timeout, int nanos) throws java.lang.InterruptedException;
+
+public final void wait() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected void finalize() throws java.lang.Throwable { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java
new file mode 100644
index 0000000..a8cf1de
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/String.annotated.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.StringJoiner;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Comparator;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
+
+public String() { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.String original) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public String(int[] codePoints, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuffer buffer) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuilder builder) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public native char charAt(int index);
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object anObject) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+
+public boolean equalsIgnoreCase(@libcore.util.Nullable java.lang.String anotherString) { throw new RuntimeException("Stub!"); }
+
+public native int compareTo(@libcore.util.NonNull java.lang.String anotherString);
+
+public int compareToIgnoreCase(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(boolean ignoreCase, int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix, int toffset) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix) { throw new RuntimeException("Stub!"); }
+
+public boolean endsWith(@libcore.util.NonNull java.lang.String suffix) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String substring(int beginIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String substring(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.CharSequence subSequence(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.String concat(@libcore.util.NonNull java.lang.String str);
+
+@libcore.util.NonNull public java.lang.String replace(char oldChar, char newChar) { throw new RuntimeException("Stub!"); }
+
+public boolean matches(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.NonNull java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceFirst(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceAll(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replace(@libcore.util.NonNull java.lang.CharSequence target, @libcore.util.NonNull java.lang.CharSequence replacement) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex, int limit) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, java.lang.@libcore.util.NonNull CharSequence @libcore.util.Nullable ... elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, @libcore.util.NonNull java.lang.Iterable<? extends @libcore.util.Nullable java.lang.CharSequence> elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toLowerCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toLowerCase() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toUpperCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toUpperCase() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String trim() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public native char[] toCharArray();
+
+@libcore.util.NonNull public static java.lang.String format(@libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String format(@libcore.util.NonNull java.util.Locale l, @libcore.util.NonNull java.lang.String format, java.lang.@libcore.util.Nullable Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String copyValueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String copyValueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.String intern();
+
+public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+static { CASE_INSENSITIVE_ORDER = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java
new file mode 100644
index 0000000..4baff67
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/StringBuffer.annotated.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuffer implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuffer() { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+public synchronized int length() { throw new RuntimeException("Stub!"); }
+
+public synchronized int capacity() { throw new RuntimeException("Stub!"); }
+
+public synchronized void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public synchronized void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public synchronized char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public synchronized int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public synchronized void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(long lng) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer append(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.StringBuffer reverse() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java
new file mode 100644
index 0000000..9ec4039
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/StringBuilder.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuilder implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuilder() { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(long lng) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder append(double d) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuilder reverse() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
+public java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public int capacity() { throw new RuntimeException("Stub!"); }
+
+public void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java
new file mode 100644
index 0000000..82e62b8
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/System.annotated.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.io.*;
+import java.nio.channels.spi.SelectorProvider;
+import java.nio.channels.Channel;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class System {
+
+System() { throw new RuntimeException("Stub!"); }
+
+public static void setIn(@libcore.util.Nullable java.io.InputStream in) { throw new RuntimeException("Stub!"); }
+
+public static void setOut(@libcore.util.Nullable java.io.PrintStream out) { throw new RuntimeException("Stub!"); }
+
+public static void setErr(@libcore.util.Nullable java.io.PrintStream err) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.io.Console console() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static void setSecurityManager(@libcore.util.Nullable java.lang.SecurityManager s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.SecurityManager getSecurityManager() { throw new RuntimeException("Stub!"); }
+
+public static native long currentTimeMillis();
+
+public static native long nanoTime();
+
+public static native void arraycopy(@libcore.util.NonNull java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+public static int identityHashCode(@libcore.util.Nullable java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Properties getProperties() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String lineSeparator() { throw new RuntimeException("Stub!"); }
+
+public static void setProperties(@libcore.util.Nullable java.util.Properties props) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getProperty(@libcore.util.NonNull java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getProperty(@libcore.util.NonNull java.lang.String key, @libcore.util.Nullable java.lang.String def) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String setProperty(@libcore.util.NonNull java.lang.String key, @libcore.util.Nullable java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String clearProperty(@libcore.util.NonNull java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String getenv(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.String,java.lang.String> getenv() { throw new RuntimeException("Stub!"); }
+
+public static void exit(int status) { throw new RuntimeException("Stub!"); }
+
+public static void gc() { throw new RuntimeException("Stub!"); }
+
+public static void runFinalization() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static void runFinalizersOnExit(boolean value) { throw new RuntimeException("Stub!"); }
+
+public static void load(@libcore.util.NonNull java.lang.String filename) { throw new RuntimeException("Stub!"); }
+
+public static void loadLibrary(@libcore.util.NonNull java.lang.String libname) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static native java.lang.String mapLibraryName(@libcore.util.NonNull java.lang.String libname);
+
+public static final java.io.PrintStream err;
+static { err = null; }
+
+public static final java.io.InputStream in;
+static { in = null; }
+
+public static final java.io.PrintStream out;
+static { out = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java
new file mode 100644
index 0000000..27a0114
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.Map;
+import java.util.concurrent.locks.LockSupport;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Thread implements java.lang.Runnable {
+
+public Thread() { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name, long stackSize) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static native java.lang.Thread currentThread();
+
+public static native void yield();
+
+public static void sleep(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void sleep(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public synchronized void start() { throw new RuntimeException("Stub!"); }
+
+public void run() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void stop() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final synchronized void stop(java.lang.Throwable obj) { throw new RuntimeException("Stub!"); }
+
+public void interrupt() { throw new RuntimeException("Stub!"); }
+
+public static native boolean interrupted();
+
+public native boolean isInterrupted();
+
+@Deprecated public void destroy() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAlive() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void suspend() { throw new RuntimeException("Stub!"); }
+
+@Deprecated public final void resume() { throw new RuntimeException("Stub!"); }
+
+public final void setPriority(int newPriority) { throw new RuntimeException("Stub!"); }
+
+public final int getPriority() { throw new RuntimeException("Stub!"); }
+
+public final synchronized void setName(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.ThreadGroup getThreadGroup() { throw new RuntimeException("Stub!"); }
+
+public static int activeCount() { throw new RuntimeException("Stub!"); }
+
+public static int enumerate(java.lang.Thread[] tarray) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public int countStackFrames() { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void dumpStack() { throw new RuntimeException("Stub!"); }
+
+public final void setDaemon(boolean on) { throw new RuntimeException("Stub!"); }
+
+public final boolean isDaemon() { throw new RuntimeException("Stub!"); }
+
+public final void checkAccess() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getContextClassLoader() { throw new RuntimeException("Stub!"); }
+
+public void setContextClassLoader(java.lang.ClassLoader cl) { throw new RuntimeException("Stub!"); }
+
+public static native boolean holdsLock(java.lang.Object obj);
+
+public java.lang.StackTraceElement[] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces() { throw new RuntimeException("Stub!"); }
+
+public long getId() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.State getState() { throw new RuntimeException("Stub!"); }
+
+public static void setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public void setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static final int MAX_PRIORITY = 10; // 0xa
+
+public static final int MIN_PRIORITY = 1; // 0x1
+
+public static final int NORM_PRIORITY = 5; // 0x5
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum State {
+NEW,
+RUNNABLE,
+BLOCKED,
+WAITING,
+TIMED_WAITING,
+TERMINATED;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+@java.lang.FunctionalInterface
+public static interface UncaughtExceptionHandler {
+
+public void uncaughtException(java.lang.Thread t, java.lang.Throwable e);
+}
+
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java
new file mode 100644
index 0000000..3b7e93a
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/ThreadLocal.annotated.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang;
+
+import java.lang.ref.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocal<T> {
+
+public ThreadLocal() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable protected T initialValue() { throw new RuntimeException("Stub!"); }
+
+public static <S> java.lang.ThreadLocal<S> withInitial(@libcore.util.NonNull java.util.function.Supplier<? extends S> supplier) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public T get() { throw new RuntimeException("Stub!"); }
+
+public void set(@libcore.util.NullFromTypeParam T value) { throw new RuntimeException("Stub!"); }
+
+public void remove() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java
new file mode 100644
index 0000000..4846fc7
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/AccessibleObject.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
+
+protected AccessibleObject() { throw new RuntimeException("Stub!"); }
+
+public static void setAccessible(java.lang.reflect.AccessibleObject[] array, boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public void setAccessible(boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java
new file mode 100644
index 0000000..b6f67b7
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/AnnotatedElement.annotated.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface AnnotatedElement {
+
+public default boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass);
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations();
+
+public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java
new file mode 100644
index 0000000..fb09931
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Array {
+
+Array() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newInstance(java.lang.Class<?> componentType, int length) throws java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newInstance(java.lang.Class<?> componentType, int... dimensions) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+public static int getLength(java.lang.Object array) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Object get(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static byte getByte(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static char getChar(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static short getShort(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static int getInt(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static long getLong(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static float getFloat(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static double getDouble(java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void set(java.lang.Object array, int index, java.lang.Object value) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setBoolean(java.lang.Object array, int index, boolean z) { throw new RuntimeException("Stub!"); }
+
+public static void setByte(java.lang.Object array, int index, byte b) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setChar(java.lang.Object array, int index, char c) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setShort(java.lang.Object array, int index, short s) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setInt(java.lang.Object array, int index, int i) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setLong(java.lang.Object array, int index, long l) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setFloat(java.lang.Object array, int index, float f) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setDouble(java.lang.Object array, int index, double d) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java
new file mode 100644
index 0000000..2ebfbe6
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Constructor.annotated.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Constructor<T> extends java.lang.reflect.Executable {
+
+Constructor() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<T> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getExceptionTypes();
+
+public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public T newInstance(java.lang.Object... initargs) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java
new file mode 100644
index 0000000..dade51c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Executable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member, java.lang.reflect.GenericDeclaration {
+
+Executable() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.NonNull public abstract java.lang.String getName();
+
+public abstract int getModifiers();
+
+public abstract java.lang.reflect.@libcore.util.NonNull TypeVariable<?> @libcore.util.NonNull [] getTypeParameters();
+
+public abstract java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getParameterTypes();
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.@libcore.util.NonNull Parameter @libcore.util.NonNull [] getParameters() { throw new RuntimeException("Stub!"); }
+
+public abstract java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] getExceptionTypes();
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.String toGenericString();
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public abstract java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] @libcore.util.NonNull [] getParameterAnnotations();
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java
new file mode 100644
index 0000000..d212353
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
+
+Field() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnumConstant() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type getGenericType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object get(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native boolean getBoolean(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native byte getByte(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native char getChar(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native short getShort(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native int getInt(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native long getLong(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native float getFloat(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native double getDouble(java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void set(java.lang.Object obj, java.lang.Object value) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setBoolean(java.lang.Object obj, boolean z) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setByte(java.lang.Object obj, byte b) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setChar(java.lang.Object obj, char c) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setShort(java.lang.Object obj, short s) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setInt(java.lang.Object obj, int i) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setLong(java.lang.Object obj, long l) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setFloat(java.lang.Object obj, float f) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setDouble(java.lang.Object obj, double d) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
index 011089d..c173408 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,13 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericArrayType extends java.lang.reflect.Type {
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericComponentType();
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
index 011089d..3614d84 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,13 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+
+@libcore.util.NonNull public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
index 011089d..0552ce2 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,23 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Member {
+
+@libcore.util.NonNull public java.lang.Class<?> getDeclaringClass();
+
+@libcore.util.NonNull public java.lang.String getName();
+
+public int getModifiers();
+
+public boolean isSynthetic();
+
+public static final int DECLARED = 1; // 0x1
+
+public static final int PUBLIC = 0; // 0x0
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java
new file mode 100644
index 0000000..1c37b2e
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Method extends java.lang.reflect.Executable {
+
+Method() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getReturnType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericReturnType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?>[] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public native java.lang.Class<?>[] getExceptionTypes();
+
+@libcore.util.NonNull public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object invoke(java.lang.Object obj, java.lang.Object... args) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+
+public boolean isBridge() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isDefault() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Object getDefaultValue();
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java
new file mode 100644
index 0000000..5d7ddb6
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Parameter.annotated.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+import java.lang.annotation.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Parameter implements java.lang.reflect.AnnotatedElement {
+
+Parameter(java.lang.String name, int modifiers, java.lang.reflect.Executable executable, int index) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean isNamePresent() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Executable getDeclaringExecutable() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type getParameterizedType() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public boolean isImplicit() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.@libcore.util.NonNull Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
similarity index 65%
rename from ojluni/src/main/native/String.c
rename to ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
index 011089d..6d72f3f 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,16 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface ParameterizedType extends java.lang.reflect.Type {
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getActualTypeArguments();
+
+@libcore.util.NonNull public java.lang.reflect.Type getRawType();
+
+public java.lang.reflect.Type getOwnerType();
 }
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java
new file mode 100644
index 0000000..781308d
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.lang.reflect;
+
+import java.security.Permission;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy implements java.io.Serializable {
+
+protected Proxy(java.lang.reflect.InvocationHandler h) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> getProxyClass(java.lang.ClassLoader loader, java.lang.Class<?>... interfaces) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newProxyInstance(java.lang.ClassLoader loader, java.lang.Class<?>[] interfaces, java.lang.reflect.InvocationHandler h) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean isProxyClass(java.lang.Class<?> cl) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(java.lang.Object proxy) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.reflect.InvocationHandler h;
+}
+
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
index 011089d..f2b646b 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,13 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Type {
+
+@libcore.util.NonNull public default java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
 }
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
index 011089d..5654963 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,16 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getBounds();
+
+@libcore.util.NonNull public D getGenericDeclaration();
+
+@libcore.util.NonNull public java.lang.String getName();
 }
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
index 011089d..c8b90a0 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,14 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+package java.lang.reflect;
 
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface WildcardType extends java.lang.reflect.Type {
 
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getUpperBounds();
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getLowerBounds();
 }
diff --git a/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java
new file mode 100644
index 0000000..255c4be
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/ArrayList.annotated.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ArrayList<E> extends java.util.AbstractList<E> implements java.util.List<E>, java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable {
+
+public ArrayList(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public ArrayList() { throw new RuntimeException("Stub!"); }
+
+public ArrayList(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minCapacity) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E get(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E set(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public void add(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E remove(int index) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public boolean addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+protected void removeRange(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public void forEach(@libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NullFromTypeParam E> action) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+
+public boolean removeIf(@libcore.util.NonNull java.util.function.Predicate<? super @libcore.util.NullFromTypeParam E> filter) { throw new RuntimeException("Stub!"); }
+
+public void replaceAll(@libcore.util.NonNull java.util.function.UnaryOperator<@libcore.util.NullFromTypeParam E> operator) { throw new RuntimeException("Stub!"); }
+
+public void sort(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java
new file mode 100644
index 0000000..567354a
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/HashMap.annotated.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class HashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V>, java.lang.Cloneable, java.io.Serializable {
+
+public HashMap(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+public HashMap(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public HashMap() { throw new RuntimeException("Stub!"); }
+
+public HashMap(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V get(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V put(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V remove(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<@libcore.util.NullFromTypeParam K> keySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Collection<@libcore.util.NullFromTypeParam V> values() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V>> entrySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V getOrDefault(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable V defaultValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V putIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public boolean replace(@libcore.util.NullFromTypeParam K key, @libcore.util.Nullable V oldValue, @libcore.util.NullFromTypeParam V newValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V replace(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V computeIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NullFromTypeParam K,? extends @libcore.util.Nullable V> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V computeIfPresent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NonNull V,? extends Nu V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V compute(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.Nullable V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V merge(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull V value, @libcore.util.NonNull java.util.function.BiFunction<? super Nn V,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+public void forEach(@libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V> action) { throw new RuntimeException("Stub!"); }
+
+public void replaceAll(@libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V,? extends @libcore.util.NullFromTypeParam V> function) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
similarity index 65%
copy from ojluni/src/main/native/String.c
copy to ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
index 011089d..b4f4522 100644
--- a/ojluni/src/main/native/String.c
+++ b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,14 @@
  * questions.
  */
 
-#include "jvm.h"
-#include <nativehelper/JNIHelp.h>
+package java.util;
 
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
+import java.util.function.Consumer;
 
+public interface Iterator<E> {
 
-JNIEXPORT jobject JNICALL
-String_intern(JNIEnv *env, jobject this)
-{
-    return JVM_InternString(env, this);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
-};
-
-void register_java_lang_String(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/String", gMethods, NELEM(gMethods));
+  public boolean hasNext();
+  public @libcore.util.NullFromTypeParam E next();
+  public default void remove() { throw new RuntimeException("Stub!"); }
+  public default void forEachRemaining(@libcore.util.NonNull Consumer<? super @libcore.util.NullFromTypeParam E> action) { throw new RuntimeException("Stub!"); }
 }
diff --git a/ojluni/annotations/sdk/nullability/java/util/List.annotated.java b/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
new file mode 100644
index 0000000..958b335
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface List<E> extends java.util.Collection<E> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray();
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a);
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o);
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public default void replaceAll(@libcore.util.NonNull java.util.function.UnaryOperator<@libcore.util.NullFromTypeParam E> operator) { throw new RuntimeException("Stub!"); }
+
+public default void sort(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public void clear();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.NullFromTypeParam public E get(int index);
+
+@libcore.util.NullFromTypeParam public E set(int index, @libcore.util.NullFromTypeParam E element);
+
+public void add(int index, @libcore.util.NullFromTypeParam E element);
+
+@libcore.util.NullFromTypeParam public E remove(int index);
+
+public int indexOf(@libcore.util.Nullable java.lang.Object o);
+
+public int lastIndexOf(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator();
+
+@libcore.util.NonNull public java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index);
+
+@libcore.util.NonNull public java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex);
+
+@libcore.util.NonNull public default java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
new file mode 100644
index 0000000..2c89e2b3
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1997, 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.util;
+
+import java.util.function.Function;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Map<K, V> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key);
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value);
+
+@libcore.util.Nullable public V get(@libcore.util.Nullable java.lang.Object key);
+
+@libcore.util.Nullable public V put(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value);
+
+@libcore.util.Nullable public V remove(@libcore.util.Nullable java.lang.Object key);
+
+public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m);
+
+public void clear();
+
+@libcore.util.NonNull public java.util.Set<@libcore.util.NullFromTypeParam K> keySet();
+
+@libcore.util.NonNull public java.util.Collection<@libcore.util.NullFromTypeParam V> values();
+
+@libcore.util.NonNull public java.util.Set<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V>> entrySet();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.Nullable public default V getOrDefault(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable V defaultValue) { throw new RuntimeException("Stub!"); }
+
+public default void forEach(@libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V> action) { throw new RuntimeException("Stub!"); }
+
+public default void replaceAll(@libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NullFromTypeParam V,? extends @libcore.util.NullFromTypeParam V> function) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V putIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public default boolean remove(@libcore.util.Nullable java.lang.Object key, @libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public default boolean replace(@libcore.util.NullFromTypeParam K key, @libcore.util.Nullable V oldValue, @libcore.util.NullFromTypeParam V newValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V replace(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V computeIfAbsent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NullFromTypeParam K,? extends @libcore.util.Nullable V> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V computeIfPresent(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V compute(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NullFromTypeParam K,? super @libcore.util.Nullable V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default V merge(@libcore.util.NullFromTypeParam K key, @libcore.util.NonNull V value, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull V,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static interface Entry<K, V> {
+
+@libcore.util.NullFromTypeParam public K getKey();
+
+@libcore.util.NullFromTypeParam public V getValue();
+
+@libcore.util.NullFromTypeParam public V setValue(@libcore.util.NullFromTypeParam V value);
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+public static <K extends java.lang.Comparable<? super K>, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.Nullable V>> comparingByKey() { throw new RuntimeException("Stub!"); }
+
+public static <K, V extends java.lang.Comparable<? super V>> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.Nullable K, @libcore.util.NonNull V>> comparingByValue() { throw new RuntimeException("Stub!"); }
+
+public static <K, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NullFromTypeParam K, @libcore.util.Nullable V>> comparingByKey(@libcore.util.NonNull java.util.Comparator<? super @libcore.util.NullFromTypeParam K> cmp) { throw new RuntimeException("Stub!"); }
+
+public static <K, V> @libcore.util.NonNull java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.Nullable K, @libcore.util.NullFromTypeParam V>> comparingByValue(@libcore.util.NonNull java.util.Comparator<? super @libcore.util.NullFromTypeParam V> cmp) { throw new RuntimeException("Stub!"); }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
new file mode 100644
index 0000000..1257b5c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Set<E> extends java.util.Collection<E> {
+
+public int size();
+
+public boolean isEmpty();
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o);
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray();
+
+// TODO: Make param and return types @Nullable T @NonNull [] once metalava supports TYPE_USE.
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a);
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o);
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
+
+public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public void clear();
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o);
+
+public int hashCode();
+
+@libcore.util.NonNull public default java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/src/main/java/java/awt/font/TextAttribute.java b/ojluni/src/main/java/java/awt/font/TextAttribute.java
index 7dff4ad..af0dca3 100644
--- a/ojluni/src/main/java/java/awt/font/TextAttribute.java
+++ b/ojluni/src/main/java/java/awt/font/TextAttribute.java
@@ -491,6 +491,8 @@
     public static final TextAttribute FONT =
         new TextAttribute("font");
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see GraphicAttribute
     /**
      * Attribute key for a user-defined glyph to display in lieu
      * of the font's standard glyph for a character.  Values are
@@ -509,8 +511,6 @@
      *
      * <p>The GraphicAttribute determines the logical and visual
      * bounds of the text; the actual Font values are ignored.
-     *
-     * @see GraphicAttribute
      */
     public static final TextAttribute CHAR_REPLACEMENT =
         new TextAttribute("char_replacement");
@@ -519,6 +519,8 @@
     // Adornments added to text.
     //
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see java.awt.Paint
     /**
      * Attribute key for the paint used to render the text.  Values are
      * instances of <b><code>Paint</code></b>.  The default value is
@@ -529,12 +531,13 @@
      * <code>Paint</code> regardless of the <code>Paint</code> value
      * set on the <code>Graphics</code> (but see {@link #SWAP_COLORS}).
      *
-     * @see java.awt.Paint
      * @see #SWAP_COLORS
      */
     public static final TextAttribute FOREGROUND =
         new TextAttribute("foreground");
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see java.awt.Paint
     /**
      * Attribute key for the paint used to render the background of
      * the text.  Values are instances of <b><code>Paint</code></b>.
@@ -548,7 +551,6 @@
      * <p>The visual bounds of the text is extended to include the
      * logical bounds, if necessary.  The outline is not affected.
      *
-     * @see java.awt.Paint
      * @see #SWAP_COLORS
      */
     public static final TextAttribute BACKGROUND =
@@ -661,6 +663,8 @@
     public static final TextAttribute BIDI_EMBEDDING =
         new TextAttribute("bidi_embedding");
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see TextLayout#getJustifiedLayout
     /**
      * Attribute key for the justification of a paragraph.  Values are
      * instances of <b><code>Number</code></b>.  The default value is
@@ -679,8 +683,6 @@
      *
      * <p><em>Note:</em> This should have the same value for all the
      * text in a paragraph, otherwise the behavior is undetermined.
-     *
-     * @see TextLayout#getJustifiedLayout
      */
     public static final TextAttribute JUSTIFICATION =
         new TextAttribute("justification");
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
index d55ae76..b99f481 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
@@ -32,6 +32,8 @@
 import java.util.Hashtable;
 import java.util.Map.Entry;
 
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see VetoableChangeSupport
 /**
  * This is a utility class that can be used by beans that support bound
  * properties.  It manages a list of listeners and dispatches
@@ -75,8 +77,6 @@
  * This class is serializable.  When it is serialized it will save
  * (and restore) any listeners that are themselves serializable.  Any
  * non-serializable listeners will be skipped during serialization.
- *
- * @see VetoableChangeSupport
  */
 public class PropertyChangeSupport implements Serializable {
     private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
diff --git a/ojluni/src/main/java/java/io/FileDescriptor.java b/ojluni/src/main/java/java/io/FileDescriptor.java
index f0017ee..a2c833d 100644
--- a/ojluni/src/main/java/java/io/FileDescriptor.java
+++ b/ojluni/src/main/java/java/io/FileDescriptor.java
@@ -54,6 +54,15 @@
     // fetching the descriptor value.
     private int descriptor;
 
+    // Android-added: Track fd owner to guard against accidental closure. http://b/110100358
+    // The owner on the libc side is an pointer-sized value that can be set to an arbitrary
+    // value (with 0 meaning 'unowned'). libcore chooses to use System.identityHashCode.
+    private long ownerId = NO_OWNER;
+
+    // Android-added: value of ownerId indicating that a FileDescriptor is unowned.
+    /** @hide */
+    public static final long NO_OWNER = 0L;
+
     /**
      * Constructs an (invalid) FileDescriptor
      * object.
@@ -140,26 +149,63 @@
     /* This routine initializes JNI field offsets for the class */
     //private static native void initIDs();
 
+    // Android-added: Needed for framework to access descriptor value
     /**
      * Returns the int descriptor. It's highly unlikely you should be calling this. Please discuss
      * your needs with a libcore maintainer before using this method.
      * @hide internal use only
      */
-    // Android-added: Needed for framework to access descriptor value
     public final int getInt$() {
         return descriptor;
     }
 
+    // Android-added: Needed for framework to access descriptor value
     /**
      * Sets the int descriptor. It's highly unlikely you should be calling this. Please discuss
      * your needs with a libcore maintainer before using this method.
      * @hide internal use only
      */
-    // Android-added: Needed for framework to access descriptor value
     public final void setInt$(int fd) {
         this.descriptor = fd;
     }
 
+    // BEGIN Android-added: Methods to enable ownership enforcement of Unix file descriptors.
+    /**
+     * Returns the owner ID of this FileDescriptor. It's highly unlikely you should be calling this.
+     * Please discuss your needs with a libcore maintainer before using this method.
+     * @hide internal use only
+     */
+    public long getOwnerId$() {
+        return this.ownerId;
+    }
+
+    /**
+     * Sets the owner ID of this FileDescriptor. The owner ID does not need to be unique, but it is
+     * assumed that clashes are rare. See bionic/include/android/fdsan.h for more details.
+     *
+     * It's highly unlikely you should be calling this.
+     * Please discuss your needs with a libcore maintainer before using this method.
+     * @param owner the owner ID of the Object that is responsible for closing this FileDescriptor
+     * @hide internal use only
+     */
+    public void setOwnerId$(long newOwnerId) {
+        this.ownerId = newOwnerId;
+    }
+
+    /**
+     * Returns a copy of this FileDescriptor, and sets this to an invalid state.
+     * @hide internal use only
+     */
+    public FileDescriptor release$() {
+      FileDescriptor result = new FileDescriptor();
+      result.descriptor = this.descriptor;
+      result.ownerId = this.ownerId;
+      this.descriptor = -1;
+      this.ownerId = FileDescriptor.NO_OWNER;
+      return result;
+    }
+    // END Android-added: Methods to enable ownership enforcement of Unix file descriptors.
+
     /**
      * @hide internal use only
      */
diff --git a/ojluni/src/main/java/java/io/FileInputStream.java b/ojluni/src/main/java/java/io/FileInputStream.java
index db7ba65..03a67dc 100755
--- a/ojluni/src/main/java/java/io/FileInputStream.java
+++ b/ojluni/src/main/java/java/io/FileInputStream.java
@@ -26,6 +26,8 @@
 
 package java.io;
 
+import static android.system.OsConstants.O_RDONLY;
+
 import java.nio.channels.FileChannel;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
@@ -34,6 +36,7 @@
 import sun.nio.ch.FileChannelImpl;
 import libcore.io.IoBridge;
 import libcore.io.IoTracker;
+import libcore.io.IoUtils;
 
 
 /**
@@ -151,7 +154,9 @@
         if (file.isInvalid()) {
             throw new FileNotFoundException("Invalid file path");
         }
-        fd = new FileDescriptor();
+        // Android-changed: Open files through common bridge code.
+        // fd = new FileDescriptor();
+        fd = IoBridge.open(name, O_RDONLY);
 
         // Android-changed: Tracking mechanism for FileDescriptor sharing.
         // fd.attach(this);
@@ -159,10 +164,11 @@
 
         path = name;
 
-        // Android-added: BlockGuard support.
-        BlockGuard.getThreadPolicy().onReadFromDisk();
+        // Android-removed: Open files through common bridge code.
+        // open(name);
 
-        open(name);
+        // Android-added: File descriptor ownership tracking.
+        IoUtils.setFdOwner(this.fd, this);
 
         // Android-added: CloseGuard support.
         guard.open("close");
diff --git a/ojluni/src/main/java/java/io/FileOutputStream.java b/ojluni/src/main/java/java/io/FileOutputStream.java
index f29a741..95ad1be 100755
--- a/ojluni/src/main/java/java/io/FileOutputStream.java
+++ b/ojluni/src/main/java/java/io/FileOutputStream.java
@@ -26,6 +26,11 @@
 
 package java.io;
 
+import static android.system.OsConstants.O_APPEND;
+import static android.system.OsConstants.O_CREAT;
+import static android.system.OsConstants.O_TRUNC;
+import static android.system.OsConstants.O_WRONLY;
+
 import java.nio.channels.FileChannel;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
@@ -34,6 +39,7 @@
 import sun.nio.ch.FileChannelImpl;
 import libcore.io.IoBridge;
 import libcore.io.IoTracker;
+import libcore.io.IoUtils;
 
 /**
  * A file output stream is an output stream for writing data to a
@@ -223,7 +229,11 @@
         if (file.isInvalid()) {
             throw new FileNotFoundException("Invalid file path");
         }
-        this.fd = new FileDescriptor();
+        // BEGIN Android-changed: Open files through common bridge code.
+        // this.fd = new FileDescriptor();
+        int flags = O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC);
+        this.fd = IoBridge.open(name, flags);
+        // END Android-changed: Open files through common bridge code.
 
         // Android-changed: Tracking mechanism for FileDescriptor sharing.
         // fd.attach(this);
@@ -232,10 +242,11 @@
         this.append = append;
         this.path = name;
 
-        // Android-added: BlockGuard support.
-        BlockGuard.getThreadPolicy().onWriteToDisk();
+        // Android-removed: Open files through common bridge code.
+        // open(name, append);
 
-        open(name, append);
+        // Android-added: File descriptor ownership tracking.
+        IoUtils.setFdOwner(this.fd, this);
 
         // Android-added: CloseGuard support.
         guard.open("close");
diff --git a/ojluni/src/main/java/java/io/FilenameFilter.java b/ojluni/src/main/java/java/io/FilenameFilter.java
index 71b88af..25d866b 100644
--- a/ojluni/src/main/java/java/io/FilenameFilter.java
+++ b/ojluni/src/main/java/java/io/FilenameFilter.java
@@ -25,6 +25,8 @@
 
 package java.io;
 
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see     java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
 /**
  * Instances of classes that implement this interface are used to
  * filter filenames. These instances are used to filter directory
@@ -34,7 +36,6 @@
  *
  * @author  Arthur van Hoff
  * @author  Jonathan Payne
- * @see     java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
  * @see     java.io.File
  * @see     java.io.File#list(java.io.FilenameFilter)
  * @since   JDK1.0
diff --git a/ojluni/src/main/java/java/io/ObjectInputStream.java b/ojluni/src/main/java/java/io/ObjectInputStream.java
index f722df0..e06306d 100644
--- a/ojluni/src/main/java/java/io/ObjectInputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectInputStream.java
@@ -239,12 +239,54 @@
             new ReferenceQueue<>();
     }
 
+    // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    /*
+    static {
+        /* Setup access so sun.misc can invoke package private functions. *
+        sun.misc.SharedSecrets.setJavaOISAccess(new JavaOISAccess() {
+            public void setObjectInputFilter(ObjectInputStream stream, ObjectInputFilter filter) {
+                stream.setInternalObjectInputFilter(filter);
+            }
+
+            public ObjectInputFilter getObjectInputFilter(ObjectInputStream stream) {
+                return stream.getInternalObjectInputFilter();
+            }
+        });
+    }
+
+    /*
+     * Separate class to defer initialization of logging until needed.
+     *
+    private static class Logging {
+
+        /*
+         * Logger for ObjectInputFilter results.
+         * Setup the filter logger if it is set to INFO or WARNING.
+         * (Assuming it will not change).
+         *
+        private static final PlatformLogger traceLogger;
+        private static final PlatformLogger infoLogger;
+        static {
+            PlatformLogger filterLog = PlatformLogger.getLogger("java.io.serialization");
+            infoLogger = (filterLog != null &&
+                filterLog.isLoggable(PlatformLogger.Level.INFO)) ? filterLog : null;
+            traceLogger = (filterLog != null &&
+                filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null;
+        }
+    }
+    */
+
     /** filter stream for handling block data conversion */
     private final BlockDataInputStream bin;
     /** validation callback list */
     private final ValidationList vlist;
     /** recursion depth */
+    // Android-changed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    // private long depth;
     private int depth;
+    // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    // /** Total number of references to any type of object, class, enum, proxy, etc. */
+    // private long totalObjectRefs;
     /** whether stream is closed */
     private boolean closed;
 
@@ -270,6 +312,14 @@
      */
     private SerialCallbackContext curContext;
 
+    // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    /**
+     * Filter of class descriptors and classes read from the stream;
+     * may be null.
+     *
+    private ObjectInputFilter serialFilter;
+    */
+
     /**
      * Creates an ObjectInputStream that reads from the specified InputStream.
      * A serialization stream header is read from the stream and verified.
@@ -297,6 +347,8 @@
         bin = new BlockDataInputStream(in);
         handles = new HandleTable(10);
         vlist = new ValidationList();
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // serialFilter = ObjectInputFilter.Config.getSerialFilter();
         enableOverride = false;
         readStreamHeader();
         bin.setBlockDataMode(true);
@@ -327,6 +379,8 @@
         bin = null;
         handles = null;
         vlist = null;
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // serialFilter = ObjectInputFilter.Config.getSerialFilter();
         enableOverride = true;
     }
 
@@ -334,7 +388,7 @@
      * Read an object from the ObjectInputStream.  The class of the object, the
      * signature of the class, and the values of the non-transient and
      * non-static fields of the class and all of its supertypes are read.
-     * Default deserializing for a class can be overriden using the writeObject
+     * Default deserializing for a class can be overridden using the writeObject
      * and readObject methods.  Objects referenced by this object are read
      * transitively so that a complete equivalent graph of objects is
      * reconstructed by readObject.
@@ -1075,6 +1129,9 @@
         return bin.readUTF();
     }
 
+    // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    // Removed ObjectInputFilter related methods.
+
     /**
      * Provide access to the persistent fields read from the input stream.
      */
@@ -1324,6 +1381,8 @@
         }
 
         depth++;
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // totalObjectRefs++;
         try {
             switch (tc) {
                 case TC_NULL:
@@ -1400,6 +1459,18 @@
         }
         Object rep = resolveObject(obj);
         if (rep != obj) {
+            // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+            /*
+            // The type of the original object has been filtered but resolveObject
+            // may have replaced it;  filter the replacement's type
+            if (rep != null) {
+                if (rep.getClass().isArray()) {
+                    filterCheck(rep.getClass(), Array.getLength(rep));
+                } else {
+                    filterCheck(rep.getClass(), -1);
+                }
+            }
+            */
             handles.setObject(passHandle, rep);
         }
         return rep;
@@ -1470,6 +1541,8 @@
             throw new InvalidObjectException(
                 "cannot read back reference to unshared object");
         }
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // filterCheck(null, -1);       // just a check for number of references, depth, no class
         return obj;
     }
 
@@ -1506,23 +1579,29 @@
         throws IOException
     {
         byte tc = bin.peekByte();
+        ObjectStreamClass descriptor;
         switch (tc) {
             case TC_NULL:
-                return (ObjectStreamClass) readNull();
-
+                descriptor = (ObjectStreamClass) readNull();
+                break;
             case TC_REFERENCE:
-                return (ObjectStreamClass) readHandle(unshared);
-
+                descriptor = (ObjectStreamClass) readHandle(unshared);
+                break;
             case TC_PROXYCLASSDESC:
-                return readProxyDesc(unshared);
-
+                descriptor = readProxyDesc(unshared);
+                break;
             case TC_CLASSDESC:
-                return readNonProxyDesc(unshared);
-
+                descriptor = readNonProxyDesc(unshared);
+                break;
             default:
                 throw new StreamCorruptedException(
                     String.format("invalid type code: %02X", tc));
         }
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // if (descriptor != null) {
+        //     validateDescriptor(descriptor);
+        // }
+        return descriptor;
     }
 
     private boolean isCustomSubclass() {
@@ -1569,6 +1648,11 @@
                 ReflectUtil.checkProxyPackageAccess(
                         getClass().getClassLoader(),
                         cl.getInterfaces());
+                // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+                // // Filter the interfaces
+                // for (Class<?> clazz : cl.getInterfaces()) {
+                //     filterCheck(clazz, -1);
+                // }
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
@@ -1577,6 +1661,10 @@
 
         desc.initProxy(cl, resolveEx, readClassDesc(false));
 
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // // Call filterCheck on the definition
+        // filterCheck(desc.forClass(), -1);
+
         handles.finish(descHandle);
         passHandle = descHandle;
         return desc;
@@ -1624,8 +1712,13 @@
 
         desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
 
+        // Android-removed: ObjectInputFilter unsupported - removed filterCheck() call.
+        // // Call filterCheck on the definition
+        // filterCheck(desc.forClass(), -1);
+
         handles.finish(descHandle);
         passHandle = descHandle;
+
         return desc;
     }
 
@@ -1666,6 +1759,9 @@
         ObjectStreamClass desc = readClassDesc(false);
         int len = bin.readInt();
 
+        // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+        // filterCheck(desc.forClass(), len);
+
         Object array = null;
         Class<?> cl, ccl = null;
         if ((cl = desc.forClass()) != null) {
@@ -1814,6 +1910,17 @@
                 rep = cloneArray(rep);
             }
             if (rep != obj) {
+                // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+                /*
+                // Filter the replacement object
+                if (rep != null) {
+                    if (rep.getClass().isArray()) {
+                        filterCheck(rep.getClass(), Array.getLength(rep));
+                    } else {
+                        filterCheck(rep.getClass(), -1);
+                    }
+                }
+                */
                 handles.setObject(passHandle, obj = rep);
             }
         }
@@ -1892,6 +1999,10 @@
                 if (obj == null || handles.lookupException(passHandle) != null) {
                     defaultReadFields(null, slotDesc); // skip field values
                 } else if (slotDesc.hasReadObjectMethod()) {
+                    // BEGIN Android-changed: ThreadDeath cannot cause corruption on Android.
+                    // Android does not support Thread.stop() or Thread.stop(Throwable) so this
+                    // does not need to protect against state corruption that can occur when a
+                    // ThreadDeath Error is thrown in the middle of the finally block.
                     SerialCallbackContext oldContext = curContext;
                     if (oldContext != null)
                         oldContext.check();
@@ -1914,6 +2025,7 @@
                         if (oldContext!= null)
                             oldContext.check();
                         curContext = oldContext;
+                        // END Android-changed: ThreadDeath cannot cause corruption on Android.
                     }
 
                     /*
@@ -1924,7 +2036,7 @@
                     defaultDataEnd = false;
                 } else {
                     defaultReadFields(obj, slotDesc);
-                }
+                    }
 
                 if (slotDesc.hasWriteObjectData()) {
                     skipCustomData();
@@ -1940,7 +2052,7 @@
                 }
             }
         }
-    }
+            }
 
     /**
      * Skips over all block data and objects until TC_ENDBLOCKDATA is
@@ -1988,7 +2100,7 @@
         if (primVals == null || primVals.length < primDataSize) {
             primVals = new byte[primDataSize];
         }
-        bin.readFully(primVals, 0, primDataSize, false);
+            bin.readFully(primVals, 0, primDataSize, false);
         if (obj != null) {
             desc.setPrimFieldValues(obj, primVals);
         }
@@ -2287,6 +2399,9 @@
         }
     }
 
+    // Android-removed: ObjectInputFilter logic, to be reconsidered. http://b/110252929
+    // Removed FilterValues class.
+
     /**
      * Input stream supporting single-byte peek operations.
      */
@@ -2296,6 +2411,8 @@
         private final InputStream in;
         /** peeked byte */
         private int peekb = -1;
+        /** total bytes read from the stream */
+        private long totalBytesRead = 0;
 
         /**
          * Creates new PeekInputStream on top of given underlying stream.
@@ -2309,7 +2426,12 @@
          * that it does not consume the read value.
          */
         int peek() throws IOException {
-            return (peekb >= 0) ? peekb : (peekb = in.read());
+            if (peekb >= 0) {
+                return peekb;
+            }
+            peekb = in.read();
+            totalBytesRead += peekb >= 0 ? 1 : 0;
+            return peekb;
         }
 
         public int read() throws IOException {
@@ -2318,21 +2440,27 @@
                 peekb = -1;
                 return v;
             } else {
-                return in.read();
+                int nbytes = in.read();
+                totalBytesRead += nbytes >= 0 ? 1 : 0;
+                return nbytes;
             }
         }
 
         public int read(byte[] b, int off, int len) throws IOException {
+            int nbytes;
             if (len == 0) {
                 return 0;
             } else if (peekb < 0) {
-                return in.read(b, off, len);
+                nbytes = in.read(b, off, len);
+                totalBytesRead += nbytes >= 0 ? nbytes : 0;
+                return nbytes;
             } else {
                 b[off++] = (byte) peekb;
                 len--;
                 peekb = -1;
-                int n = in.read(b, off, len);
-                return (n >= 0) ? (n + 1) : 1;
+                nbytes = in.read(b, off, len);
+                totalBytesRead += nbytes >= 0 ? nbytes : 0;
+                return (nbytes >= 0) ? (nbytes + 1) : 1;
             }
         }
 
@@ -2357,7 +2485,9 @@
                 skipped++;
                 n--;
             }
-            return skipped + skip(n);
+            n = skipped + in.skip(n);
+            totalBytesRead += n;
+            return n;
         }
 
         public int available() throws IOException {
@@ -2367,6 +2497,10 @@
         public void close() throws IOException {
             in.close();
         }
+
+        public long getBytesRead() {
+            return totalBytesRead;
+        }
     }
 
     /**
@@ -3222,6 +3356,14 @@
                     throw new UTFDataFormatException();
             }
         }
+
+        /**
+         * Returns the number of bytes read from the input stream.
+         * @return the number of bytes read from the input stream
+         */
+        long getBytesRead() {
+            return in.getBytesRead();
+        }
     }
 
     /**
@@ -3552,4 +3694,23 @@
         }
     }
 
+    // Android-removed: Logic related to ObjectStreamClassValidator, unused on Android
+    /*
+    private void validateDescriptor(ObjectStreamClass descriptor) {
+        ObjectStreamClassValidator validating = validator;
+        if (validating != null) {
+            validating.validateDescriptor(descriptor);
+        }
+    }
+
+    // controlled access to ObjectStreamClassValidator
+    private volatile ObjectStreamClassValidator validator;
+
+    private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
+        ois.validator = validator;
+    }
+    static {
+        SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+    }
+    */
 }
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index b2651b8..4a183f8 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -53,7 +53,7 @@
 import sun.reflect.Reflection;
 import sun.reflect.misc.ReflectUtil;
 import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
+
 /**
  * Serialization's descriptor for classes.  It contains the name and
  * serialVersionUID of the class.  The ObjectStreamClass for a specific class
@@ -279,9 +279,8 @@
         }
         requireInitialized();
         if (System.getSecurityManager() != null) {
-            // Android-changed: Class loader obtained from VMStack
-            if (ReflectUtil.needsPackageAccessCheck(VMStack.getCallingClassLoader(),
-                  cl.getClassLoader())) {
+            Class<?> caller = Reflection.getCallerClass();
+            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) {
                 ReflectUtil.checkPackageAccess(cl);
             }
         }
diff --git a/ojluni/src/main/java/java/io/ObjectStreamField.java b/ojluni/src/main/java/java/io/ObjectStreamField.java
index 957972e..d26535f 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamField.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamField.java
@@ -162,14 +162,16 @@
      */
     @CallerSensitive
     public Class<?> getType() {
-        /* BEGIN Android-removed: Security manager is always null on Android.
+        // BEGIN Android-removed: Security manager is always null on Android.
+        /*
         if (System.getSecurityManager() != null) {
-             Class<?> caller = Reflection.getCallerClass();
+            Class<?> caller = Reflection.getCallerClass();
             if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {
                 ReflectUtil.checkPackageAccess(type);
             }
         }
-        END Android-removed: Security manager is always null on Android. */
+        */
+        // END Android-removed: Security manager is always null on Android.
         return type;
     }
 
diff --git a/ojluni/src/main/java/java/io/RandomAccessFile.java b/ojluni/src/main/java/java/io/RandomAccessFile.java
index a83829f..06683ad 100755
--- a/ojluni/src/main/java/java/io/RandomAccessFile.java
+++ b/ojluni/src/main/java/java/io/RandomAccessFile.java
@@ -34,6 +34,7 @@
 import dalvik.system.CloseGuard;
 import libcore.io.IoBridge;
 import libcore.io.IoTracker;
+import libcore.io.IoUtils;
 import libcore.io.Libcore;
 import static android.system.OsConstants.*;
 
@@ -286,6 +287,7 @@
 
         // BEGIN Android-changed: Use IoBridge.open() instead of open.
         fd = IoBridge.open(name, imode);
+        IoUtils.setFdOwner(fd, this);
         maybeSync();
         guard.open("close");
         // END Android-changed: Use IoBridge.open() instead of open.
diff --git a/ojluni/src/main/java/java/io/UnixFileSystem.java b/ojluni/src/main/java/java/io/UnixFileSystem.java
index 1659b17..6e1298d 100644
--- a/ojluni/src/main/java/java/io/UnixFileSystem.java
+++ b/ojluni/src/main/java/java/io/UnixFileSystem.java
@@ -166,7 +166,10 @@
                     }
                 }
                 if (res == null) {
+                    // BEGIN Android-added: BlockGuard support.
                     BlockGuard.getThreadPolicy().onReadFromDisk();
+                    BlockGuard.getVmPolicy().onPathAccess(path);
+                    // END Android-added: BlockGuard support.
                     res = canonicalize0(path);
                     cache.put(path, res);
                     if (useCanonPrefixCache &&
@@ -236,9 +239,11 @@
 
     private native int getBooleanAttributes0(String abspath);
 
-    // Android-changed: Added thread policy check
     public int getBooleanAttributes(File f) {
+        // BEGIN Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
+        // END Android-added: BlockGuard support.
 
         int rv = getBooleanAttributes0(f.getPath());
         String name = f.getName();
@@ -246,43 +251,47 @@
         return rv | (hidden ? BA_HIDDEN : 0);
     }
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean checkAccess(File f, int access) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return checkAccess0(f, access);
     }
     private native boolean checkAccess0(File f, int access);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public long getLastModifiedTime(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return getLastModifiedTime0(f);
     }
     private native long getLastModifiedTime0(File f);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public long getLength(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return getLength0(f);
     }
     private native long getLength0(File f);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return setPermission0(f, access, enable, owneronly);
     }
     private native boolean setPermission0(File f, int access, boolean enable, boolean owneronly);
 
     /* -- File operations -- */
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean createFileExclusively(String path) throws IOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(path);
         return createFileExclusively0(path);
     }
     private native boolean createFileExclusively0(String path) throws IOException;
 
-    // Android-changed: Added thread policy check
     public boolean delete(File f) {
         // Keep canonicalization caches in sync after file deletion
         // and renaming operations. Could be more clever than this
@@ -291,27 +300,31 @@
         // anyway.
         cache.clear();
         javaHomePrefixCache.clear();
+        // BEGIN Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
+        // END Android-added: BlockGuard support.
         return delete0(f);
     }
 
     private native boolean delete0(File f);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public String[] list(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return list0(f);
     }
     private native String[] list0(File f);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean createDirectory(File f) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return createDirectory0(f);
     }
     private native boolean createDirectory0(File f);
 
-    // Android-changed: Added thread policy check
     public boolean rename(File f1, File f2) {
         // Keep canonicalization caches in sync after file deletion
         // and renaming operations. Could be more clever than this
@@ -320,22 +333,28 @@
         // anyway.
         cache.clear();
         javaHomePrefixCache.clear();
+        // BEGIN Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f1.getPath());
+        BlockGuard.getVmPolicy().onPathAccess(f2.getPath());
+        // END Android-added: BlockGuard support.
         return rename0(f1, f2);
     }
 
     private native boolean rename0(File f1, File f2);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean setLastModifiedTime(File f, long time) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return setLastModifiedTime0(f, time);
     }
     private native boolean setLastModifiedTime0(File f, long time);
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public boolean setReadOnly(File f) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
         return setReadOnly0(f);
     }
     private native boolean setReadOnly0(File f);
@@ -356,9 +375,10 @@
     }
 
     /* -- Disk usage -- */
-    // Android-changed: Added thread policy check
+    // Android-changed: Add method to intercept native method call; BlockGuard support.
     public long getSpace(File f, int t) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
+        BlockGuard.getVmPolicy().onPathAccess(f.getPath());
 
         return getSpace0(f, t);
     }
diff --git a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
index cc24e96..4c31e23 100644
--- a/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/ojluni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -419,7 +418,6 @@
      *
      * @param   obj   an {@code Object}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(Object obj) {
         return append(String.valueOf(obj));
@@ -442,7 +440,6 @@
      *
      * @param   str   a string.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(String str) {
         if (str == null)
@@ -455,7 +452,6 @@
     }
 
     // Documentation in subclasses because of synchro difference
-    /** @hide */
     public AbstractStringBuilder append(StringBuffer sb) {
         if (sb == null)
             return appendNull();
@@ -468,7 +464,6 @@
 
     /**
      * @since 1.8
-     * @hide
      */
     AbstractStringBuilder append(AbstractStringBuilder asb) {
         if (asb == null)
@@ -481,7 +476,6 @@
     }
 
     // Documentation in subclasses because of synchro difference
-    /** @hide */
     @Override
     public AbstractStringBuilder append(CharSequence s) {
         if (s == null)
@@ -534,7 +528,6 @@
      *             {@code start} is negative, or
      *             {@code start} is greater than {@code end} or
      *             {@code end} is greater than {@code s.length()}
-     * @hide
      */
     @Override
     public AbstractStringBuilder append(CharSequence s, int start, int end) {
@@ -567,7 +560,6 @@
      *
      * @param   str   the characters to be appended.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(char[] str) {
         int len = str.length;
@@ -598,7 +590,6 @@
      * @throws IndexOutOfBoundsException
      *         if {@code offset < 0} or {@code len < 0}
      *         or {@code offset+len > str.length}
-     * @hide
      */
     public AbstractStringBuilder append(char str[], int offset, int len) {
         if (len > 0)                // let arraycopy report AIOOBE for len < 0
@@ -619,7 +610,6 @@
      *
      * @param   b   a {@code boolean}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(boolean b) {
         if (b) {
@@ -653,7 +643,6 @@
      *
      * @param   c   a {@code char}.
      * @return  a reference to this object.
-     * @hide
      */
     @Override
     public AbstractStringBuilder append(char c) {
@@ -673,7 +662,6 @@
      *
      * @param   i   an {@code int}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(int i) {
         if (i == Integer.MIN_VALUE) {
@@ -700,7 +688,6 @@
      *
      * @param   l   a {@code long}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(long l) {
         if (l == Long.MIN_VALUE) {
@@ -727,7 +714,6 @@
      *
      * @param   f   a {@code float}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(float f) {
         FloatingDecimal.appendTo(f,this);
@@ -745,7 +731,6 @@
      *
      * @param   d   a {@code double}.
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder append(double d) {
         FloatingDecimal.appendTo(d,this);
@@ -765,7 +750,6 @@
      * @throws     StringIndexOutOfBoundsException  if {@code start}
      *             is negative, greater than {@code length()}, or
      *             greater than {@code end}.
-     * @hide
      */
     public AbstractStringBuilder delete(int start, int end) {
         if (start < 0)
@@ -800,7 +784,6 @@
      * @return  a reference to this object.
      * @exception IllegalArgumentException if the specified
      * {@code codePoint} isn't a valid Unicode code point
-     * @hide
      */
     public AbstractStringBuilder appendCodePoint(int codePoint) {
         final int count = this.count;
@@ -835,7 +818,6 @@
      * @throws      StringIndexOutOfBoundsException  if the {@code index}
      *              is negative or greater than or equal to
      *              {@code length()}.
-     * @hide
      */
     public AbstractStringBuilder deleteCharAt(int index) {
         if ((index < 0) || (index >= count))
@@ -863,7 +845,6 @@
      * @throws     StringIndexOutOfBoundsException  if {@code start}
      *             is negative, greater than {@code length()}, or
      *             greater than {@code end}.
-     * @hide
      */
     public AbstractStringBuilder replace(int start, int end, String str) {
         if (start < 0)
@@ -975,7 +956,6 @@
      *             {@code offset} or {@code len} are negative, or
      *             {@code (offset+len)} is greater than
      *             {@code str.length}.
-     * @hide
      */
     public AbstractStringBuilder insert(int index, char[] str, int offset,
                                         int len)
@@ -1011,7 +991,6 @@
      * @param      obj      an {@code Object}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, Object obj) {
         return insert(offset, String.valueOf(obj));
@@ -1047,7 +1026,6 @@
      * @param      str      a string.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, String str) {
         if ((offset < 0) || (offset > length()))
@@ -1085,7 +1063,6 @@
      * @param      str      a character array.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, char[] str) {
         if ((offset < 0) || (offset > length()))
@@ -1118,7 +1095,6 @@
      * @param      s the sequence to be inserted
      * @return     a reference to this object.
      * @throws     IndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
         if (s == null)
@@ -1171,7 +1147,6 @@
      *              {@code start} or {@code end} are negative, or
      *              {@code start} is greater than {@code end} or
      *              {@code end} is greater than {@code s.length()}
-     * @hide
      */
      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
                                          int start, int end) {
@@ -1211,7 +1186,6 @@
      * @param      b        a {@code boolean}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, boolean b) {
         return insert(offset, String.valueOf(b));
@@ -1235,7 +1209,6 @@
      * @param      c        a {@code char}.
      * @return     a reference to this object.
      * @throws     IndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, char c) {
         ensureCapacityInternal(count + 1);
@@ -1263,7 +1236,6 @@
      * @param      i        an {@code int}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, int i) {
         return insert(offset, String.valueOf(i));
@@ -1287,7 +1259,6 @@
      * @param      l        a {@code long}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, long l) {
         return insert(offset, String.valueOf(l));
@@ -1311,7 +1282,6 @@
      * @param      f        a {@code float}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, float f) {
         return insert(offset, String.valueOf(f));
@@ -1335,7 +1305,6 @@
      * @param      d        a {@code double}.
      * @return     a reference to this object.
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
-     * @hide
      */
     public AbstractStringBuilder insert(int offset, double d) {
         return insert(offset, String.valueOf(d));
@@ -1376,8 +1345,7 @@
      *          specified substring, starting at the specified index.
      */
     public int indexOf(String str, int fromIndex) {
-        return String.indexOf(value, 0, count,
-                              str.toCharArray(), 0, str.length(), fromIndex);
+        return String.indexOf(value, 0, count, str, fromIndex);
     }
 
     /**
@@ -1416,8 +1384,7 @@
      *          specified substring.
      */
     public int lastIndexOf(String str, int fromIndex) {
-        return String.lastIndexOf(value, 0, count,
-                                  str.toCharArray(), 0, str.length(), fromIndex);
+        return String.lastIndexOf(value, 0, count, str, fromIndex);
     }
 
     /**
@@ -1441,7 +1408,6 @@
      * a valid surrogate pair.
      *
      * @return  a reference to this object.
-     * @hide
      */
     public AbstractStringBuilder reverse() {
         boolean hasSurrogates = false;
diff --git a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
index 9c85456..d07a4b2 100644
--- a/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
+++ b/ojluni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
@@ -65,22 +65,4 @@
     public ArrayIndexOutOfBoundsException(String s) {
         super(s);
     }
-
-    // Android-added: Additional constructor for internal use.
-    /**
-     * @hide
-     */
-    public ArrayIndexOutOfBoundsException(int sourceLength, int index) {
-        super("length=" + sourceLength + "; index=" + index);
-    }
-
-    // Android-added: Additional constructor for internal use.
-    /**
-     * @hide
-     */
-    public ArrayIndexOutOfBoundsException(int sourceLength, int offset,
-            int count) {
-        super("length=" + sourceLength + "; regionStart=" + offset
-                + "; regionLength=" + count);
-    }
 }
diff --git a/ojluni/src/main/java/java/lang/Character.java b/ojluni/src/main/java/java/lang/Character.java
index 454cbbb..0b3081f 100644
--- a/ojluni/src/main/java/java/lang/Character.java
+++ b/ojluni/src/main/java/java/lang/Character.java
@@ -6000,6 +6000,8 @@
     @FastNative
     static native boolean isIdeographicImpl(int codePoint);
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
     /**
      * Determines if the specified character is
      * permissible as the first character in a Java identifier.
@@ -6024,13 +6026,14 @@
      * @see     Character#isJavaIdentifierPart(char)
      * @see     Character#isLetter(char)
      * @see     Character#isUnicodeIdentifierStart(char)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.1
      */
     public static boolean isJavaIdentifierStart(char ch) {
         return isJavaIdentifierStart((int)ch);
     }
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
     /**
      * Determines if the character (Unicode code point) is
      * permissible as the first character in a Java identifier.
@@ -6053,7 +6056,6 @@
      * @see     Character#isJavaIdentifierPart(int)
      * @see     Character#isLetter(int)
      * @see     Character#isUnicodeIdentifierStart(int)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
     public static boolean isJavaIdentifierStart(int codePoint) {
@@ -6074,6 +6076,8 @@
                    | (1  << LETTER_NUMBER))) != 0;
     }
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
     /**
      * Determines if the specified character may be part of a Java
      * identifier as other than the first character.
@@ -6104,13 +6108,14 @@
      * @see     Character#isJavaIdentifierStart(char)
      * @see     Character#isLetterOrDigit(char)
      * @see     Character#isUnicodeIdentifierPart(char)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.1
      */
     public static boolean isJavaIdentifierPart(char ch) {
         return isJavaIdentifierPart((int)ch);
     }
 
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
     /**
      * Determines if the character (Unicode code point) may be part of a Java
      * identifier as other than the first character.
@@ -6137,7 +6142,6 @@
      * @see     Character#isJavaIdentifierStart(int)
      * @see     Character#isLetterOrDigit(int)
      * @see     Character#isUnicodeIdentifierPart(int)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
     public static boolean isJavaIdentifierPart(int codePoint) {
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index f31a42c..f792248 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -57,8 +57,8 @@
 import libcore.util.EmptyArray;
 
 import dalvik.system.ClassExt;
-import dalvik.system.VMStack;
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
 /**
  * Instances of the class {@code Class} represent classes and
@@ -375,7 +375,8 @@
     @CallerSensitive
     public static Class<?> forName(String className)
                 throws ClassNotFoundException {
-        return forName(className, true, VMStack.getCallingClassLoader());
+        Class<?> caller = Reflection.getCallerClass();
+        return forName(className, true, ClassLoader.getClassLoader(caller));
     }
 
 
@@ -778,6 +779,8 @@
         if (isPrimitive()) {
             return null;
         }
+        // Android-note: The RI returns null in the case where Android returns BootClassLoader.
+        // Noted in http://b/111850480#comment3
         return (classLoader == null) ? BootClassLoader.getInstance() : classLoader;
     }
 
@@ -2065,7 +2068,8 @@
         // Fail if we didn't find the method or it was expected to be public.
         if (result == null ||
             (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
-            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
+            throw new NoSuchMethodException(getName() + "." + name + " "
+                    + Arrays.toString(parameterTypes));
         }
         return result;
     }
@@ -2324,7 +2328,8 @@
         }
         Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
         if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) {
-            throw new NoSuchMethodException("<init> " + Arrays.toString(parameterTypes));
+            throw new NoSuchMethodException(getName() + ".<init> "
+                    + Arrays.toString(parameterTypes));
         }
         return result;
     }
diff --git a/ojluni/src/main/java/java/lang/ClassLoader.java b/ojluni/src/main/java/java/lang/ClassLoader.java
index 08dee73..0a8b08a 100644
--- a/ojluni/src/main/java/java/lang/ClassLoader.java
+++ b/ojluni/src/main/java/java/lang/ClassLoader.java
@@ -1098,6 +1098,18 @@
         return SystemClassLoader.loader;
     }
 
+    // Returns the class's class loader, or null if none.
+    static ClassLoader getClassLoader(Class<?> caller) {
+        // This can be null if the VM is requesting it
+        if (caller == null) {
+            return null;
+        }
+        // Android-changed: Use Class.getClassLoader(); there is no Class.getClassLoader0().
+        // // Circumvent security check since this is package-private
+        // return caller.getClassLoader0();
+        return caller.getClassLoader();
+    }
+
     // -- Package --
 
     /**
diff --git a/ojluni/src/main/java/java/lang/Enum.java b/ojluni/src/main/java/java/lang/Enum.java
index 8ada57f..988c133 100644
--- a/ojluni/src/main/java/java/lang/Enum.java
+++ b/ojluni/src/main/java/java/lang/Enum.java
@@ -33,6 +33,7 @@
 import java.io.ObjectStreamException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Objects;
 import libcore.util.BasicLruCache;
 import libcore.util.EmptyArray;
 
@@ -232,15 +233,13 @@
      *         is null
      * @since 1.5
      */
+    // BEGIN Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+    // This change was made to fix a performance regression. See b/4087759 and b/109791362 for more
+    // background information.
     public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                 String name) {
-        // Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
-        if (enumType == null) {
-            throw new NullPointerException("enumType == null");
-        }
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
+        Objects.requireNonNull(enumType, "enumType == null");
+        Objects.requireNonNull(enumType, "name == null");
         T[] values = getSharedConstants(enumType);
         if (values == null) {
             throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
@@ -258,23 +257,24 @@
                 "No enum constant " + enumType.getCanonicalName() + "." + name);
     }
 
+    private static Object[] enumValues(Class<? extends Enum> clazz) {
+        if (!clazz.isEnum()) {
+            // Either clazz is Enum.class itself, or it is not an enum class and the method was
+            // called unsafely e.g. using an unchecked cast or via reflection.
+            return null;
+        }
+        try {
+            Method valueMethod = clazz.getDeclaredMethod("values");
+            return (Object[]) valueMethod.invoke(null);
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
             = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
         @Override protected Object[] create(Class<? extends Enum> enumType) {
-            if (!enumType.isEnum()) {
-                return null;
-            }
-            try {
-                Method method = enumType.getDeclaredMethod("values", EmptyArray.CLASS);
-                method.setAccessible(true);
-                return (Object[]) method.invoke((Object[]) null);
-            } catch (NoSuchMethodException impossible) {
-                throw new AssertionError("impossible", impossible);
-            } catch (IllegalAccessException impossible) {
-                throw new AssertionError("impossible", impossible);
-            } catch (InvocationTargetException impossible) {
-                throw new AssertionError("impossible", impossible);
-            }
+            return enumValues(enumType);
         }
     };
 
@@ -288,6 +288,7 @@
     public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
         return (T[]) sharedConstantsCache.get(enumType);
     }
+    // END Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
 
     /**
      * enum classes cannot have finalize methods.
diff --git a/ojluni/src/main/java/java/lang/Object.java b/ojluni/src/main/java/java/lang/Object.java
index e9728e0..d307144 100644
--- a/ojluni/src/main/java/java/lang/Object.java
+++ b/ojluni/src/main/java/java/lang/Object.java
@@ -39,6 +39,13 @@
  */
 public class Object {
 
+    // Android-removed: registerNatives() not used on Android
+    // private static native void registerNatives();
+    // static {
+    //     registerNatives();
+    // }
+
+    // Android-added: Use Android specific fields for Class and monitor.
     private transient Class<?> shadow$_klass_;
     private transient int shadow$_monitor_;
 
@@ -61,6 +68,8 @@
      *         class of this object.
      * @jls 15.8.2 Class Literals
      */
+    // Android-changed: Use Android specific fields for Class and monitor.
+    // public final native Class<?> getClass();
     public final Class<?> getClass() {
       return shadow$_klass_;
     }
@@ -100,11 +109,12 @@
      * @see     java.lang.Object#equals(java.lang.Object)
      * @see     java.lang.System#identityHashCode
      */
+    // BEGIN Android-changed: Added a local helper for identityHashCode.
+    // public native int hashCode();
     public int hashCode() {
         return identityHashCode(this);
     }
 
-    // Android-changed: add a local helper for identityHashCode.
     // Package-private to be used by j.l.System. We do the implementation here
     // to avoid Object.hashCode doing a clinit check on j.l.System, and also
     // to avoid leaking shadow$_monitor_ outside of this class.
@@ -119,8 +129,13 @@
         return identityHashCodeNative(obj);
     }
 
+    /**
+     * Return the identity hash code when the information in the monitor field
+     * is not sufficient.
+     */
     @FastNative
     private static native int identityHashCodeNative(Object obj);
+    // END Android-changed: Added a local helper for identityHashCode.
 
     /**
      * Indicates whether some other object is "equal to" this one.
@@ -232,6 +247,9 @@
      *               be cloned.
      * @see java.lang.Cloneable
      */
+    // BEGIN Android-changed: Use native local helper for clone()
+    // Checks whether cloning is allowed before calling native local helper.
+    // protected native Object clone() throws CloneNotSupportedException;
     protected Object clone() throws CloneNotSupportedException {
         if (!(this instanceof Cloneable)) {
             throw new CloneNotSupportedException("Class " + getClass().getName() +
@@ -246,7 +264,7 @@
      */
     @FastNative
     private native Object internalClone();
-
+    // END Android-changed: Use native local helper for clone()
 
     /**
      * Returns a string representation of the object. In general, the
@@ -405,7 +423,7 @@
      * description of the ways in which a thread can become the owner of
      * a monitor.
      *
-     * @param      millis   the maximum time to wait in milliseconds.
+     * @param      timeout   the maximum time to wait in milliseconds.
      * @throws  IllegalArgumentException      if the value of timeout is
      *               negative.
      * @throws  IllegalMonitorStateException  if the current thread is not
@@ -418,8 +436,10 @@
      * @see        java.lang.Object#notify()
      * @see        java.lang.Object#notifyAll()
      */
-    public final void wait(long millis) throws InterruptedException {
-        wait(millis, 0);
+    // Android-changed: Implement wait(long) non-natively.
+    // public final native void wait(long timeout) throws InterruptedException;
+    public final void wait(long timeout) throws InterruptedException {
+        wait(timeout, 0);
     }
 
     /**
@@ -470,7 +490,7 @@
      * description of the ways in which a thread can become the owner of
      * a monitor.
      *
-     * @param      millis   the maximum time to wait in milliseconds.
+     * @param      timeout   the maximum time to wait in milliseconds.
      * @param      nanos      additional time, in nanoseconds range
      *                       0-999999.
      * @throws  IllegalArgumentException      if the value of timeout is
@@ -484,8 +504,27 @@
      *             status</i> of the current thread is cleared when
      *             this exception is thrown.
      */
+    // Android-changed: Implement wait(long, int) natively.
+    /*
+    public final void wait(long timeout, int nanos) throws InterruptedException {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+
+        if (nanos > 0) {
+            timeout++;
+        }
+
+        wait(timeout);
+    }
+    */
     @FastNative
-    public final native void wait(long millis, int nanos) throws InterruptedException;
+    public final native void wait(long timeout, int nanos) throws InterruptedException;
 
     /**
      * Causes the current thread to wait until another thread invokes the
@@ -525,8 +564,9 @@
      * @see        java.lang.Object#notify()
      * @see        java.lang.Object#notifyAll()
      */
-    @FastNative
-    public final native void wait() throws InterruptedException;
+    public final void wait() throws InterruptedException {
+        wait(0);
+    }
 
     /**
      * Called by the garbage collector on an object when garbage collection
diff --git a/ojluni/src/main/java/java/lang/Package.java b/ojluni/src/main/java/java/lang/Package.java
index 33136f3..b6a37fd 100644
--- a/ojluni/src/main/java/java/lang/Package.java
+++ b/ojluni/src/main/java/java/lang/Package.java
@@ -52,7 +52,7 @@
 import sun.net.www.ParseUtil;
 import sun.reflect.CallerSensitive;
 import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
+import sun.reflect.Reflection;
 
 import java.lang.annotation.Annotation;
 
@@ -279,9 +279,7 @@
      */
     @CallerSensitive
     public static Package getPackage(String name) {
-        // Android-changed: Use VMStack.getCallingClassLoader() to obtain the classloader.
-        // ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
-        ClassLoader l = VMStack.getCallingClassLoader();
+        ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
         if (l != null) {
             return l.getPackage(name);
         } else {
@@ -303,9 +301,7 @@
      */
     @CallerSensitive
     public static Package[] getPackages() {
-        // Android-changed: Use VMStack.getCallingClassLoader() to obtain the classloader.
-        // ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
-        ClassLoader l = VMStack.getCallingClassLoader();
+        ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
         if (l != null) {
             return l.getPackages();
         } else {
diff --git a/ojluni/src/main/java/java/lang/ProcessImpl.java b/ojluni/src/main/java/java/lang/ProcessImpl.java
index 6b88585..39ea145 100644
--- a/ojluni/src/main/java/java/lang/ProcessImpl.java
+++ b/ojluni/src/main/java/java/lang/ProcessImpl.java
@@ -39,6 +39,9 @@
  * @since   1.5
  */
 final class ProcessImpl {
+    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+    // private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+    //     = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
 
     private ProcessImpl() {}    // Not instantiable
 
@@ -101,6 +104,8 @@
                     std_fds[0] = 0;
                 else {
                     f0 = new FileInputStream(redirects[0].file());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[0] = fdAccess.get(f0.getFD());
                     std_fds[0] = f0.getFD().getInt$();
                 }
 
@@ -111,6 +116,8 @@
                 else {
                     f1 = new FileOutputStream(redirects[1].file(),
                                               redirects[1].append());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[1] = fdAccess.get(f1.getFD());
                     std_fds[1] = f1.getFD().getInt$();
                 }
 
@@ -121,6 +128,8 @@
                 else {
                     f2 = new FileOutputStream(redirects[2].file(),
                                               redirects[2].append());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[2] = fdAccess.get(f2.getFD());
                     std_fds[2] = f2.getFD().getInt$();
                 }
             }
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index acc75b0..2fc124c 100644
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -29,14 +29,17 @@
 import dalvik.annotation.optimization.FastNative;
 import java.io.*;
 import java.util.StringTokenizer;
+
+import dalvik.system.BlockGuard;
 import sun.reflect.CallerSensitive;
 import java.lang.ref.FinalizerReference;
 import java.util.ArrayList;
 import java.util.List;
 import dalvik.system.BaseDexClassLoader;
 import dalvik.system.VMDebug;
-import dalvik.system.VMStack;
 import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
 import libcore.util.EmptyArray;
@@ -765,7 +768,14 @@
      * The method {@link System#gc()} is the conventional and convenient
      * means of invoking this method.
      */
-    public native void gc();
+    // Android-changed: Added BlockGuard check to gc()
+    // public native void gc();
+    public void gc() {
+        BlockGuard.getThreadPolicy().onExplicitGc();
+        nativeGc();
+    }
+
+    private native void nativeGc();
 
     /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
     private static native void runFinalization0();
@@ -888,7 +898,7 @@
      */
     @CallerSensitive
     public void load(String filename) {
-        load0(VMStack.getStackClass1(), filename);
+        load0(Reflection.getCallerClass(), filename);
     }
 
     /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */
@@ -975,7 +985,26 @@
      */
     @CallerSensitive
     public void loadLibrary(String libname) {
-        loadLibrary0(VMStack.getCallingClassLoader(), libname);
+        loadLibrary0(Reflection.getCallerClass(), libname);
+    }
+
+    // BEGIN Android-changed: Different implementation of loadLibrary0(Class, String).
+    /*
+    synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkLink(libname);
+        }
+        if (libname.indexOf((int)File.separatorChar) != -1) {
+            throw new UnsatisfiedLinkError(
+    "Directory separator should not appear in library name: " + libname);
+        }
+        ClassLoader.loadLibrary(fromClass, libname, false);
+    }
+    */
+    void loadLibrary0(Class<?> fromClass, String libname) {
+        ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);
+        loadLibrary0(classLoader, libname);
     }
 
     /**
@@ -1001,7 +1030,10 @@
     "Directory separator should not appear in library name: " + libname);
         }
         String libraryName = libname;
-        if (loader != null) {
+        // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480
+        // Android's class.getClassLoader() can return BootClassLoader where the RI would
+        // have returned null; therefore we treat BootClassLoader the same as null here.
+        if (loader != null && !(loader instanceof BootClassLoader)) {
             String filename = loader.findLibrary(libraryName);
             if (filename == null) {
                 // It's not necessarily true that the ClassLoader used
@@ -1069,6 +1101,7 @@
     }
 
     private static native String nativeLoad(String filename, ClassLoader loader);
+    // END Android-changed: Different implementation of loadLibrary0(Class, String).
 
     /**
      * Creates a localized version of an input stream. This method takes
diff --git a/ojluni/src/main/java/java/lang/StackTraceElement.java b/ojluni/src/main/java/java/lang/StackTraceElement.java
index e519fea..e3dad88 100644
--- a/ojluni/src/main/java/java/lang/StackTraceElement.java
+++ b/ojluni/src/main/java/java/lang/StackTraceElement.java
@@ -169,8 +169,22 @@
      * @see    Throwable#printStackTrace()
      */
     public String toString() {
-        // Android-changed: When ART cannot find a line number, the lineNumber field is set
-        // to the dex_pc and the fileName field is set to null.
+        // BEGIN Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+        // http://b/30183883
+        // The only behavior change is that "Unknown Source" is followed by a number
+        // (the value of the dex program counter, dex_pc), which never occurs on the
+        // RI. This value isn't a line number, but can be useful for debugging and
+        // avoids the need to ship line number information along with the dex code to
+        // get an accurate stack trace.
+        // Formatting it in this way might be more digestible to automated tools that
+        // are not specifically written to expect this behavior.
+        /*
+        return getClassName() + "." + methodName +
+            (isNativeMethod() ? "(Native Method)" :
+             (fileName != null && lineNumber >= 0 ?
+              "(" + fileName + ":" + lineNumber + ")" :
+              (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
+        */
         StringBuilder result = new StringBuilder();
         result.append(getClassName()).append(".").append(methodName);
         if (isNativeMethod()) {
@@ -190,6 +204,7 @@
             }
         }
         return result.toString();
+        // END Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/String.java b/ojluni/src/main/java/java/lang/String.java
index de54882..b5df9f0 100644
--- a/ojluni/src/main/java/java/lang/String.java
+++ b/ojluni/src/main/java/java/lang/String.java
@@ -1707,24 +1707,20 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int indexOf(String str, int fromIndex) {
-        // Android-changed: Change parameters to static indexOf to match new signature below.
+        // Android-changed: Delegate to the static indexOf method below.
         return indexOf(this, str, fromIndex);
     }
 
+    // BEGIN Android-added: Private static indexOf method that takes String parameters.
+    // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
     /**
-     * Code shared by String and AbstractStringBuilder to do searches. The
-     * source is the character array being searched, and the target
-     * is the string being searched for.
+     * The source is the string being searched, and the target is the string being searched for.
      *
      * @param   source       the characters being searched.
      * @param   target       the characters being searched for.
      * @param   fromIndex    the index to begin searching from.
      */
-    // BEGIN Android-changed: Change signature to take String object rather than char arrays.
-    // The implementation using a java char array is replaced with one using length() & charAt().
-    static int indexOf(String source,
-                       String target,
-                       int fromIndex) {
+    private static int indexOf(String source, String target, int fromIndex) {
         final int sourceLength = source.length();
         final int targetLength = target.length();
         if (fromIndex >= sourceLength) {
@@ -1761,7 +1757,25 @@
         }
         return -1;
     }
-    // END Android-changed: Change signature to take String object rather than char arrays.
+    // END Android-added: Private static indexOf method that takes String parameters.
+
+    /**
+     * Code shared by String and AbstractStringBuilder to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int indexOf(char[] source, int sourceOffset, int sourceCount,
+            String target, int fromIndex) {
+        return indexOf(source, sourceOffset, sourceCount,
+                       target.toCharArray(), 0, target.length(),
+                       fromIndex);
+    }
 
     /**
      * Code shared by String and StringBuffer to do searches. The
@@ -1854,20 +1868,16 @@
         return lastIndexOf(this, str, fromIndex);
     }
 
+    // BEGIN Android-added: Private static lastIndexOf method that takes String parameters.
+    // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
     /**
-     * Code shared by String and AbstractStringBuilder to do searches. The
-     * source is the character array being searched, and the target
-     * is the string being searched for.
+     * The source is the string being searched, and the target is the string being searched for.
      *
      * @param   source       the characters being searched.
      * @param   target       the characters being searched for.
      * @param   fromIndex    the index to begin searching from.
      */
-    // BEGIN Android-changed: Change signature to take String object rather than char arrays.
-    // The implementation using a java char array is replaced with one using length() & charAt().
-    static int lastIndexOf(String source,
-                           String target,
-                           int fromIndex) {
+    private static int lastIndexOf(String source, String target, int fromIndex) {
         /*
          * Check arguments; return immediately where possible. For
          * consistency, don't check for null str.
@@ -1912,7 +1922,25 @@
             return start + 1;
         }
     }
-    // END Android-changed: Change signature to take String object rather than char arrays.
+    // END Android-added: Private static lastIndexOf method that takes String parameters.
+
+    /**
+     * Code shared by String and AbstractStringBuilder to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+            String target, int fromIndex) {
+        return lastIndexOf(source, sourceOffset, sourceCount,
+                       target.toCharArray(), 0, target.length(),
+                       fromIndex);
+    }
 
     /**
      * Code shared by String and StringBuffer to do searches. The
@@ -2907,9 +2935,7 @@
      *          character array.
      */
     public static String valueOf(char data[]) {
-        // Android-changed: Replace constructor call with call to new StringFactory class.
-        // return new String(data);
-        return StringFactory.newStringFromChars(data);
+        return new String(data);
     }
 
     /**
@@ -2933,9 +2959,7 @@
      *          {@code data.length}.
      */
     public static String valueOf(char data[], int offset, int count) {
-        // Android-changed: Replace constructor call with call to new StringFactory class.
-        // return new String(data, offset, count);
-        return StringFactory.newStringFromChars(data, offset, count);
+        return new String(data, offset, count);
     }
 
     /**
@@ -2952,10 +2976,7 @@
      *          {@code data.length}.
      */
     public static String copyValueOf(char data[], int offset, int count) {
-        // Android-changed: Replace constructor call with call to new StringFactory class.
-        // All public String constructors now copy the data.
-        // return new String(data, offset, count);
-        return StringFactory.newStringFromChars(data, offset, count);
+        return new String(data, offset, count);
     }
 
     /**
@@ -2966,9 +2987,7 @@
      *          character array.
      */
     public static String copyValueOf(char data[]) {
-        // Android-changed: Replace constructor call with call to new StringFactory class.
-        // return new String(data);
-        return StringFactory.newStringFromChars(data);
+        return new String(data);
     }
 
     /**
@@ -2992,7 +3011,8 @@
      *          as its single character the argument {@code c}.
      */
     public static String valueOf(char c) {
-        // Android-changed: Replace constructor call with call to new StringFactory class.
+        // Android-changed: Replace constructor call with call to StringFactory class.
+        // There is currently no String(char[], boolean) on Android to call. http://b/79902155
         // char data[] = {c};
         // return new String(data, true);
         return StringFactory.newStringFromChars(0, 1, new char[] { c });
diff --git a/ojluni/src/main/java/java/lang/StringBuilder.java b/ojluni/src/main/java/java/lang/StringBuilder.java
index 42642c7..325c9c5 100644
--- a/ojluni/src/main/java/java/lang/StringBuilder.java
+++ b/ojluni/src/main/java/java/lang/StringBuilder.java
@@ -404,10 +404,13 @@
 
     @Override
     public String toString() {
+        // BEGIN Android-added: Return a constant "" for an empty buffer to keep historic behavior.
         if (count == 0) {
             return "";
         }
-        return StringFactory.newStringFromChars(0, count, value);
+        // END Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+        // Create a copy, don't share the array
+        return new String(value, 0, count);
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/System.java b/ojluni/src/main/java/java/lang/System.java
index 65a9d4a..2008380 100644
--- a/ojluni/src/main/java/java/lang/System.java
+++ b/ojluni/src/main/java/java/lang/System.java
@@ -30,7 +30,6 @@
 import android.system.StructPasswd;
 import android.system.StructUtsname;
 import dalvik.system.VMRuntime;
-import dalvik.system.VMStack;
 import java.io.*;
 import java.lang.annotation.Annotation;
 import java.nio.channels.Channel;
@@ -44,6 +43,7 @@
 import libcore.util.TimeZoneDataFiles;
 
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 import sun.security.util.SecurityConstants;
 /**
  * The <code>System</code> class contains several useful class fields
@@ -1630,7 +1630,7 @@
      */
     @CallerSensitive
     public static void load(String filename) {
-        Runtime.getRuntime().load0(VMStack.getStackClass1(), filename);
+        Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
     }
 
     /**
@@ -1666,7 +1666,7 @@
      */
     @CallerSensitive
     public static void loadLibrary(String libname) {
-        Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libname);
+        Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index d462033..28b50a8 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -141,22 +141,33 @@
  */
 public
 class Thread implements Runnable {
-    /* Make sure registerNatives is the first thing <clinit> does. */
+    // Android-removed: registerNatives() not used on Android.
+    /*
+    /* Make sure registerNatives is the first thing <clinit> does. *
+    private static native void registerNatives();
+    static {
+        registerNatives();
+    }
+    */
 
+    // BEGIN Android-added: Android specific fields, lock, nativePeer.
     /**
      * The synchronization object responsible for this thread's join/sleep/park operations.
      */
     private final Object lock = new Object();
 
+    /**
+     * Reference to the native thread object.
+     *
+     * <p>Is 0 if the native thread has not yet been created/started, or has been destroyed.
+     */
     private volatile long nativePeer;
-
-    boolean started = false;
+    // END Android-added: Android specific fields, lock, nativePeer, started.
 
     private volatile String name;
-
-    private int         priority;
-    private Thread      threadQ;
-    private long        eetop;
+    private int            priority;
+    private Thread         threadQ;
+    private long           eetop;
 
     /* Whether or not to single_step this thread. */
     private boolean     single_step;
@@ -219,7 +230,22 @@
      * initialized to indicate thread 'not yet started'
      */
 
-    private volatile int threadStatus = 0;
+    // BEGIN Android-changed: Replace unused threadStatus field with started field.
+    // Upstream this is modified by the native code and read in the start() and getState() methods
+    // but in Android it is unused. The threadStatus is essentially an internal representation of
+    // the Thread.State enum. Android uses two sources for that information, the native thread
+    // state and the started field. The reason two sources are needed is because the native thread
+    // is created when the thread is started and destroyed when the thread is stopped. That means
+    // that the native thread state does not exist before the Thread has started (in State.NEW) or
+    // after it has been stopped (in State.TERMINATED). In that case (i.e. when the nativePeer = 0)
+    // the started field differentiates between the two states, i.e. if started = false then the
+    // thread is in State.NEW and if started = true then the thread is in State.TERMINATED.
+    // private volatile int threadStatus = 0;
+    /**
+     * True if the the Thread has been started, even it has since been stopped.
+     */
+    boolean started = false;
+    // END Android-changed: Replace unused threadStatus field with started field.
 
 
     private static synchronized long nextThreadID() {
@@ -241,11 +267,11 @@
     private volatile Interruptible blocker;
     private final Object blockerLock = new Object();
 
-    /**
-     * Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
-     *
+    /** Set the blocker field
      * @hide
      */
+    // Android-changed: Make blockedOn() @hide public, for internal use.
+    // Used by java.nio.channels.spi.AbstractInterruptibleChannel.
     public void blockedOn(Interruptible b) {
         synchronized (blockerLock) {
             blocker = b;
@@ -310,13 +336,15 @@
      *          <i>interrupted status</i> of the current thread is
      *          cleared when this exception is thrown.
      */
+    // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
     public static void sleep(long millis) throws InterruptedException {
-        Thread.sleep(millis, 0);
+        sleep(millis, 0);
     }
 
     @FastNative
     private static native void sleep(Object lock, long millis, int nanos)
         throws InterruptedException;
+    // END Android-changed: Implement sleep() methods using a shared native implementation.
 
     /**
      * Causes the currently executing thread to sleep (temporarily cease
@@ -342,6 +370,17 @@
      */
     public static void sleep(long millis, int nanos)
     throws InterruptedException {
+        // BEGIN Android-changed: Improve exception messages.
+        /*
+        if (millis < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+        */
         if (millis < 0) {
             throw new IllegalArgumentException("millis < 0: " + millis);
         }
@@ -351,7 +390,18 @@
         if (nanos > 999999) {
             throw new IllegalArgumentException("nanos > 999999: " + nanos);
         }
+        // END Android-changed: Improve exception messages.
 
+        // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+        // Attempt nanosecond rather than millisecond accuracy for sleep();
+        // RI code rounds to the nearest millisecond.
+        /*
+        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+            millis++;
+        }
+
+        sleep(millis);
+        */
         // The JLS 3rd edition, section 17.9 says: "...sleep for zero
         // time...need not have observable effects."
         if (millis == 0 && nanos == 0) {
@@ -367,7 +417,8 @@
 
         Object lock = currentThread().lock;
 
-        // Wait may return early, so loop until sleep duration passes.
+        // The native sleep(...) method actually performs a special type of wait, which may return
+        // early, so loop until sleep duration passes.
         synchronized (lock) {
             while (true) {
                 sleep(lock, millis, nanos);
@@ -385,6 +436,16 @@
                 nanos = (int) (duration % NANOS_PER_MILLI);
             }
         }
+        // END Android-changed: Implement sleep() methods using a shared native implementation.
+    }
+
+    /**
+     * Initializes a Thread with the current AccessControlContext.
+     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
+     */
+    private void init(ThreadGroup g, Runnable target, String name,
+                      long stackSize) {
+        init(g, target, name, stackSize, null);
     }
 
     /**
@@ -395,25 +456,83 @@
      * @param name the name of the new Thread
      * @param stackSize the desired stack size for the new thread, or
      *        zero to indicate that this parameter is to be ignored.
+     * @param acc the AccessControlContext to inherit, or
+     *            AccessController.getContext() if null
      */
-    private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
-        Thread parent = currentThread();
-        if (g == null) {
-            g = parent.getThreadGroup();
+    private void init(ThreadGroup g, Runnable target, String name,
+                      long stackSize, AccessControlContext acc) {
+        if (name == null) {
+            throw new NullPointerException("name cannot be null");
         }
 
+        this.name = name;
+
+        Thread parent = currentThread();
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager security = System.getSecurityManager();
+        if (g == null) {
+            // Android-changed: SecurityManager stubbed out on Android
+            /*
+            /* Determine if it's an applet or not *
+
+            /* If there is a security manager, ask the security manager
+               what to do. *
+            if (security != null) {
+                g = security.getThreadGroup();
+            }
+
+            /* If the security doesn't have a strong opinion of the matter
+               use the parent thread group. *
+            if (g == null) {
+            */
+                g = parent.getThreadGroup();
+            // }
+        }
+
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        /* checkAccess regardless of whether or not threadgroup is
+           explicitly passed in. *
+        g.checkAccess();
+
+        /*
+         * Do we have the required permissions?
+         *
+        if (security != null) {
+            if (isCCLOverridden(getClass())) {
+                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
+            }
+        }
+        */
+
         g.addUnstarted();
+
         this.group = g;
-
-        this.target = target;
-        this.priority = parent.getPriority();
         this.daemon = parent.isDaemon();
-        setName(name);
-
+        this.priority = parent.getPriority();
+        // Android-changed: Moved into init2(Thread) helper method.
+        /*
+        if (security == null || isCCLOverridden(parent.getClass()))
+            this.contextClassLoader = parent.getContextClassLoader();
+        else
+            this.contextClassLoader = parent.contextClassLoader;
+        this.inheritedAccessControlContext =
+                acc != null ? acc : AccessController.getContext();
+        */
+        this.target = target;
+        // Android-removed: The priority parameter is unchecked on Android.
+        // It is unclear why this is not being done (b/80180276).
+        // setPriority(priority);
+        // Android-changed: Moved into init2(Thread) helper method.
+        // if (parent.inheritableThreadLocals != null)
+        //     this.inheritableThreadLocals =
+        //         ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
         init2(parent);
 
         /* Stash the specified stack size in case the VM cares */
         this.stackSize = stackSize;
+
+        /* Set thread ID */
         tid = nextThreadID();
     }
 
@@ -457,6 +576,14 @@
     }
 
     /**
+     * Creates a new Thread that inherits the given AccessControlContext.
+     * This is not a public constructor.
+     */
+    Thread(Runnable target, AccessControlContext acc) {
+        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
+    }
+
+    /**
      * Allocates a new {@code Thread} object. This constructor has the same
      * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
      * {@code (group, target, gname)} ,where {@code gname} is a newly generated
@@ -519,7 +646,6 @@
         init(group, null, name, 0);
     }
 
-
     /** @hide */
     // Android-added: Private constructor - used by the runtime.
     Thread(ThreadGroup group, String name, int priority, boolean daemon) {
@@ -541,6 +667,7 @@
         tid = nextThreadID();
     }
 
+    // Android-added: Helper method for previous constructor and init(...) method.
     private void init2(Thread parent) {
         this.contextClassLoader = parent.getContextClassLoader();
         this.inheritedAccessControlContext = AccessController.getContext();
@@ -719,8 +846,9 @@
          *
          * A zero status value corresponds to state "NEW".
          */
-        // Android-changed: throw if 'started' is true
-        if (threadStatus != 0 || started)
+        // Android-changed: Replace unused threadStatus field with started field.
+        // The threadStatus field is unused on Android.
+        if (started)
             throw new IllegalThreadStateException();
 
         /* Notify the group that this thread is about to be started
@@ -728,8 +856,14 @@
          * and the group's unstarted count can be decremented. */
         group.add(this);
 
+        // Android-changed: Use field instead of local variable.
+        // It is necessary to remember the state of this across calls to this method so that it
+        // can throw an IllegalThreadStateException if this method is called on an already
+        // started thread.
         started = false;
         try {
+            // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+            // start0();
             nativeCreate(this, stackSize, daemon);
             started = true;
         } finally {
@@ -744,6 +878,11 @@
         }
     }
 
+    // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+    // The upstream native method start0() only takes a reference to this object and so must obtain
+    // the stack size and daemon status directly from the field whereas Android supplies the values
+    // explicitly on the method call.
+    // private native void start0();
     private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
 
     /**
@@ -784,54 +923,13 @@
         uncaughtExceptionHandler = null;
     }
 
+    // Android-changed: Throws UnsupportedOperationException.
     /**
-     * Forces the thread to stop executing.
-     * <p>
-     * If there is a security manager installed, its <code>checkAccess</code>
-     * method is called with <code>this</code>
-     * as its argument. This may result in a
-     * <code>SecurityException</code> being raised (in the current thread).
-     * <p>
-     * If this thread is different from the current thread (that is, the current
-     * thread is trying to stop a thread other than itself), the
-     * security manager's <code>checkPermission</code> method (with a
-     * <code>RuntimePermission("stopThread")</code> argument) is called in
-     * addition.
-     * Again, this may result in throwing a
-     * <code>SecurityException</code> (in the current thread).
-     * <p>
-     * The thread represented by this thread is forced to stop whatever
-     * it is doing abnormally and to throw a newly created
-     * <code>ThreadDeath</code> object as an exception.
-     * <p>
-     * It is permitted to stop a thread that has not yet been started.
-     * If the thread is eventually started, it immediately terminates.
-     * <p>
-     * An application should not normally try to catch
-     * <code>ThreadDeath</code> unless it must do some extraordinary
-     * cleanup operation (note that the throwing of
-     * <code>ThreadDeath</code> causes <code>finally</code> clauses of
-     * <code>try</code> statements to be executed before the thread
-     * officially dies).  If a <code>catch</code> clause catches a
-     * <code>ThreadDeath</code> object, it is important to rethrow the
-     * object so that the thread actually dies.
-     * <p>
-     * The top-level error handler that reacts to otherwise uncaught
-     * exceptions does not print out a message or otherwise notify the
-     * application if the uncaught exception is an instance of
-     * <code>ThreadDeath</code>.
+     * Throws {@code UnsupportedOperationException}.
      *
-     * @exception  SecurityException  if the current thread cannot
-     *               modify this thread.
-     * @see        #interrupt()
-     * @see        #checkAccess()
-     * @see        #run()
-     * @see        #start()
-     * @see        ThreadDeath
-     * @see        ThreadGroup#uncaughtException(Thread,Throwable)
-     * @see        SecurityManager#checkAccess(Thread)
-     * @see        SecurityManager#checkPermission
-     * @deprecated This method is inherently unsafe.  Stopping a thread with
+     * @deprecated This method was originally designed to force a thread to stop
+     *       and throw a {@code ThreadDeath} as an exception. It was inherently unsafe.
+     *       Stopping a thread with
      *       Thread.stop causes it to unlock all of the monitors that it
      *       has locked (as a natural consequence of the unchecked
      *       <code>ThreadDeath</code> exception propagating up the stack).  If
@@ -852,7 +950,24 @@
      */
     @Deprecated
     public final void stop() {
-        stop(new ThreadDeath());
+        /*
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            checkAccess();
+            if (this != Thread.currentThread()) {
+                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
+            }
+        }
+        // A zero status value corresponds to "NEW", it can't change to
+        // not-NEW because we hold the lock.
+        if (threadStatus != 0) {
+            resume(); // Wake up thread if it was suspended; no-op otherwise
+        }
+
+        // The VM can handle all thread states
+        stop0(new ThreadDeath());
+        */
+        throw new UnsupportedOperationException();
     }
 
     /**
@@ -870,7 +985,7 @@
      *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
     @Deprecated
-    public final void stop(Throwable obj) {
+    public final synchronized void stop(Throwable obj) {
         throw new UnsupportedOperationException();
     }
 
@@ -920,12 +1035,12 @@
         synchronized (blockerLock) {
             Interruptible b = blocker;
             if (b != null) {
-                nativeInterrupt();
+                interrupt0();           // Just to set the interrupt flag
                 b.interrupt(this);
                 return;
             }
         }
-        nativeInterrupt();
+        interrupt0();
     }
 
     /**
@@ -945,6 +1060,19 @@
      * @see #isInterrupted()
      * @revised 6.0
      */
+    // Android-changed: Use native interrupted()/isInterrupted() methods.
+    // Upstream has one native method for both these methods that takes a boolean parameter that
+    // determines whether the interrupted status of the thread should be cleared after reading
+    // it. While that approach does allow code reuse it is less efficient/more complex than having
+    // a native implementation of each method because:
+    // * The pure Java interrupted() method requires two native calls, one to get the current
+    //   thread and one to get its interrupted status.
+    // * Updating the interrupted flag is more complex than simply reading it. Knowing that only
+    //   the current thread can clear the interrupted status makes the code simpler as it does not
+    //   need to be concerned about multiple threads trying to clear the status simultaneously.
+    // public static boolean interrupted() {
+    //     return currentThread().isInterrupted(true);
+    // }
     @FastNative
     public static native boolean interrupted();
 
@@ -961,9 +1089,24 @@
      * @see     #interrupted()
      * @revised 6.0
      */
+    // Android-changed: Use native interrupted()/isInterrupted() methods.
+    // public boolean isInterrupted() {
+    //     return isInterrupted(false);
+    // }
     @FastNative
     public native boolean isInterrupted();
 
+    // Android-removed: Use native interrupted()/isInterrupted() methods.
+    /*
+    /**
+     * Tests if some Thread has been interrupted.  The interrupted state
+     * is reset or not based on the value of ClearInterrupted that is
+     * passed.
+     *
+    private native boolean isInterrupted(boolean ClearInterrupted);
+    */
+
+    // Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
     /**
      * Throws {@link UnsupportedOperationException}.
      *
@@ -981,8 +1124,6 @@
      *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      * @throws UnsupportedOperationException always
      */
-    // Android-changed: Throw UnsupportedOperationException instead of
-    // NoSuchMethodError.
     @Deprecated
     public void destroy() {
         throw new UnsupportedOperationException();
@@ -995,24 +1136,16 @@
      * @return  <code>true</code> if this thread is alive;
      *          <code>false</code> otherwise.
      */
+    // Android-changed: Provide pure Java implementation of isAlive().
     public final boolean isAlive() {
         return nativePeer != 0;
     }
 
+    // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
     /**
-     * Suspends this thread.
-     * <p>
-     * First, the <code>checkAccess</code> method of this thread is called
-     * with no arguments. This may result in throwing a
-     * <code>SecurityException </code>(in the current thread).
-     * <p>
-     * If the thread is alive, it is suspended and makes no further
-     * progress unless and until it is resumed.
+     * Throws {@link UnsupportedOperationException}.
      *
-     * @exception  SecurityException  if the current thread cannot modify
-     *               this thread.
-     * @see #checkAccess
-     * @deprecated   This method has been deprecated, as it is
+     * @deprecated   This method was designed to suspend the Thread but it was
      *   inherently deadlock-prone.  If the target thread holds a lock on the
      *   monitor protecting a critical system resource when it is suspended, no
      *   thread can access this resource until the target thread is resumed. If
@@ -1022,34 +1155,33 @@
      *   For more information, see
      *   <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     * @throws UnsupportedOperationException always
      */
     @Deprecated
     public final void suspend() {
+        // Android-changed: Unsupported on Android.
+        // checkAccess();
+        // suspend0();
+
         throw new UnsupportedOperationException();
     }
 
+    // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
     /**
-     * Resumes a suspended thread.
-     * <p>
-     * First, the <code>checkAccess</code> method of this thread is called
-     * with no arguments. This may result in throwing a
-     * <code>SecurityException</code> (in the current thread).
-     * <p>
-     * If the thread is alive but suspended, it is resumed and is
-     * permitted to make progress in its execution.
+     * Throws {@link UnsupportedOperationException}.
      *
-     * @exception  SecurityException  if the current thread cannot modify this
-     *               thread.
-     * @see        #checkAccess
-     * @see        #suspend()
      * @deprecated This method exists solely for use with {@link #suspend},
      *     which has been deprecated because it is deadlock-prone.
      *     For more information, see
      *     <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     * @throws UnsupportedOperationException always
      */
     @Deprecated
     public final void resume() {
+        // Android-changed: Unsupported on Android.
+        // checkAccess();
+        // resume0();
         throw new UnsupportedOperationException();
     }
 
@@ -1081,18 +1213,19 @@
         ThreadGroup g;
         checkAccess();
         if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
-            // Android-changed: Improve exception message when the new priority
-            // is out of bounds.
+            // Android-changed: Improve exception message when the new priority is out of bounds.
             throw new IllegalArgumentException("Priority out of range: " + newPriority);
         }
         if((g = getThreadGroup()) != null) {
             if (newPriority > g.getMaxPriority()) {
                 newPriority = g.getMaxPriority();
             }
+            // Android-changed: Avoid native call if Thread is not yet started.
+            // setPriority0(priority = newPriority);
             synchronized(this) {
                 this.priority = newPriority;
                 if (isAlive()) {
-                    nativeSetPriority(newPriority);
+                    setPriority0(newPriority);
                 }
             }
         }
@@ -1122,17 +1255,18 @@
      * @see        #getName
      * @see        #checkAccess()
      */
-    public final void setName(String name) {
+    public final synchronized void setName(String name) {
         checkAccess();
         if (name == null) {
-            throw new NullPointerException("name == null");
+            throw new NullPointerException("name cannot be null");
         }
 
-        synchronized (this) {
-            this.name = name;
-            if (isAlive()) {
-                nativeSetName(name);
-            }
+        this.name = name;
+        // Android-changed: Use isAlive() not threadStatus to check whether Thread has started.
+        // The threadStatus field is not used in Android.
+        // if (threadStatus != 0) {
+        if (isAlive()) {
+            setNativeName(name);
         }
     }
 
@@ -1154,10 +1288,15 @@
      * @return  this thread's thread group.
      */
     public final ThreadGroup getThreadGroup() {
-        // Android-changed: Return null if the thread is terminated.
+        // BEGIN Android-added: Work around exit() not being called.
+        // Android runtime does not call exit() when a Thread exits so the group field is not
+        // set to null so it needs to pretend as if it did. If we are not going to call exit()
+        // then this should probably just check isAlive() here rather than getState() as the
+        // latter requires a native call.
         if (getState() == Thread.State.TERMINATED) {
             return null;
         }
+        // END Android-added: Work around exit() not being called.
         return group;
     }
 
@@ -1223,6 +1362,8 @@
      *             were never well-defined.
      */
     @Deprecated
+    // Android-changed: Provide non-native implementation of countStackFrames().
+    // public native int countStackFrames();
     public int countStackFrames() {
         return getStackTrace().length;
     }
@@ -1248,7 +1389,10 @@
      *          <i>interrupted status</i> of the current thread is
      *          cleared when this exception is thrown.
      */
-    public final void join(long millis) throws InterruptedException {
+    // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+    // public final synchronized void join(long millis)
+    public final void join(long millis)
+    throws InterruptedException {
         synchronized(lock) {
         long base = System.currentTimeMillis();
         long now = 0;
@@ -1273,6 +1417,7 @@
         }
         }
     }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
 
     /**
      * Waits at most {@code millis} milliseconds plus
@@ -1299,8 +1444,11 @@
      *          <i>interrupted status</i> of the current thread is
      *          cleared when this exception is thrown.
      */
+    // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+    // public final synchronized void join(long millis, int nanos)
     public final void join(long millis, int nanos)
     throws InterruptedException {
+
         synchronized(lock) {
         if (millis < 0) {
             throw new IllegalArgumentException("timeout value is negative");
@@ -1318,6 +1466,7 @@
         join(millis);
         }
     }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
 
     /**
      * Waits for this thread to die.
@@ -1397,6 +1546,11 @@
      * @see        SecurityManager#checkAccess(Thread)
      */
     public final void checkAccess() {
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager security = System.getSecurityManager();
+        // if (security != null) {
+        //     security.checkAccess(this);
+        // }
     }
 
     /**
@@ -1444,6 +1598,16 @@
      */
     @CallerSensitive
     public ClassLoader getContextClassLoader() {
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        if (contextClassLoader == null)
+            return null;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            ClassLoader.checkClassLoaderPermission(contextClassLoader,
+                                                   Reflection.getCallerClass());
+        }
+        */
         return contextClassLoader;
     }
 
@@ -1470,6 +1634,11 @@
      * @since 1.2
      */
     public void setContextClassLoader(ClassLoader cl) {
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm != null) {
+        //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+        // }
         contextClassLoader = cl;
     }
 
@@ -1489,11 +1658,7 @@
      *         the specified object.
      * @since 1.4
      */
-    public static boolean holdsLock(Object obj) {
-        return currentThread().nativeHoldsLock(obj);
-    }
-
-    private native boolean nativeHoldsLock(Object object);
+    public static native boolean holdsLock(Object obj);
 
     private static final StackTraceElement[] EMPTY_STACK_TRACE
         = new StackTraceElement[0];
@@ -1535,6 +1700,7 @@
      * @since 1.5
      */
     public StackTraceElement[] getStackTrace() {
+        // Android-changed: Use native VMStack to get stack trace.
         StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
         return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
     }
@@ -1575,20 +1741,47 @@
      * @since 1.5
      */
     public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
-        Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        // check for getStackTrace permission
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(
+                SecurityConstants.GET_STACK_TRACE_PERMISSION);
+            security.checkPermission(
+                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+        }
+        */
 
-        // Find out how many live threads we have. Allocate a bit more
-        // space than needed, in case new ones are just being created.
+        // Get a snapshot of the list of all threads
+        // BEGIN Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+        // Allocate a bit more space than needed, in case new ones are just being created.
+        /*
+        Thread[] threads = getThreads();
+        StackTraceElement[][] traces = dumpThreads(threads);
+        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
+        for (int i = 0; i < threads.length; i++) {
+            StackTraceElement[] stackTrace = traces[i];
+            if (stackTrace != null) {
+                m.put(threads[i], stackTrace);
+            }
+            // else terminated so we don't put it in the map
+        }
+        */
         int count = ThreadGroup.systemThreadGroup.activeCount();
         Thread[] threads = new Thread[count + count / 2];
 
-        // Enumerate the threads and collect the stacktraces.
+        // Enumerate the threads.
         count = ThreadGroup.systemThreadGroup.enumerate(threads);
-        for (int i = 0; i < count; i++) {
-            map.put(threads[i], threads[i].getStackTrace());
-        }
 
-        return map;
+        // Collect the stacktraces
+        Map<Thread, StackTraceElement[]> m = new HashMap<Thread, StackTraceElement[]>();
+        for (int i = 0; i < count; i++) {
+            StackTraceElement[] stackTrace = threads[i].getStackTrace();
+            m.put(threads[i], stackTrace);
+        }
+        // END Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+        return m;
     }
 
 
@@ -1661,6 +1854,10 @@
         return result.booleanValue();
     }
 
+    // Android-removed: Native methods that are unused on Android.
+    // private native static StackTraceElement[][] dumpThreads(Thread[] threads);
+    // private native static Thread[] getThreads();
+
     /**
      * Returns the identifier of this Thread.  The thread ID is a positive
      * <tt>long</tt> number generated when this thread was created.
@@ -1783,6 +1980,10 @@
      */
     public State getState() {
         // get current thread state
+        // Android-changed: Replace unused threadStatus field with started field.
+        // Use Android specific nativeGetStatus() method. See comment on started field for more
+        // information.
+        // return sun.misc.VM.toThreadState(threadStatus);
         return State.values()[nativeGetStatus(started)];
     }
 
@@ -1864,6 +2065,16 @@
      * @since 1.5
      */
     public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(
+                new RuntimePermission("setDefaultUncaughtExceptionHandler")
+                    );
+        }
+        */
+
          defaultUncaughtExceptionHandler = eh;
      }
 
@@ -1879,7 +2090,8 @@
         return defaultUncaughtExceptionHandler;
     }
 
-    // Android-changed: Added concept of an uncaughtExceptionPreHandler for use by platform.
+    // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
+    // See http://b/29624607 for background information.
     // null unless explicitly set
     private static volatile UncaughtExceptionHandler uncaughtExceptionPreHandler;
 
@@ -1890,7 +2102,8 @@
      * throwables thrown by the handler will be ignored by
      * {@link #dispatchUncaughtException(Throwable)}.
      *
-     * @hide only for use by the Android framework (RuntimeInit) b/29624607
+     * @hide used when configuring the runtime for exception logging; see
+     *     {@link dalvik.system.RuntimeHooks} b/29624607
      */
     public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) {
         uncaughtExceptionPreHandler = eh;
@@ -1900,6 +2113,7 @@
     public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
         return uncaughtExceptionPreHandler;
     }
+    // END Android-added: uncaughtExceptionPreHandler for use by platform.
 
     /**
      * Returns the handler invoked when this thread abruptly terminates
@@ -1941,8 +2155,9 @@
      *
      * @hide
      */
-    // @VisibleForTesting (would be package-private if not for tests)
+    // Android-changed: Make dispatchUncaughtException() public, for use by tests.
     public final void dispatchUncaughtException(Throwable e) {
+        // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
         Thread.UncaughtExceptionHandler initialUeh =
                 Thread.getUncaughtExceptionPreHandler();
         if (initialUeh != null) {
@@ -1952,6 +2167,7 @@
                 // Throwables thrown by the initial handler are ignored
             }
         }
+        // END Android-added: uncaughtExceptionPreHandler for use by platform.
         getUncaughtExceptionHandler().uncaughtException(this, e);
     }
 
@@ -2024,6 +2240,7 @@
     // concurrent code, and we can not risk accidental false sharing.
     // Hence, the fields are isolated with @Contended.
 
+    // BEGIN Android-changed: @sun.misc.Contended is not supported on Android.
     /** The current seed for a ThreadLocalRandom */
     // @sun.misc.Contended("tlr")
     long threadLocalRandomSeed;
@@ -2035,17 +2252,27 @@
     /** Secondary seed isolated from public ThreadLocalRandom sequence */
     //  @sun.misc.Contended("tlr")
     int threadLocalRandomSecondarySeed;
+    // END Android-changed: @sun.misc.Contended is not supported on Android.
 
     /* Some private helper methods */
-    private native void nativeSetName(String newName);
+    private native void setPriority0(int newPriority);
 
-    private native void nativeSetPriority(int newPriority);
-
-    private native int nativeGetStatus(boolean hasBeenStarted);
+    // BEGIN Android-removed: Native methods that are unused on Android.
+    /*
+    private native void stop0(Object o);
+    private native void suspend0();
+    private native void resume0();
+    */
+    // END Android-removed: Native methods that are unused on Android.
 
     @FastNative
-    private native void nativeInterrupt();
+    private native void interrupt0();
+    private native void setNativeName(String name);
 
+    // Android-added: Android specific nativeGetStatus() method.
+    private native int nativeGetStatus(boolean hasBeenStarted);
+
+    // BEGIN Android-added: Support for parking threads, used by Unsafe.park()/unpark().
     /** Park states */
     private static class ParkState {
         /** park state indicating unparked */
@@ -2209,4 +2436,5 @@
         }
         }
     }
+    // END Android-added: Support for parking threads, used by Unsafe.park()/unpark().
 }
diff --git a/ojluni/src/main/java/java/lang/ThreadGroup.java b/ojluni/src/main/java/java/lang/ThreadGroup.java
index 521c3c3..292b536 100644
--- a/ojluni/src/main/java/java/lang/ThreadGroup.java
+++ b/ojluni/src/main/java/java/lang/ThreadGroup.java
@@ -261,14 +261,13 @@
      * @see        java.lang.ThreadGroup#checkAccess()
      * @since      JDK1.0
      */
-    // Android-changed: We clamp the priority to the range [MIN_PRIORITY, MAX_PRIORITY]
-    // before using it.
     public final void setMaxPriority(int pri) {
         int ngroupsSnapshot;
         ThreadGroup[] groupsSnapshot;
         synchronized (this) {
             checkAccess();
-            // Android-changed: Clamp to MIN_PRIORITY, MAX_PRIORITY.
+            // BEGIN Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+            // This preserves backward compatibility with previous versions of Android.
             // if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
             //     return;
             // }
@@ -278,6 +277,7 @@
             if (pri > Thread.MAX_PRIORITY) {
                 pri = Thread.MAX_PRIORITY;
             }
+            // END Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
 
             maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri;
             ngroupsSnapshot = ngroups;
@@ -325,6 +325,11 @@
      * @since      JDK1.0
      */
     public final void checkAccess() {
+        // Android-removed: SecurityManager stubbed out on Android.
+        // SecurityManager security = System.getSecurityManager();
+        // if (security != null) {
+        //     security.checkAccess(this);
+        // }
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
index cd09322..13d719b 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
@@ -419,18 +419,8 @@
  * @author John Rose, JSR 292 EG
  */
 public abstract class MethodHandle {
-    // Android-changed:
-    //
+    // Android-removed: MethodHandleImpl.initStatics() unused on Android.
     // static { MethodHandleImpl.initStatics(); }
-    //
-    // LambdaForm and customizationCount are currently unused in our implementation
-    // and will be substituted with appropriate implementation / delegate classes.
-    //
-    // /*private*/ final LambdaForm form;
-    // form is not private so that invokers can easily fetch it
-    // /*non-public*/ byte customizationCount;
-    // customizationCount should be accessible from invokers
-
 
     /**
      * Internal marker interface which distinguishes (to the Java compiler)
@@ -440,14 +430,32 @@
      */
     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+    // Android-changed: Made public @hide as otherwise it breaks the stubs generation.
+    // @interface PolymorphicSignature { }
     public @interface PolymorphicSignature { }
 
+    // Android-added: Comment to differentiate between type and nominalType.
     /**
      * The type of this method handle, this corresponds to the exact type of the method
      * being invoked.
+     * 
+     * @see #nominalType
      */
     private final MethodType type;
+    // Android-removed: LambdaForm and customizationCount unused on Android.
+    // They will be substituted with appropriate implementation / delegate classes.
+    /*
+    /*private* final LambdaForm form;
+    // form is not private so that invokers can easily fetch it
+    /*private* MethodHandle asTypeCache;
+    // asTypeCache is not private so that invokers can easily fetch it
+    /*non-public* byte customizationCount;
+    // customizationCount should be accessible from invokers
+    */
 
+    // BEGIN Android-added: Android specific implementation.
+    // The MethodHandle functionality is tightly coupled with internal details of the runtime and
+    // so Android has a completely different implementation compared to the RI.
     /**
      * The nominal type of this method handle, will be non-null if a method handle declares
      * a different type from its "real" type, which is either the type of the method being invoked
@@ -506,6 +514,7 @@
         this.handleKind = handleKind;
         this.type = type;
     }
+    // END Android-added: Android specific implementation.
 
     /**
      * Reports the type of this method handle.
@@ -513,6 +522,7 @@
      * @return the method handle type
      */
     public MethodType type() {
+        // Android-added: Added nominalType field.
         if (nominalType != null) {
             return nominalType;
         }
@@ -520,6 +530,25 @@
         return type;
     }
 
+    // BEGIN Android-removed: LambdaForm unsupported on Android.
+    /*
+    /**
+     * Package-private constructor for the method handle implementation hierarchy.
+     * Method handle inheritance will be contained completely within
+     * the {@code java.lang.invoke} package.
+     *
+    // @param type type (permanently assigned) of the new method handle
+    /*non-public* MethodHandle(MethodType type, LambdaForm form) {
+        type.getClass();  // explicit NPE
+        form.getClass();  // explicit NPE
+        this.type = type;
+        this.form = form.uncustomize();
+
+        this.form.prepare();  // TO DO:  Try to delay this step until just before invocation.
+    }
+    */
+    // END Android-removed: LambdaForm unsupported on Android.
+
     /**
      * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
      * The symbolic type descriptor at the call site of {@code invokeExact} must
@@ -576,13 +605,64 @@
      */
     public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
 
-    // Android-changed: Removed implementation details.
-    //
-    // /*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args)
-    // /*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args)
-    // /*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args)
-    // /*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args)
-    // /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args)
+    // BEGIN Android-removed: RI implementation unused on Android.
+    /*
+    /**
+     * Private method for trusted invocation of a method handle respecting simplified signatures.
+     * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
+     * <p>
+     * The caller signature is restricted to the following basic types:
+     * Object, int, long, float, double, and void return.
+     * <p>
+     * The caller is responsible for maintaining type correctness by ensuring
+     * that the each outgoing argument value is a member of the range of the corresponding
+     * callee argument type.
+     * (The caller should therefore issue appropriate casts and integer narrowing
+     * operations on outgoing argument values.)
+     * The caller can assume that the incoming result value is part of the range
+     * of the callee's return type.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+    */
+    // END Android-removed: RI implementation unused on Android.
 
     /**
      * Performs a variable arity invocation, passing the arguments in the given list
@@ -635,6 +715,9 @@
      * @see MethodHandles#spreadInvoker
      */
     public Object invokeWithArguments(Object... arguments) throws Throwable {
+        // BEGIN Android-changed: Android specific implementation.
+        // MethodType invocationType = MethodType.genericMethodType(arguments == null ? 0 : arguments.length);
+        // return invocationType.invokers().spreadInvoker(0).invokeExact(asType(invocationType), arguments);
         MethodHandle invoker = null;
         synchronized (this) {
             if (cachedSpreadInvoker == null) {
@@ -645,6 +728,7 @@
         }
 
         return invoker.invoke(this, arguments);
+        // END Android-changed: Android specific implementation.
     }
 
     /**
@@ -773,14 +857,38 @@
         if (newType == type) {
             return this;
         }
-
-        if (!type.isConvertibleTo(newType)) {
-            throw new WrongMethodTypeException("cannot convert " + this + " to " + newType);
+        // Android-removed: Type conversion memoizing is unsupported on Android.
+        /*
+        // Return 'this.asTypeCache' if the conversion is already memoized.
+        MethodHandle atc = asTypeCached(newType);
+        if (atc != null) {
+            return atc;
         }
+        */
+        return asTypeUncached(newType);
+    }
 
+    // Android-removed: Type conversion memoizing is unsupported on Android.
+    /*
+    private MethodHandle asTypeCached(MethodType newType) {
+        MethodHandle atc = asTypeCache;
+        if (atc != null && newType == atc.type) {
+            return atc;
+        }
+        return null;
+    }
+    */
+
+    /** Override this to change asType behavior. */
+    /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+        if (!type.isConvertibleTo(newType))
+            throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
+        // BEGIN Android-changed: Android specific implementation.
+        // return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
         MethodHandle mh = duplicate();
         mh.nominalType = newType;
         return mh;
+        // END Android-changed: Android specific implementation.
     }
 
     /**
@@ -874,13 +982,23 @@
      */
     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
         MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
-
+        // BEGIN Android-changed: Android specific implementation.
+        /*
+        int arity = type().parameterCount();
+        int spreadArgPos = arity - arrayLength;
+        MethodHandle afterSpread = this.asType(postSpreadType);
+        BoundMethodHandle mh = afterSpread.rebind();
+        LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
+        MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
+        return mh.copyWith(preSpreadType, lform);
+        */
         final int targetParamCount = postSpreadType.parameterCount();
         MethodType dropArrayArgs = postSpreadType.dropParameterTypes(
                 (targetParamCount - arrayLength), targetParamCount);
         MethodType adapterType = dropArrayArgs.appendParameterTypes(arrayType);
 
         return new Transformers.Spreader(this, adapterType, arrayLength);
+        // END Android-changed: Android specific implementation.
     }
 
     /**
@@ -1000,8 +1118,21 @@
      */
     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
         asCollectorChecks(arrayType, arrayLength);
-
+        // BEGIN Android-changed: Android specific implementation.
+        /*
+        int collectArgPos = type().parameterCount() - 1;
+        BoundMethodHandle mh = rebind();
+        MethodType resultType = type().asCollectorType(arrayType, arrayLength);
+        MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
+        LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
+        if (lform != null) {
+            return mh.copyWith(resultType, lform);
+        }
+        lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
+        return mh.copyWithExtendL(resultType, lform, newArray);
+        */
         return new Transformers.Collector(this, arrayType, arrayLength);
+        // END Android-changed: Android specific implementation.
     }
 
     /**
@@ -1174,7 +1305,8 @@
         boolean lastMatch = asCollectorChecks(arrayType, 0);
         if (isVarargsCollector() && lastMatch)
             return this;
-
+        // Android-changed: Android specific implementation.
+        // return MethodHandleImpl.makeVarargsCollector(this, arrayType);
         return new Transformers.VarargsCollector(this);
     }
 
@@ -1241,13 +1373,17 @@
      * @see #isVarargsCollector
      */
     public MethodHandle asFixedArity() {
-        // Android-changed: implementation specific.
+        // BEGIN Android-changed: Android specific implementation.
+        // assert(!isVarargsCollector());
+        // return this;
+
         MethodHandle mh = this;
         if (mh.isVarargsCollector()) {
             mh = ((Transformers.VarargsCollector) mh).asFixedArity();
         }
         assert(!mh.isVarargsCollector());
         return mh;
+        // END Android-changed: Android specific implementation.
     }
 
     /**
@@ -1279,7 +1415,8 @@
      */
     public MethodHandle bindTo(Object x) {
         x = type.leadingReferenceParameter().cast(x);  // throw CCE if needed
-
+        // Android-changed: Android specific implementation.
+        // return bindArgumentL(0, x);
         return new Transformers.BindTo(this, x);
     }
 
@@ -1300,10 +1437,26 @@
      */
     @Override
     public String toString() {
-        // Android-changed: Removed debugging support.
+        // Android-removed: Debugging support unused on Android.
+        // if (DEBUG_METHOD_HANDLE_NAMES)  return "MethodHandle"+debugString();
+        return standardString();
+    }
+    String standardString() {
         return "MethodHandle"+type;
     }
 
+    // BEGIN Android-removed: Debugging support unused on Android.
+    /*
+    /** Return a string with a several lines describing the method handle structure.
+     *  This string would be suitable for display in an IDE debugger.
+     *
+    String debugString() {
+        return type+" : "+internalForm()+internalProperties();
+    }
+    */
+    // END Android-removed: Debugging support unused on Android. 
+
+    // BEGIN Android-added: Android specific implementation.
     /** @hide */
     public int getHandleKind() {
         return handleKind;
@@ -1327,7 +1480,6 @@
         }
     }
 
-
     /**
      * This is the entry point for all transform calls, and dispatches to the protected
      * transform method. This layer of indirection exists purely for convenience, because
@@ -1339,41 +1491,156 @@
     private void transformInternal(EmulatedStackFrame arguments) throws Throwable {
         transform(arguments);
     }
+    // END Android-added: Android specific implementation.
 
-    // Android-changed: Removed implementation details :
-    //
-    // String standardString();
-    // String debugString();
-    //
+    // BEGIN Android-removed: RI implementation unused on Android.
+    /*
     //// Implementation methods.
     //// Sub-classes can override these default implementations.
     //// All these methods assume arguments are already validated.
-    //
+
     // Other transforms to do:  convert, explicitCast, permute, drop, filter, fold, GWT, catch
-    //
-    // BoundMethodHandle bindArgumentL(int pos, Object value);
-    // /*non-public*/ MethodHandle setVarargs(MemberName member);
-    // /*non-public*/ MethodHandle viewAsType(MethodType newType, boolean strict);
-    // /*non-public*/ boolean viewAsTypeChecks(MethodType newType, boolean strict);
-    //
+
+    BoundMethodHandle bindArgumentL(int pos, Object value) {
+        return rebind().bindArgumentL(pos, value);
+    }
+
+    /*non-public*
+    MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+        if (!member.isVarargs())  return this;
+        Class<?> arrayType = type().lastParameterType();
+        if (arrayType.isArray()) {
+            return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+        }
+        throw member.makeAccessException("cannot make variable arity", null);
+    }
+
+    /*non-public*
+    MethodHandle viewAsType(MethodType newType, boolean strict) {
+        // No actual conversions, just a new view of the same method.
+        // Note that this operation must not produce a DirectMethodHandle,
+        // because retyped DMHs, like any transformed MHs,
+        // cannot be cracked into MethodHandleInfo.
+        assert viewAsTypeChecks(newType, strict);
+        BoundMethodHandle mh = rebind();
+        assert(!((MethodHandle)mh instanceof DirectMethodHandle));
+        return mh.copyWith(newType, mh.form);
+    }
+
+    /*non-public*
+    boolean viewAsTypeChecks(MethodType newType, boolean strict) {
+        if (strict) {
+            assert(type().isViewableAs(newType, true))
+                : Arrays.asList(this, newType);
+        } else {
+            assert(type().basicType().isViewableAs(newType.basicType(), true))
+                : Arrays.asList(this, newType);
+        }
+        return true;
+    }
+
     // Decoding
-    //
-    // /*non-public*/ LambdaForm internalForm();
-    // /*non-public*/ MemberName internalMemberName();
-    // /*non-public*/ Class<?> internalCallerClass();
-    // /*non-public*/ MethodHandleImpl.Intrinsic intrinsicName();
-    // /*non-public*/ MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial);
-    // /*non-public*/ boolean isInvokeSpecial();
-    // /*non-public*/ Object internalValues();
-    // /*non-public*/ Object internalProperties();
-    //
+
+    /*non-public*
+    LambdaForm internalForm() {
+        return form;
+    }
+
+    /*non-public*
+    MemberName internalMemberName() {
+        return null;  // DMH returns DMH.member
+    }
+
+    /*non-public*
+    Class<?> internalCallerClass() {
+        return null;  // caller-bound MH for @CallerSensitive method returns caller
+    }
+
+    /*non-public*
+    MethodHandleImpl.Intrinsic intrinsicName() {
+        // no special intrinsic meaning to most MHs
+        return MethodHandleImpl.Intrinsic.NONE;
+    }
+
+    /*non-public*
+    MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
+        if (member != null) {
+            return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
+        } else if (internalMemberName() == null) {
+            // The required internaMemberName is null, and this MH (like most) doesn't have one.
+            return this;
+        } else {
+            // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
+            MethodHandle result = rebind();
+            assert (result.internalMemberName() == null);
+            return result;
+        }
+    }
+
+    /*non-public*
+    boolean isInvokeSpecial() {
+        return false;  // DMH.Special returns true
+    }
+
+    /*non-public*
+    Object internalValues() {
+        return null;
+    }
+
+    /*non-public*
+    Object internalProperties() {
+        // Override to something to follow this.form, like "\n& FOO=bar"
+        return "";
+    }
+
     //// Method handle implementation methods.
     //// Sub-classes can override these default implementations.
     //// All these methods assume arguments are already validated.
-    //
-    // /*non-public*/ abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
-    // abstract BoundMethodHandle rebind();
-    // /*non-public*/ void updateForm(LambdaForm newForm);
-    // /*non-public*/ void customize();
-    // private static final long FORM_OFFSET;
+
+    /*non-public*
+    abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
+
+    /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
+     *  Many transforms are implemented only for BMHs.
+     *  @return a behaviorally equivalent BMH
+     *
+    abstract BoundMethodHandle rebind();
+
+    /**
+     * Replace the old lambda form of this method handle with a new one.
+     * The new one must be functionally equivalent to the old one.
+     * Threads may continue running the old form indefinitely,
+     * but it is likely that the new one will be preferred for new executions.
+     * Use with discretion.
+     *
+    /*non-public*
+    void updateForm(LambdaForm newForm) {
+        assert(newForm.customized == null || newForm.customized == this);
+        if (form == newForm)  return;
+        newForm.prepare();  // as in MethodHandle.<init>
+        UNSAFE.putObject(this, FORM_OFFSET, newForm);
+        UNSAFE.fullFence();
+    }
+
+    /** Craft a LambdaForm customized for this particular MethodHandle *
+    /*non-public*
+    void customize() {
+        if (form.customized == null) {
+            LambdaForm newForm = form.customize(this);
+            updateForm(newForm);
+        } else {
+            assert(form.customized == this);
+        }
+    }
+
+    private static final long FORM_OFFSET;
+    static {
+        try {
+            FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+    */
+    // END Android-removed: RI implementation unused on Android.
 }
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
index b037716..6514cb6 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java
@@ -1,11 +1,12 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * 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.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
@@ -25,6 +26,10 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
+// Android-changed: Android specific implementation.
+// The whole class was implemented from scratch for the Android runtime based
+// on the specification of the MethodHandle class.
+// The code does not originate from upstream OpenJDK.
 /**
  * A method handle that's directly associated with an ArtField or an ArtMethod and
  * specifies no additional transformations.
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
index e24bc68..2746d4a 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java
@@ -27,6 +27,7 @@
 
 import java.lang.reflect.*;
 import java.util.*;
+import java.lang.invoke.MethodHandleNatives.Constants;
 import java.lang.invoke.MethodHandles.Lookup;
 import static java.lang.invoke.MethodHandleStatics.*;
 
@@ -127,17 +128,16 @@
      * A direct method handle reference kind,
      * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
      */
-    // Android-changed: Inlined the values of these constants from MethodHandleNatives.Constants.
     public static final int
-        REF_getField                = 1,
-        REF_getStatic               = 2,
-        REF_putField                = 3,
-        REF_putStatic               = 4,
-        REF_invokeVirtual           = 5,
-        REF_invokeStatic            = 6,
-        REF_invokeSpecial           = 7,
-        REF_newInvokeSpecial        = 8,
-        REF_invokeInterface         = 9;
+        REF_getField                = Constants.REF_getField,
+        REF_getStatic               = Constants.REF_getStatic,
+        REF_putField                = Constants.REF_putField,
+        REF_putStatic               = Constants.REF_putStatic,
+        REF_invokeVirtual           = Constants.REF_invokeVirtual,
+        REF_invokeStatic            = Constants.REF_invokeStatic,
+        REF_invokeSpecial           = Constants.REF_invokeSpecial,
+        REF_newInvokeSpecial        = Constants.REF_newInvokeSpecial,
+        REF_invokeInterface         = Constants.REF_invokeInterface;
 
     /**
      * Returns the reference kind of the cracked method handle, which in turn
@@ -224,13 +224,11 @@
     // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
     public default boolean isVarArgs()  {
         // fields are never varargs:
-        if (refKindIsField(getReferenceKind()))
+        if (MethodHandleNatives.refKindIsField((byte) getReferenceKind()))
             return false;
         // not in the public API: Modifier.VARARGS
         final int ACC_VARARGS = 0x00000080;  // from JVMS 4.6 (Table 4.20)
-
-        // Android-changed: Removed assert() due to http://b/30862573
-        // assert(ACC_VARARGS == Modifier.TRANSIENT);
+        assert(ACC_VARARGS == Modifier.TRANSIENT);
         return Modifier.isTransient(getModifiers());
     }
 
@@ -244,9 +242,9 @@
      *            <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
      */
     public static String referenceKindToString(int referenceKind) {
-        if (!refKindIsValid(referenceKind))
+        if (!MethodHandleNatives.refKindIsValid(referenceKind))
             throw newIllegalArgumentException("invalid reference kind", referenceKind);
-        return refKindName(referenceKind);
+        return MethodHandleNatives.refKindName((byte)referenceKind);
     }
 
     /**
@@ -284,31 +282,22 @@
         return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type);
     }
 
-    // Android-changed: Inlined from MethodHandleNatives and changed to avoid references to
-    // REF_NONE and REF_LIMITED
+    // BEGIN Android-added: refKind...() methods needed for API compatibility with 26.
+    // These methods were accidentally added into the public API in API level 26 and so cannot be
+    // removed.
     static boolean refKindIsValid(int refKind) {
-        return (refKind >= REF_getField && refKind <= REF_invokeInterface);
+        return MethodHandleNatives.refKindIsValid(refKind);
     }
 
     // Android-changed: Inlined from MethodHandleNatives.
     static boolean refKindIsField(int refKind) {
-        return (refKind <= REF_putStatic);
+        return MethodHandleNatives.refKindIsField((byte) refKind);
     }
 
     // Android-changed: Inlined from MethodHandleNatives and replaced 'byte' argument with
     // 'int'.
     static String refKindName(int refKind) {
-        switch (refKind) {
-            case REF_getField:          return "getField";
-            case REF_getStatic:         return "getStatic";
-            case REF_putField:          return "putField";
-            case REF_putStatic:         return "putStatic";
-            case REF_invokeVirtual:     return "invokeVirtual";
-            case REF_invokeStatic:      return "invokeStatic";
-            case REF_invokeSpecial:     return "invokeSpecial";
-            case REF_newInvokeSpecial:  return "newInvokeSpecial";
-            case REF_invokeInterface:   return "invokeInterface";
-            default:                    return "REF_???";
-        }
+        return MethodHandleNatives.refKindName((byte) refKind);
     }
+    // END Android-added: refKind...() methods needed for API compatibility with 26.
 }
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java
new file mode 100644
index 0000000..87f95ff
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The JVM interface for the method handles package is all here.
+ * This is an interface internal and private to an implementation of JSR 292.
+ * <em>This class is not part of the JSR 292 standard.</em>
+ * @author jrose
+ */
+class MethodHandleNatives {
+
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    private MethodHandleNatives() { } // static only
+
+    /// MemberName support
+
+    static native void init(MemberName self, Object ref);
+    static native void expand(MemberName self);
+    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
+    static native int getMembers(Class<?> defc, String matchName, String matchSig,
+            int matchFlags, Class<?> caller, int skip, MemberName[] results);
+
+    /// Field layout queries parallel to sun.misc.Unsafe:
+    static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
+    static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
+
+    /// MethodHandle support
+
+    /** Fetch MH-related JVM parameter.
+     *  which=0 retrieves MethodHandlePushLimit
+     *  which=1 retrieves stack slot push size (in address units)
+     *
+    static native int getConstant(int which);
+
+    static final boolean COUNT_GWT;
+
+    /// CallSite support
+
+    /** Tell the JVM that we need to change the target of a CallSite. *
+    static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
+    static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+
+    private static native void registerNatives();
+    static {
+        registerNatives();
+        COUNT_GWT                   = getConstant(Constants.GC_COUNT_GWT) != 0;
+
+        // The JVM calls MethodHandleNatives.<clinit>.  Cascade the <clinit> calls as needed:
+        MethodHandleImpl.initStatics();
+    }
+    */
+    // END Android-removed: Unused implementation code.
+
+    // All compile-time constants go here.
+    // There is an opportunity to check them against the JVM's idea of them.
+    static class Constants {
+        Constants() { } // static only
+        // BEGIN Android-removed: Unused implementation code.
+        /*
+        // MethodHandleImpl
+        static final int // for getConstant
+                GC_COUNT_GWT = 4,
+                GC_LAMBDA_SUPPORT = 5;
+
+        // MemberName
+        // The JVM uses values of -2 and above for vtable indexes.
+        // Field values are simple positive offsets.
+        // Ref: src/share/vm/oops/methodOop.hpp
+        // This value is negative enough to avoid such numbers,
+        // but not too negative.
+        static final int
+                MN_IS_METHOD           = 0x00010000, // method (not constructor)
+                MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
+                MN_IS_FIELD            = 0x00040000, // field
+                MN_IS_TYPE             = 0x00080000, // nested type
+                MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
+                MN_REFERENCE_KIND_SHIFT = 24, // refKind
+                MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+                // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+                MN_SEARCH_SUPERCLASSES = 0x00100000,
+                MN_SEARCH_INTERFACES   = 0x00200000;
+
+        /**
+         * Basic types as encoded in the JVM.  These code values are not
+         * intended for use outside this class.  They are used as part of
+         * a private interface between the JVM and this class.
+         *
+        static final int
+            T_BOOLEAN  =  4,
+            T_CHAR     =  5,
+            T_FLOAT    =  6,
+            T_DOUBLE   =  7,
+            T_BYTE     =  8,
+            T_SHORT    =  9,
+            T_INT      = 10,
+            T_LONG     = 11,
+            T_OBJECT   = 12,
+            //T_ARRAY    = 13
+            T_VOID     = 14,
+            //T_ADDRESS  = 15
+            T_ILLEGAL  = 99;
+
+        /**
+         * Constant pool entry types.
+         *
+        static final byte
+            CONSTANT_Utf8                = 1,
+            CONSTANT_Integer             = 3,
+            CONSTANT_Float               = 4,
+            CONSTANT_Long                = 5,
+            CONSTANT_Double              = 6,
+            CONSTANT_Class               = 7,
+            CONSTANT_String              = 8,
+            CONSTANT_Fieldref            = 9,
+            CONSTANT_Methodref           = 10,
+            CONSTANT_InterfaceMethodref  = 11,
+            CONSTANT_NameAndType         = 12,
+            CONSTANT_MethodHandle        = 15,  // JSR 292
+            CONSTANT_MethodType          = 16,  // JSR 292
+            CONSTANT_InvokeDynamic       = 18,
+            CONSTANT_LIMIT               = 19;   // Limit to tags found in classfiles
+
+        /**
+         * Access modifier flags.
+         *
+        static final char
+            ACC_PUBLIC                 = 0x0001,
+            ACC_PRIVATE                = 0x0002,
+            ACC_PROTECTED              = 0x0004,
+            ACC_STATIC                 = 0x0008,
+            ACC_FINAL                  = 0x0010,
+            ACC_SYNCHRONIZED           = 0x0020,
+            ACC_VOLATILE               = 0x0040,
+            ACC_TRANSIENT              = 0x0080,
+            ACC_NATIVE                 = 0x0100,
+            ACC_INTERFACE              = 0x0200,
+            ACC_ABSTRACT               = 0x0400,
+            ACC_STRICT                 = 0x0800,
+            ACC_SYNTHETIC              = 0x1000,
+            ACC_ANNOTATION             = 0x2000,
+            ACC_ENUM                   = 0x4000,
+            // aliases:
+            ACC_SUPER                  = ACC_SYNCHRONIZED,
+            ACC_BRIDGE                 = ACC_VOLATILE,
+            ACC_VARARGS                = ACC_TRANSIENT;
+        */
+        // END Android-removed: Unused implementation code.
+
+        /**
+         * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
+         */
+        static final byte
+            REF_NONE                    = 0,  // null value
+            REF_getField                = 1,
+            REF_getStatic               = 2,
+            REF_putField                = 3,
+            REF_putStatic               = 4,
+            REF_invokeVirtual           = 5,
+            REF_invokeStatic            = 6,
+            REF_invokeSpecial           = 7,
+            REF_newInvokeSpecial        = 8,
+            REF_invokeInterface         = 9,
+            REF_LIMIT                  = 10;
+    }
+
+    static boolean refKindIsValid(int refKind) {
+        return (refKind > REF_NONE && refKind < REF_LIMIT);
+    }
+    static boolean refKindIsField(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_putStatic);
+    }
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    static boolean refKindIsGetter(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_getStatic);
+    }
+    static boolean refKindIsSetter(byte refKind) {
+        return refKindIsField(refKind) && !refKindIsGetter(refKind);
+    }
+    static boolean refKindIsMethod(byte refKind) {
+        return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindIsConstructor(byte refKind) {
+        return (refKind == REF_newInvokeSpecial);
+    }
+    static boolean refKindHasReceiver(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind & 1) != 0;
+    }
+    static boolean refKindIsStatic(byte refKind) {
+        return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindDoesDispatch(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind == REF_invokeVirtual ||
+                refKind == REF_invokeInterface);
+    }
+    static {
+        final int HR_MASK = ((1 << REF_getField) |
+                             (1 << REF_putField) |
+                             (1 << REF_invokeVirtual) |
+                             (1 << REF_invokeSpecial) |
+                             (1 << REF_invokeInterface)
+                            );
+        for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
+            assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
+        }
+    }
+    */
+    // END Android-removed: Unused implementation code.
+    static String refKindName(byte refKind) {
+        assert(refKindIsValid(refKind));
+        switch (refKind) {
+        case REF_getField:          return "getField";
+        case REF_getStatic:         return "getStatic";
+        case REF_putField:          return "putField";
+        case REF_putStatic:         return "putStatic";
+        case REF_invokeVirtual:     return "invokeVirtual";
+        case REF_invokeStatic:      return "invokeStatic";
+        case REF_invokeSpecial:     return "invokeSpecial";
+        case REF_newInvokeSpecial:  return "newInvokeSpecial";
+        case REF_invokeInterface:   return "invokeInterface";
+        default:                    return "REF_???";
+        }
+    }
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    private static native int getNamedCon(int which, Object[] name);
+    static boolean verifyConstants() {
+        Object[] box = { null };
+        for (int i = 0; ; i++) {
+            box[0] = null;
+            int vmval = getNamedCon(i, box);
+            if (box[0] == null)  break;
+            String name = (String) box[0];
+            try {
+                Field con = Constants.class.getDeclaredField(name);
+                int jval = con.getInt(null);
+                if (jval == vmval)  continue;
+                String err = (name+": JVM has "+vmval+" while Java has "+jval);
+                if (name.equals("CONV_OP_LIMIT")) {
+                    System.err.println("warning: "+err);
+                    continue;
+                }
+                throw new InternalError(err);
+            } catch (NoSuchFieldException | IllegalAccessException ex) {
+                String err = (name+": JVM has "+vmval+" which Java does not define");
+                // ignore exotic ops the JVM cares about; we just wont issue them
+                //System.err.println("warning: "+err);
+                continue;
+            }
+        }
+        return true;
+    }
+    static {
+        assert(verifyConstants());
+    }
+
+    // Up-calls from the JVM.
+    // These must NOT be public.
+
+    /**
+     * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
+     *
+    static MemberName linkCallSite(Object callerObj,
+                                   Object bootstrapMethodObj,
+                                   Object nameObj, Object typeObj,
+                                   Object staticArguments,
+                                   Object[] appendixResult) {
+        MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
+        Class<?> caller = (Class<?>)callerObj;
+        String name = nameObj.toString().intern();
+        MethodType type = (MethodType)typeObj;
+        if (!TRACE_METHOD_LINKAGE)
+            return linkCallSiteImpl(caller, bootstrapMethod, name, type,
+                                    staticArguments, appendixResult);
+        return linkCallSiteTracing(caller, bootstrapMethod, name, type,
+                                   staticArguments, appendixResult);
+    }
+    static MemberName linkCallSiteImpl(Class<?> caller,
+                                       MethodHandle bootstrapMethod,
+                                       String name, MethodType type,
+                                       Object staticArguments,
+                                       Object[] appendixResult) {
+        CallSite callSite = CallSite.makeSite(bootstrapMethod,
+                                              name,
+                                              type,
+                                              staticArguments,
+                                              caller);
+        if (callSite instanceof ConstantCallSite) {
+            appendixResult[0] = callSite.dynamicInvoker();
+            return Invokers.linkToTargetMethod(type);
+        } else {
+            appendixResult[0] = callSite;
+            return Invokers.linkToCallSiteMethod(type);
+        }
+    }
+    // Tracing logic:
+    static MemberName linkCallSiteTracing(Class<?> caller,
+                                          MethodHandle bootstrapMethod,
+                                          String name, MethodType type,
+                                          Object staticArguments,
+                                          Object[] appendixResult) {
+        Object bsmReference = bootstrapMethod.internalMemberName();
+        if (bsmReference == null)  bsmReference = bootstrapMethod;
+        Object staticArglist = (staticArguments instanceof Object[] ?
+                                java.util.Arrays.asList((Object[]) staticArguments) :
+                                staticArguments);
+        System.out.println("linkCallSite "+caller.getName()+" "+
+                           bsmReference+" "+
+                           name+type+"/"+staticArglist);
+        try {
+            MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
+                                              staticArguments, appendixResult);
+            System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
+            return res;
+        } catch (Throwable ex) {
+            System.out.println("linkCallSite => throw "+ex);
+            throw ex;
+        }
+    }
+
+    /**
+     * The JVM wants a pointer to a MethodType.  Oblige it by finding or creating one.
+     *
+    static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
+        return MethodType.makeImpl(rtype, ptypes, true);
+    }
+
+    /**
+     * The JVM wants to link a call site that requires a dynamic type check.
+     * Name is a type-checking invoker, invokeExact or invoke.
+     * Return a JVM method (MemberName) to handle the invoking.
+     * The method assumes the following arguments on the stack:
+     * 0: the method handle being invoked
+     * 1-N: the arguments to the method handle invocation
+     * N+1: an optional, implicitly added argument (typically the given MethodType)
+     * <p>
+     * The nominal method at such a call site is an instance of
+     * a signature-polymorphic method (see @PolymorphicSignature).
+     * Such method instances are user-visible entities which are
+     * "split" from the generic placeholder method in {@code MethodHandle}.
+     * (Note that the placeholder method is not identical with any of
+     * its instances.  If invoked reflectively, is guaranteed to throw an
+     * {@code UnsupportedOperationException}.)
+     * If the signature-polymorphic method instance is ever reified,
+     * it appears as a "copy" of the original placeholder
+     * (a native final member of {@code MethodHandle}) except
+     * that its type descriptor has shape required by the instance,
+     * and the method instance is <em>not</em> varargs.
+     * The method instance is also marked synthetic, since the
+     * method (by definition) does not appear in Java source code.
+     * <p>
+     * The JVM is allowed to reify this method as instance metadata.
+     * For example, {@code invokeBasic} is always reified.
+     * But the JVM may instead call {@code linkMethod}.
+     * If the result is an * ordered pair of a {@code (method, appendix)},
+     * the method gets all the arguments (0..N inclusive)
+     * plus the appendix (N+1), and uses the appendix to complete the call.
+     * In this way, one reusable method (called a "linker method")
+     * can perform the function of any number of polymorphic instance
+     * methods.
+     * <p>
+     * Linker methods are allowed to be weakly typed, with any or
+     * all references rewritten to {@code Object} and any primitives
+     * (except {@code long}/{@code float}/{@code double})
+     * rewritten to {@code int}.
+     * A linker method is trusted to return a strongly typed result,
+     * according to the specific method type descriptor of the
+     * signature-polymorphic instance it is emulating.
+     * This can involve (as necessary) a dynamic check using
+     * data extracted from the appendix argument.
+     * <p>
+     * The JVM does not inspect the appendix, other than to pass
+     * it verbatim to the linker method at every call.
+     * This means that the JDK runtime has wide latitude
+     * for choosing the shape of each linker method and its
+     * corresponding appendix.
+     * Linker methods should be generated from {@code LambdaForm}s
+     * so that they do not become visible on stack traces.
+     * <p>
+     * The {@code linkMethod} call is free to omit the appendix
+     * (returning null) and instead emulate the required function
+     * completely in the linker method.
+     * As a corner case, if N==255, no appendix is possible.
+     * In this case, the method returned must be custom-generated to
+     * to perform any needed type checking.
+     * <p>
+     * If the JVM does not reify a method at a call site, but instead
+     * calls {@code linkMethod}, the corresponding call represented
+     * in the bytecodes may mention a valid method which is not
+     * representable with a {@code MemberName}.
+     * Therefore, use cases for {@code linkMethod} tend to correspond to
+     * special cases in reflective code such as {@code findVirtual}
+     * or {@code revealDirect}.
+     *
+    static MemberName linkMethod(Class<?> callerClass, int refKind,
+                                 Class<?> defc, String name, Object type,
+                                 Object[] appendixResult) {
+        if (!TRACE_METHOD_LINKAGE)
+            return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+        return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
+    }
+    static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
+                                     Class<?> defc, String name, Object type,
+                                     Object[] appendixResult) {
+        try {
+            if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+                return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+            }
+        } catch (Throwable ex) {
+            if (ex instanceof LinkageError)
+                throw (LinkageError) ex;
+            else
+                throw new LinkageError(ex.getMessage(), ex);
+        }
+        throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+    }
+    private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+        if (type instanceof MethodType)
+            return (MethodType) type;
+        else
+            return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+    }
+    // Tracing logic:
+    static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
+                                        Class<?> defc, String name, Object type,
+                                        Object[] appendixResult) {
+        System.out.println("linkMethod "+defc.getName()+"."+
+                           name+type+"/"+Integer.toHexString(refKind));
+        try {
+            MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+            System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
+            return res;
+        } catch (Throwable ex) {
+            System.out.println("linkMethod => throw "+ex);
+            throw ex;
+        }
+    }
+
+
+    /**
+     * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
+     * It will make an up-call to this method.  (Do not change the name or signature.)
+     * The type argument is a Class for field requests and a MethodType for non-fields.
+     * <p>
+     * Recent versions of the JVM may also pass a resolved MemberName for the type.
+     * In that case, the name is ignored and may be null.
+     *
+    static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
+                                                 Class<?> defc, String name, Object type) {
+        try {
+            Lookup lookup = IMPL_LOOKUP.in(callerClass);
+            assert(refKindIsValid(refKind));
+            return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
+        } catch (IllegalAccessException ex) {
+            Throwable cause = ex.getCause();
+            if (cause instanceof AbstractMethodError) {
+                throw (AbstractMethodError) cause;
+            } else {
+                Error err = new IllegalAccessError(ex.getMessage());
+                throw initCauseFrom(err, ex);
+            }
+        } catch (NoSuchMethodException ex) {
+            Error err = new NoSuchMethodError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (NoSuchFieldException ex) {
+            Error err = new NoSuchFieldError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (ReflectiveOperationException ex) {
+            Error err = new IncompatibleClassChangeError();
+            throw initCauseFrom(err, ex);
+        }
+    }
+
+    /**
+     * Use best possible cause for err.initCause(), substituting the
+     * cause for err itself if the cause has the same (or better) type.
+     *
+    static private Error initCauseFrom(Error err, Exception ex) {
+        Throwable th = ex.getCause();
+        if (err.getClass().isInstance(th))
+           return (Error) th;
+        err.initCause(th == null ? ex : th);
+        return err;
+    }
+
+    /**
+     * Is this method a caller-sensitive method?
+     * I.e., does it call Reflection.getCallerClass or a similer method
+     * to ask about the identity of its caller?
+     *
+    static boolean isCallerSensitive(MemberName mem) {
+        if (!mem.isInvocable())  return false;  // fields are not caller sensitive
+
+        return mem.isCallerSensitive() || canBeCalledVirtual(mem);
+    }
+
+    static boolean canBeCalledVirtual(MemberName mem) {
+        assert(mem.isInvocable());
+        Class<?> defc = mem.getDeclaringClass();
+        switch (mem.getName()) {
+        case "checkMemberAccess":
+            return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+        case "getContextClassLoader":
+            return canBeCalledVirtual(mem, java.lang.Thread.class);
+        }
+        return false;
+    }
+
+    static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
+        Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
+        if (symbolicRefClass == definingClass)  return true;
+        if (symbolicRef.isStatic() || symbolicRef.isPrivate())  return false;
+        return (definingClass.isAssignableFrom(symbolicRefClass) ||  // Msym overrides Mdef
+                symbolicRefClass.isInterface());                     // Mdef implements Msym
+    }
+    */
+    // END Android-removed: Unused implementation code.
+}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
index bc1e944..17c5f57 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
@@ -32,9 +32,10 @@
 import java.util.ArrayList;
 import java.util.NoSuchElementException;
 
-import dalvik.system.VMStack;
 import sun.invoke.util.VerifyAccess;
 import sun.invoke.util.Wrapper;
+import sun.reflect.Reflection;
+
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
@@ -85,8 +86,7 @@
     // Android-changed: Remove caller sensitive.
     // @CallerSensitive
     public static Lookup lookup() {
-        // Android-changed: Do not use Reflection.getCallerClass().
-        return new Lookup(VMStack.getStackClass1());
+        return new Lookup(Reflection.getCallerClass());
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodType.java b/ojluni/src/main/java/java/lang/invoke/MethodType.java
index bfa7ccd..b2ff6e7 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodType.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodType.java
@@ -97,8 +97,8 @@
     // The remaining fields are caches of various sorts:
     private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
     private @Stable MethodType wrapAlt;  // alternative wrapped/unwrapped version
-    // Android-changed: Remove adapter cache. We're not dynamically generating any
-    // adapters at this point.
+    // Android-removed: Cache of higher order adapters.
+    // We're not dynamically generating any adapters at this point.
     // private @Stable Invokers invokers;   // cache of handy higher-order adapters
     private @Stable String methodDescriptor;  // cache for toMethodDescriptorString
 
@@ -124,12 +124,13 @@
     }
 
     /*trusted*/ MethodTypeForm form() { return form; }
+    // Android-changed: Make rtype()/ptypes() public @hide for implementation use.
+    // /*trusted*/ Class<?> rtype() { return rtype; }
+    // /*trusted*/ Class<?>[] ptypes() { return ptypes; }
     /*trusted*/ /** @hide */ public Class<?> rtype() { return rtype; }
     /*trusted*/ /** @hide */ public Class<?>[] ptypes() { return ptypes; }
 
-    // Android-changed: Removed method setForm. It's unused in the JDK and there's no
-    // good reason to allow the form to be set externally.
-    //
+    // Android-removed: Implementation methods unused on Android.
     // void setForm(MethodTypeForm f) { form = f; }
 
     /** This number, mandated by the JVM spec as 255,
@@ -618,22 +619,26 @@
         return form.erasedType();
     }
 
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
     /**
      * Erases all reference types to {@code Object}, and all subword types to {@code int}.
      * This is the reduced type polymorphism used by private methods
      * such as {@link MethodHandle#invokeBasic invokeBasic}.
      * @return a version of the original type with all reference and subword types replaced
-     */
-    /*non-public*/ MethodType basicType() {
+     *
+    /*non-public* MethodType basicType() {
         return form.basicType();
     }
 
     /**
      * @return a version of the original type with MethodHandle prepended as the first argument
-     */
-    /*non-public*/ MethodType invokerType() {
+     *
+    /*non-public* MethodType invokerType() {
         return insertParameterTypes(0, MethodHandle.class);
     }
+    */
+    // END Android-removed: Implementation methods unused on Android.
 
     /**
      * Converts all types, both reference and primitive, to {@code Object}.
@@ -805,12 +810,36 @@
         return sb.toString();
     }
 
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
     /** True if the old return type can always be viewed (w/o casting) under new return type,
      *  and the new parameters can be viewed (w/o casting) under the old parameter types.
-     */
-    // Android-changed: Removed implementation details.
-    // boolean isViewableAs(MethodType newType, boolean keepInterfaces);
-    // boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces);
+     *
+    /*non-public*
+    boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
+        if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
+            return false;
+        return parametersAreViewableAs(newType, keepInterfaces);
+    }
+    /** True if the new parameters can be viewed (w/o casting) under the old parameter types. *
+    /*non-public*
+    boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
+        if (form == newType.form && form.erasedType == this)
+            return true;  // my reference parameters are all Object
+        if (ptypes == newType.ptypes)
+            return true;
+        int argc = parameterCount();
+        if (argc != newType.parameterCount())
+            return false;
+        for (int i = 0; i < argc; i++) {
+            if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i), keepInterfaces))
+                return false;
+        }
+        return true;
+    }
+    */
+    // END Android-removed: Implementation methods unused on Android.
+
     /*non-public*/
     boolean isConvertibleTo(MethodType newType) {
         MethodTypeForm oldForm = this.form();
@@ -865,6 +894,9 @@
         return true;
     }
 
+    // Android-changed: Temporary workaround for bug in MethodHandle.asType(MethodType).
+    // See http://b/113855305 for more details
+    // Update documentation to describe new behavior.
     /** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
      *  and with the same effect.
      *  MHs.eCA has the following "upgrades" to MH.asType:
@@ -881,9 +913,10 @@
      * Boxing primitives to references is the same for both operators.
      */
     private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
-        if (src == dst || dst == Object.class || dst == void.class) {
-            return true;
-        } else if (src.isPrimitive() && src != void.class) {
+        if (src == dst || dst == Object.class || dst == void.class)  return true;
+        // Android-changed: Temporary workaround for bug in MethodHandle.asType(MethodType).
+        // if (src.isPrimitive()) {
+        if (src.isPrimitive() && src != void.class) {
             // Could be a prim/prim conversion, where casting is a strict superset.
             // Or a boxing conversion, which is always to an exact wrapper class.
             return canConvert(src, dst);
@@ -958,6 +991,8 @@
         }
     }
 
+    /// Queries which have to do with the bytecode architecture
+
     /** Reports the number of JVM stack slots required to invoke a method
      * of this type.  Note that (for historical reasons) the JVM requires
      * a second stack slot to pass long and double arguments.
@@ -972,16 +1007,63 @@
         return form.parameterSlotCount();
     }
 
-    /// Queries which have to do with the bytecode architecture
+    // BEGIN Android-removed: Cache of higher order adapters.
+    /*
+    /*non-public* Invokers invokers() {
+        Invokers inv = invokers;
+        if (inv != null)  return inv;
+        invokers = inv = new Invokers(this);
+        return inv;
+    }
+    */
+    // END Android-removed: Cache of higher order adapters.
 
-    // Android-changed: These methods aren't needed on Android and are unused within the JDK.
-    //
-    // int parameterSlotDepth(int num);
-    // int returnSlotCount();
-    //
-    // Android-changed: Removed cache of higher order adapters.
-    //
-    // Invokers invokers();
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
+    /** Reports the number of JVM stack slots which carry all parameters including and after
+     * the given position, which must be in the range of 0 to
+     * {@code parameterCount} inclusive.  Successive parameters are
+     * more shallowly stacked, and parameters are indexed in the bytecodes
+     * according to their trailing edge.  Thus, to obtain the depth
+     * in the outgoing call stack of parameter {@code N}, obtain
+     * the {@code parameterSlotDepth} of its trailing edge
+     * at position {@code N+1}.
+     * <p>
+     * Parameters of type {@code long} and {@code double} occupy
+     * two stack slots (for historical reasons) and all others occupy one.
+     * Therefore, the number returned is the number of arguments
+     * <em>including</em> and <em>after</em> the given parameter,
+     * <em>plus</em> the number of long or double arguments
+     * at or after after the argument for the given parameter.
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and invokedynamic.
+     * @param num an index (zero-based, inclusive) within the parameter types
+     * @return the index of the (shallowest) JVM stack slot transmitting the
+     *         given parameter
+     * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+     *
+    /*non-public* int parameterSlotDepth(int num) {
+        if (num < 0 || num > ptypes.length)
+            parameterType(num);  // force a range check
+        return form.parameterToArgSlot(num-1);
+    }
+
+    /** Reports the number of JVM stack slots required to receive a return value
+     * from a method of this type.
+     * If the {@link #returnType() return type} is void, it will be zero,
+     * else if the return type is long or double, it will be two, else one.
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and invokedynamic.
+     * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
+     * Will be removed for PFD.
+     *
+    /*non-public* int returnSlotCount() {
+        return form.returnSlotCount();
+    }
+    */
+    // END Android-removed: Implementation methods unused on Android.
 
     /**
      * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
index d65392b..6f6c2a8 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
@@ -49,20 +49,45 @@
     final MethodType erasedType;        // the canonical erasure
     final MethodType basicType;         // the canonical erasure, with primitives simplified
 
+    // BEGIN Android-removed: Cached adaptors / lambda forms.
+    // The upstream caching mechanism will not work on Android because of fundamental differences
+    // in the Android runtime/implementation of MethodHandle. LambdaForm is not supported on
+    // Android for similar reasons.
+    /*
     // Cached adapter information:
-    //
-    // @Stable final SoftReference<MethodHandle>[] methodHandles;
-    // static final int  MH_BASIC_INV, MH_NF_INV, MH_UNINIT_CS, MH_LIMIT;
-    //
+    @Stable final SoftReference<MethodHandle>[] methodHandles;
+    // Indexes into methodHandles:
+    static final int
+            MH_BASIC_INV      =  0,  // cached instance of MH.invokeBasic
+            MH_NF_INV         =  1,  // cached helper for LF.NamedFunction
+            MH_UNINIT_CS      =  2,  // uninitialized call site
+            MH_LIMIT          =  3;
+
     // Cached lambda form information, for basic types only:
-    // final @Stable SoftReference<LambdaForm>[] lambdaForms;
-    //
+    final @Stable SoftReference<LambdaForm>[] lambdaForms;
     // Indexes into lambdaForms:
-    //
-    // static final int LF_INVVIRTUAL, LF_INVSTATIC, LF_INVSPECIAL, LF_NEWINVSPECIAL,
-    // LF_INVINTERFACE, LF_INVSTATIC_INIT, LF_INTERPRET, LF_REBIND, LF_DELEGATE,
-    // LF_DELEGATE_BLOCK_INLINING, LF_EX_LINKER, LF_EX_INVOKER, LF_GEN_LINKER, LF_GEN_INVOKER,
-    // LF_CS_LINKER, LF_MH_LINKER, LF_GWC, LF_GWT, LF_LIMIT;
+    static final int
+            LF_INVVIRTUAL              =  0,  // DMH invokeVirtual
+            LF_INVSTATIC               =  1,
+            LF_INVSPECIAL              =  2,
+            LF_NEWINVSPECIAL           =  3,
+            LF_INVINTERFACE            =  4,
+            LF_INVSTATIC_INIT          =  5,  // DMH invokeStatic with <clinit> barrier
+            LF_INTERPRET               =  6,  // LF interpreter
+            LF_REBIND                  =  7,  // BoundMethodHandle
+            LF_DELEGATE                =  8,  // DelegatingMethodHandle
+            LF_DELEGATE_BLOCK_INLINING =  9,  // Counting DelegatingMethodHandle w/ @DontInline
+            LF_EX_LINKER               = 10,  // invokeExact_MT (for invokehandle)
+            LF_EX_INVOKER              = 11,  // MHs.invokeExact
+            LF_GEN_LINKER              = 12,  // generic invoke_MT (for invokehandle)
+            LF_GEN_INVOKER             = 13,  // generic MHs.invoke
+            LF_CS_LINKER               = 14,  // linkToCallSite_CS
+            LF_MH_LINKER               = 15,  // linkToCallSite_MH
+            LF_GWC                     = 16,  // guardWithCatch (catchException)
+            LF_GWT                     = 17,  // guardWithTest
+            LF_LIMIT                   = 18;
+    */
+    // END Android-removed: Cached adaptors / lambda forms.
 
     /** Return the type corresponding uniquely (1-1) to this MT-form.
      *  It might have any primitive returns or arguments, but will have no references except Object.
@@ -87,12 +112,47 @@
         return true;
     }
 
-    // Android-changed: Removed caches for MethodHandle adaptors / LambdaForms.
-    //
-    // public MethodHandle cachedMethodHandle(int which);
-    // synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh);
-    // public LambdaForm cachedLambdaForm(int which);
-    // synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form);
+    // BEGIN Android-removed: Cached adaptors / lambda forms.
+    /*
+    public MethodHandle cachedMethodHandle(int which) {
+        assert(assertIsBasicType());
+        SoftReference<MethodHandle> entry = methodHandles[which];
+        return (entry != null) ? entry.get() : null;
+    }
+
+    synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        SoftReference<MethodHandle> entry = methodHandles[which];
+        if (entry != null) {
+            MethodHandle prev = entry.get();
+            if (prev != null) {
+                return prev;
+            }
+        }
+        methodHandles[which] = new SoftReference<>(mh);
+        return mh;
+    }
+
+    public LambdaForm cachedLambdaForm(int which) {
+        assert(assertIsBasicType());
+        SoftReference<LambdaForm> entry = lambdaForms[which];
+        return (entry != null) ? entry.get() : null;
+    }
+
+    synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        SoftReference<LambdaForm> entry = lambdaForms[which];
+        if (entry != null) {
+            LambdaForm prev = entry.get();
+            if (prev != null) {
+                return prev;
+            }
+        }
+        lambdaForms[which] = new SoftReference<>(form);
+        return form;
+    }
+    */
+    // END Android-removed: Cached adaptors / lambda forms.
 
     /**
      * Build an MTF for a given type, which must have all references erased to Object.
@@ -154,8 +214,7 @@
             this.argCounts = that.argCounts;
             this.argToSlotTable = that.argToSlotTable;
             this.slotToArgTable = that.slotToArgTable;
-            // Android-changed: Removed cached adaptors / lambda forms.
-            //
+            // Android-removed: Cached adaptors / lambda forms.
             // this.methodHandles = null;
             // this.lambdaForms = null;
             return;
@@ -201,8 +260,7 @@
 
         // Initialize caches, but only for basic types
         assert(basicType == erasedType);
-        // Android-changed: Removed cached adaptors / lambda forms.
-        //
+        // Android-removed: Cached adaptors / lambda forms.
         // this.lambdaForms   = new SoftReference[LF_LIMIT];
         // this.methodHandles = new SoftReference[MH_LIMIT];
     }
diff --git a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
index bb01d4c..6ca8aa0 100644
--- a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
@@ -25,9 +25,6 @@
 
 package java.lang.invoke;
 
-// Android-changed: not used.
-// import java.util.concurrent.atomic.AtomicInteger;
-
 // Android-changed: removed references to MutableCallSite.syncAll().
 /**
  * A {@code MutableCallSite} is a {@link CallSite} whose target variable
@@ -161,123 +158,125 @@
         return makeDynamicInvoker();
     }
 
-    // Android-changed: not exposing incomplete implementation.
-    // /**
-    //  * Performs a synchronization operation on each call site in the given array,
-    //  * forcing all other threads to throw away any cached values previously
-    //  * loaded from the target of any of the call sites.
-    //  * <p>
-    //  * This operation does not reverse any calls that have already started
-    //  * on an old target value.
-    //  * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
-    //  * <p>
-    //  * The overall effect is to force all future readers of each call site's target
-    //  * to accept the most recently stored value.
-    //  * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
-    //  * Conversely, the {@code syncAll} call may block until all readers have
-    //  * (somehow) decached all previous versions of each call site's target.
-    //  * <p>
-    //  * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
-    //  * should generally be performed under some sort of mutual exclusion.
-    //  * Note that reader threads may observe an updated target as early
-    //  * as the {@code setTarget} call that install the value
-    //  * (and before the {@code syncAll} that confirms the value).
-    //  * On the other hand, reader threads may observe previous versions of
-    //  * the target until the {@code syncAll} call returns
-    //  * (and after the {@code setTarget} that attempts to convey the updated version).
-    //  * <p>
-    //  * This operation is likely to be expensive and should be used sparingly.
-    //  * If possible, it should be buffered for batch processing on sets of call sites.
-    //  * <p>
-    //  * If {@code sites} contains a null element,
-    //  * a {@code NullPointerException} will be raised.
-    //  * In this case, some non-null elements in the array may be
-    //  * processed before the method returns abnormally.
-    //  * Which elements these are (if any) is implementation-dependent.
-    //  *
-    //  * <h3>Java Memory Model details</h3>
-    //  * In terms of the Java Memory Model, this operation performs a synchronization
-    //  * action which is comparable in effect to the writing of a volatile variable
-    //  * by the current thread, and an eventual volatile read by every other thread
-    //  * that may access one of the affected call sites.
-    //  * <p>
-    //  * The following effects are apparent, for each individual call site {@code S}:
-    //  * <ul>
-    //  * <li>A new volatile variable {@code V} is created, and written by the current thread.
-    //  *     As defined by the JMM, this write is a global synchronization event.
-    //  * <li>As is normal with thread-local ordering of write events,
-    //  *     every action already performed by the current thread is
-    //  *     taken to happen before the volatile write to {@code V}.
-    //  *     (In some implementations, this means that the current thread
-    //  *     performs a global release operation.)
-    //  * <li>Specifically, the write to the current target of {@code S} is
-    //  *     taken to happen before the volatile write to {@code V}.
-    //  * <li>The volatile write to {@code V} is placed
-    //  *     (in an implementation specific manner)
-    //  *     in the global synchronization order.
-    //  * <li>Consider an arbitrary thread {@code T} (other than the current thread).
-    //  *     If {@code T} executes a synchronization action {@code A}
-    //  *     after the volatile write to {@code V} (in the global synchronization order),
-    //  *     it is therefore required to see either the current target
-    //  *     of {@code S}, or a later write to that target,
-    //  *     if it executes a read on the target of {@code S}.
-    //  *     (This constraint is called "synchronization-order consistency".)
-    //  * <li>The JMM specifically allows optimizing compilers to elide
-    //  *     reads or writes of variables that are known to be useless.
-    //  *     Such elided reads and writes have no effect on the happens-before
-    //  *     relation.  Regardless of this fact, the volatile {@code V}
-    //  *     will not be elided, even though its written value is
-    //  *     indeterminate and its read value is not used.
-    //  * </ul>
-    //  * Because of the last point, the implementation behaves as if a
-    //  * volatile read of {@code V} were performed by {@code T}
-    //  * immediately after its action {@code A}.  In the local ordering
-    //  * of actions in {@code T}, this read happens before any future
-    //  * read of the target of {@code S}.  It is as if the
-    //  * implementation arbitrarily picked a read of {@code S}'s target
-    //  * by {@code T}, and forced a read of {@code V} to precede it,
-    //  * thereby ensuring communication of the new target value.
-    //  * <p>
-    //  * As long as the constraints of the Java Memory Model are obeyed,
-    //  * implementations may delay the completion of a {@code syncAll}
-    //  * operation while other threads ({@code T} above) continue to
-    //  * use previous values of {@code S}'s target.
-    //  * However, implementations are (as always) encouraged to avoid
-    //  * livelock, and to eventually require all threads to take account
-    //  * of the updated target.
-    //  *
-    //  * <p style="font-size:smaller;">
-    //  * <em>Discussion:</em>
-    //  * For performance reasons, {@code syncAll} is not a virtual method
-    //  * on a single call site, but rather applies to a set of call sites.
-    //  * Some implementations may incur a large fixed overhead cost
-    //  * for processing one or more synchronization operations,
-    //  * but a small incremental cost for each additional call site.
-    //  * In any case, this operation is likely to be costly, since
-    //  * other threads may have to be somehow interrupted
-    //  * in order to make them notice the updated target value.
-    //  * However, it may be observed that a single call to synchronize
-    //  * several sites has the same formal effect as many calls,
-    //  * each on just one of the sites.
-    //  *
-    //  * <p style="font-size:smaller;">
-    //  * <em>Implementation Note:</em>
-    //  * Simple implementations of {@code MutableCallSite} may use
-    //  * a volatile variable for the target of a mutable call site.
-    //  * In such an implementation, the {@code syncAll} method can be a no-op,
-    //  * and yet it will conform to the JMM behavior documented above.
-    //  *
-    //  * @param sites an array of call sites to be synchronized
-    //  * @throws NullPointerException if the {@code sites} array reference is null
-    //  *                              or the array contains a null
-    //  */
-    // public static void syncAll(MutableCallSite[] sites) {
-    //     if (sites.length == 0)  return;
-    //     STORE_BARRIER.lazySet(0);
-    //     for (int i = 0; i < sites.length; i++) {
-    //         sites[i].getClass();  // trigger NPE on first null
-    //     }
-    //     // FIXME: NYI
-    // }
-    // private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+    // BEGIN Android-removed: syncAll() implementation is incomplete.
+    /**
+     * Performs a synchronization operation on each call site in the given array,
+     * forcing all other threads to throw away any cached values previously
+     * loaded from the target of any of the call sites.
+     * <p>
+     * This operation does not reverse any calls that have already started
+     * on an old target value.
+     * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
+     * <p>
+     * The overall effect is to force all future readers of each call site's target
+     * to accept the most recently stored value.
+     * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+     * Conversely, the {@code syncAll} call may block until all readers have
+     * (somehow) decached all previous versions of each call site's target.
+     * <p>
+     * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
+     * should generally be performed under some sort of mutual exclusion.
+     * Note that reader threads may observe an updated target as early
+     * as the {@code setTarget} call that install the value
+     * (and before the {@code syncAll} that confirms the value).
+     * On the other hand, reader threads may observe previous versions of
+     * the target until the {@code syncAll} call returns
+     * (and after the {@code setTarget} that attempts to convey the updated version).
+     * <p>
+     * This operation is likely to be expensive and should be used sparingly.
+     * If possible, it should be buffered for batch processing on sets of call sites.
+     * <p>
+     * If {@code sites} contains a null element,
+     * a {@code NullPointerException} will be raised.
+     * In this case, some non-null elements in the array may be
+     * processed before the method returns abnormally.
+     * Which elements these are (if any) is implementation-dependent.
+     *
+     * <h1>Java Memory Model details</h1>
+     * In terms of the Java Memory Model, this operation performs a synchronization
+     * action which is comparable in effect to the writing of a volatile variable
+     * by the current thread, and an eventual volatile read by every other thread
+     * that may access one of the affected call sites.
+     * <p>
+     * The following effects are apparent, for each individual call site {@code S}:
+     * <ul>
+     * <li>A new volatile variable {@code V} is created, and written by the current thread.
+     *     As defined by the JMM, this write is a global synchronization event.
+     * <li>As is normal with thread-local ordering of write events,
+     *     every action already performed by the current thread is
+     *     taken to happen before the volatile write to {@code V}.
+     *     (In some implementations, this means that the current thread
+     *     performs a global release operation.)
+     * <li>Specifically, the write to the current target of {@code S} is
+     *     taken to happen before the volatile write to {@code V}.
+     * <li>The volatile write to {@code V} is placed
+     *     (in an implementation specific manner)
+     *     in the global synchronization order.
+     * <li>Consider an arbitrary thread {@code T} (other than the current thread).
+     *     If {@code T} executes a synchronization action {@code A}
+     *     after the volatile write to {@code V} (in the global synchronization order),
+     *     it is therefore required to see either the current target
+     *     of {@code S}, or a later write to that target,
+     *     if it executes a read on the target of {@code S}.
+     *     (This constraint is called "synchronization-order consistency".)
+     * <li>The JMM specifically allows optimizing compilers to elide
+     *     reads or writes of variables that are known to be useless.
+     *     Such elided reads and writes have no effect on the happens-before
+     *     relation.  Regardless of this fact, the volatile {@code V}
+     *     will not be elided, even though its written value is
+     *     indeterminate and its read value is not used.
+     * </ul>
+     * Because of the last point, the implementation behaves as if a
+     * volatile read of {@code V} were performed by {@code T}
+     * immediately after its action {@code A}.  In the local ordering
+     * of actions in {@code T}, this read happens before any future
+     * read of the target of {@code S}.  It is as if the
+     * implementation arbitrarily picked a read of {@code S}'s target
+     * by {@code T}, and forced a read of {@code V} to precede it,
+     * thereby ensuring communication of the new target value.
+     * <p>
+     * As long as the constraints of the Java Memory Model are obeyed,
+     * implementations may delay the completion of a {@code syncAll}
+     * operation while other threads ({@code T} above) continue to
+     * use previous values of {@code S}'s target.
+     * However, implementations are (as always) encouraged to avoid
+     * livelock, and to eventually require all threads to take account
+     * of the updated target.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * For performance reasons, {@code syncAll} is not a virtual method
+     * on a single call site, but rather applies to a set of call sites.
+     * Some implementations may incur a large fixed overhead cost
+     * for processing one or more synchronization operations,
+     * but a small incremental cost for each additional call site.
+     * In any case, this operation is likely to be costly, since
+     * other threads may have to be somehow interrupted
+     * in order to make them notice the updated target value.
+     * However, it may be observed that a single call to synchronize
+     * several sites has the same formal effect as many calls,
+     * each on just one of the sites.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Implementation Note:</em>
+     * Simple implementations of {@code MutableCallSite} may use
+     * a volatile variable for the target of a mutable call site.
+     * In such an implementation, the {@code syncAll} method can be a no-op,
+     * and yet it will conform to the JMM behavior documented above.
+     *
+     * @param sites an array of call sites to be synchronized
+     * @throws NullPointerException if the {@code sites} array reference is null
+     *                              or the array contains a null
+     *
+    public static void syncAll(MutableCallSite[] sites) {
+        if (sites.length == 0)  return;
+        STORE_BARRIER.lazySet(0);
+        for (int i = 0; i < sites.length; i++) {
+            sites[i].getClass();  // trigger NPE on first null
+        }
+        // FIXME: NYI
+    }
+    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+    */
+    // END Android-removed: syncAll() implementation is incomplete. 
 }
diff --git a/ojluni/src/main/java/java/lang/invoke/Transformers.java b/ojluni/src/main/java/java/lang/invoke/Transformers.java
index 75ee192..fc8727a 100644
--- a/ojluni/src/main/java/java/lang/invoke/Transformers.java
+++ b/ojluni/src/main/java/java/lang/invoke/Transformers.java
@@ -1,11 +1,12 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * 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.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java b/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
index 6444335..47d2689 100644
--- a/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java
@@ -25,7 +25,7 @@
 
 package java.lang.invoke;
 
-// Android-changed: removed references to MutableCallSite.syncAll().
+// Android-changed: Removed references to MutableCallSite.syncAll().
 /**
  * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
  * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
diff --git a/ojluni/src/main/java/java/lang/ref/Reference.java b/ojluni/src/main/java/java/lang/ref/Reference.java
index 4d51b18..551d672 100644
--- a/ojluni/src/main/java/java/lang/ref/Reference.java
+++ b/ojluni/src/main/java/java/lang/ref/Reference.java
@@ -38,8 +38,8 @@
  * @author   Mark Reinhold
  * @since    1.2
  */
-// Android-changed: Major parts of the code below were changed to accomodate a
-// different GC and compiler. ClassLinker knows about the fields of this class.
+// BEGIN Android-changed: Reimplemented to accommodate a different GC and compiler.
+// ClassLinker knows about the fields of this class.
 
 public abstract class Reference<T> {
     /**
@@ -156,7 +156,6 @@
        return queue != null && queue.enqueue(this);
     }
 
-
     /* -- Constructors -- */
 
     Reference(T referent) {
@@ -167,8 +166,10 @@
         this.referent = referent;
         this.queue = queue;
     }
+    // END Android-changed: Reimplemented to accommodate a different GC and compiler.
 
-    // BEGIN Android-added: reachabilityFence() documentation from upstream OpenJDK9+181
+    // BEGIN Android-added: reachabilityFence() from upstream OpenJDK9+181.
+    // The actual implementation differs from OpenJDK9.
     /**
      * Ensures that the object referenced by the given reference remains
      * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
@@ -278,9 +279,7 @@
      * @param ref the reference. If {@code null}, this method has no effect.
      * @since 9
      */
-    // END Android-added: reachabilityFence() documentation from upstream OpenJDK9+181
-
-    // Android-changed: reachabilityFence implementation differs from OpenJDK9.
+    // @DontInline
     public static void reachabilityFence(Object ref) {
         // This code is usually replaced by much faster intrinsic implementations.
         // It will be executed for tests run with the access checks interpreter in
@@ -312,4 +311,5 @@
             }
         };
     }
+    // END Android-added: Add reachabilityFence() from upstream OpenJDK9+181.
 }
diff --git a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
index 80c65d9..72e55c1b 100644
--- a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
+++ b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
@@ -35,6 +35,8 @@
  * @author   Mark Reinhold
  * @since    1.2
  */
+// BEGIN Android-changed: Reimplemented to accomodate a different GC and compiler.
+
 public class ReferenceQueue<T> {
 
     // Reference.queueNext will be set to sQueueNextUnenqueued to indicate
@@ -278,3 +280,4 @@
         }
     }
 }
+// END Android-changed: Reimplemented to accomodate a different GC and compiler.
diff --git a/ojluni/src/main/java/java/lang/ref/SoftReference.java b/ojluni/src/main/java/java/lang/ref/SoftReference.java
index 814baa4..272d1bd 100644
--- a/ojluni/src/main/java/java/lang/ref/SoftReference.java
+++ b/ojluni/src/main/java/java/lang/ref/SoftReference.java
@@ -25,7 +25,7 @@
 
 package java.lang.ref;
 
-
+// Android-changed: Javadoc change to recommend against using SoftReferences for caches.
 /**
  * Soft reference objects, which are cleared at the discretion of the garbage
  * collector in response to memory demand.
diff --git a/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java b/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
index cf6af47..7bb2a60 100644
--- a/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
+++ b/ojluni/src/main/java/java/lang/reflect/AnnotatedElement.java
@@ -27,6 +27,7 @@
 package java.lang.reflect;
 
 import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
 import java.util.Objects;
 import libcore.reflect.AnnotatedElements;
 
diff --git a/ojluni/src/main/java/java/lang/reflect/Type.java b/ojluni/src/main/java/java/lang/reflect/Type.java
index 02e97b0..eee7443 100644
--- a/ojluni/src/main/java/java/lang/reflect/Type.java
+++ b/ojluni/src/main/java/java/lang/reflect/Type.java
@@ -32,7 +32,6 @@
  *
  * @since 1.5
  */
-
 public interface Type {
     /**
      * Returns a string describing this type, including information
diff --git a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
index 07b375c..4e29a94 100644
--- a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -89,6 +89,8 @@
      */
     String getName();
 
+    // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
+    /*
     /**
      * Returns an array of AnnotatedType objects that represent the use of
      * types to denote the upper bounds of the type parameter represented by
@@ -99,7 +101,7 @@
      *
      * @return an array of objects representing the upper bounds of the type variable
      * @since 1.8
-     */
-    // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
-    // AnnotatedType[] getAnnotatedBounds();
+     *
+     AnnotatedType[] getAnnotatedBounds();
+    */
 }
diff --git a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
index ad0a618..a3c738a 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
@@ -25,6 +25,7 @@
 package java.net;
 
 import libcore.io.IoBridge;
+import libcore.io.IoUtils;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -96,9 +97,10 @@
             throw ioe;
         }
 
-        // Android-added: CloseGuard
+        // Android-added: CloseGuard/fdsan
         if (fd != null && fd.valid()) {
             guard.open("close");
+            IoUtils.setFdOwner(fd, this);
         }
     }
 
diff --git a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
index a36dae4..0500811 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
@@ -488,9 +488,12 @@
         return socketOutputStream;
     }
 
+    // Android-removed: this.fd is maintained by the concrete implementation.
+    /*
     void setFileDescriptor(FileDescriptor fd) {
         this.fd = fd;
     }
+    */
 
     void setAddress(InetAddress address) {
         this.address = address;
diff --git a/ojluni/src/main/java/java/net/InMemoryCookieStore.java b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
index 974eeaa..5df66c0 100644
--- a/ojluni/src/main/java/java/net/InMemoryCookieStore.java
+++ b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
@@ -169,17 +169,38 @@
      * of this cookie store.
      */
     public List<URI> getURIs() {
+        // BEGIN Android-changed: App compat. Return URI with no cookies. http://b/65538736
+        /*
         List<URI> uris = new ArrayList<URI>();
 
         lock.lock();
         try {
+            Iterator<URI> it = uriIndex.keySet().iterator();
+            while (it.hasNext()) {
+                URI uri = it.next();
+                List<HttpCookie> cookies = uriIndex.get(uri);
+                if (cookies == null || cookies.size() == 0) {
+                    // no cookies list or an empty list associated with
+                    // this uri entry, delete it
+                    it.remove();
+                }
+            }
+        } finally {
+            uris.addAll(uriIndex.keySet());
+            lock.unlock();
+        }
+
+        return uris;
+         */
+        lock.lock();
+        try {
             List<URI> result = new ArrayList<URI>(uriIndex.keySet());
             result.remove(null);
             return Collections.unmodifiableList(result);
         } finally {
-            uris.addAll(uriIndex.keySet());
             lock.unlock();
         }
+        // END Android-changed: App compat. Return URI with no cookies. http://b/65538736
     }
 
 
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index 94d32d3..2e6b534 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -1606,7 +1606,7 @@
     static final int NETID_UNSET = 0;
 
     // BEGIN Android-added: Add methods required by frameworks/base.
-    // Particularly those required to deal with net-ids and scope ids.
+    // Particularly those required to deal with scope ids.
     /**
      * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
      * This copes with all forms of address that Java supports, detailed in the {@link InetAddress}
@@ -1673,7 +1673,8 @@
     public static void clearDnsCache() {
         impl.clearAddressCache();
     }
-
+    // END Android-added: Add methods required by frameworks/base.
+    // BEGIN Android-added: Support for network (netId)-specific DNS resolution.
     /**
      * Operates identically to {@code getByName} except host resolution is
      * performed on the network designated by {@code netId}.
@@ -1702,17 +1703,7 @@
     public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
         return impl.lookupAllHostAddr(host, netId).clone();
     }
-    // END Android-added: Add methods required by frameworks/base.
-
-    // Only called by java.net.SocketPermission.
-    static InetAddress[] getAllByName0(String authHost, boolean check) throws UnknownHostException {
-        throw new UnsupportedOperationException();
-    }
-
-    // Only called by java.net.SocketPermission.
-    String getHostName(boolean check) {
-        throw new UnsupportedOperationException();
-    }
+    // END Android-added: Support for network (netId)-specific DNS resolution.
 }
 // BEGIN Android-removed: Android doesn't load user-provided implementation.
 /*
diff --git a/ojluni/src/main/java/java/net/PlainSocketImpl.java b/ojluni/src/main/java/java/net/PlainSocketImpl.java
index f592398..89ee53e 100644
--- a/ojluni/src/main/java/java/net/PlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainSocketImpl.java
@@ -72,15 +72,19 @@
      * Constructs an empty instance.
      */
     PlainSocketImpl() {
-        this(new FileDescriptor());
+        // Android-changed: Let PlainSocketImpl construct its own FileDescriptor.
+        this.fd = new FileDescriptor();
     }
 
     /**
      * Constructs an instance with the given file descriptor.
      */
+    // Android-removed: Let PlainSocketImpl construct its own FileDescriptor.
+    /*
     PlainSocketImpl(FileDescriptor fd) {
         this.fd = fd;
     }
+    */
 
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
         if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
@@ -122,6 +126,7 @@
         // The fd object must not change after calling bind, because we rely on this undocumented
         // behaviour. See libcore.java.net.SocketTest#testFileDescriptorStaysSame.
         fd.setInt$(IoBridge.socket(AF_INET6, isStream ? SOCK_STREAM : SOCK_DGRAM, 0).getInt$());
+        IoUtils.setFdOwner(fd, this);
 
         if (serverSocket != null) {
             IoUtils.setBlocking(fd, false);
@@ -196,11 +201,14 @@
             FileDescriptor newfd = Libcore.os.accept(fd, peerAddress);
 
             s.fd.setInt$(newfd.getInt$());
+            IoUtils.setFdOwner(s.fd, s);
             s.address = peerAddress.getAddress();
             s.port = peerAddress.getPort();
         } catch (ErrnoException errnoException) {
             if (errnoException.errno == EAGAIN) {
-                throw new SocketTimeoutException(errnoException);
+                SocketTimeoutException e = new SocketTimeoutException();
+                e.initCause(errnoException);
+                throw e;
             } else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) {
                 throw new SocketException("Socket closed");
             }
diff --git a/ojluni/src/main/java/java/net/ProtocolException.java b/ojluni/src/main/java/java/net/ProtocolException.java
index 0368350..5944282 100644
--- a/ojluni/src/main/java/java/net/ProtocolException.java
+++ b/ojluni/src/main/java/java/net/ProtocolException.java
@@ -54,10 +54,4 @@
      */
     public ProtocolException() {
     }
-
-    // Android-added: ProtocolException ctor used by frameworks.
-    /** @hide */
-    public ProtocolException(String msg, Throwable cause) {
-        super(msg, cause);
-    }
 }
diff --git a/ojluni/src/main/java/java/net/SocketTimeoutException.java b/ojluni/src/main/java/java/net/SocketTimeoutException.java
index 2c61415..5daf600 100644
--- a/ojluni/src/main/java/java/net/SocketTimeoutException.java
+++ b/ojluni/src/main/java/java/net/SocketTimeoutException.java
@@ -48,16 +48,4 @@
      * Construct a new SocketTimeoutException with no detailed message.
      */
     public SocketTimeoutException() {}
-
-    /** @hide */
-    // Android-added: Additional constructor for internal use.
-    public SocketTimeoutException(Throwable cause) {
-        super(cause);
-    }
-
-    /** @hide */
-    // Android-added: Additional constructor for internal use.
-    public SocketTimeoutException(String msg, Throwable cause) {
-        super(msg, cause);
-    }
 }
diff --git a/ojluni/src/main/java/java/net/URLStreamHandler.java b/ojluni/src/main/java/java/net/URLStreamHandler.java
index d5380c1..12b842c 100644
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -528,6 +528,8 @@
         return result.toString();
     }
 
+    // Android-changed: Removed @see tag (target is package-private):
+    // @see     java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
     /**
      * Sets the fields of the {@code URL} argument to the indicated values.
      * Only classes derived from URLStreamHandler are able
@@ -544,7 +546,6 @@
      * @param   ref       the reference.
      * @exception       SecurityException       if the protocol handler of the URL is
      *                                  different from this one
-     * @see     java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
      * @since 1.3
      */
        protected void setURL(URL u, String protocol, String host, int port,
diff --git a/ojluni/src/main/java/java/nio/Bits.java b/ojluni/src/main/java/java/nio/Bits.java
index 8f8767d..dda5b09 100644
--- a/ojluni/src/main/java/java/nio/Bits.java
+++ b/ojluni/src/main/java/java/nio/Bits.java
@@ -564,37 +564,20 @@
 
     // -- Processor and memory-system properties --
 
-    // Android-changed: Android is always little-endian.
-    // private static final ByteOrder byteOrder;
-    private static final ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
+    private static final ByteOrder byteOrder;
 
     static ByteOrder byteOrder() {
-        // BEGIN Android-removed: Android is always little-endian.
+        // Android-removed: Android is always little-endian.
         /*
         if (byteOrder == null)
             throw new Error("Unknown byte order");
-        if (byteOrder == null) {
-            long a = unsafe.allocateMemory(8);
-            try {
-                unsafe.putLong(a, 0x0102030405060708L);
-                byte b = unsafe.getByte(a);
-                switch (b) {
-                    case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
-                    case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
-                    default: throw new Error("Unknown byte order");
-                }
-            } finally {
-                unsafe.freeMemory(a);
-            }
-        }
         */
-        // END Android-removed: Android is always little-endian.
         return byteOrder;
     }
 
-    // BEGIN Android-removed: Android is always little-endian.
-    /*
     static {
+        // BEGIN Android-changed: Android is always little-endian.
+        /*
         long a = unsafe.allocateMemory(8);
         try {
             unsafe.putLong(a, 0x0102030405060708L);
@@ -609,9 +592,10 @@
         } finally {
             unsafe.freeMemory(a);
         }
+        */
+        byteOrder = ByteOrder.LITTLE_ENDIAN;
+        // END Android-changed: Android is always little-endian.
     }
-    */
-    // END Android-removed: Android is always little-endian.
 
 
     private static int pageSize = -1;
@@ -643,65 +627,115 @@
 
     // -- Direct memory management --
 
+    // BEGIN Android-removed: Direct memory management unused on Android.
+    /*
     // A user-settable upper limit on the maximum amount of allocatable
     // direct buffer memory.  This value may be changed during VM
     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
     private static volatile long maxMemory = VM.maxDirectMemory();
-    private static volatile long reservedMemory;
-    private static volatile long totalCapacity;
-    private static volatile long count;
-    private static boolean memoryLimitSet = false;
+    private static final AtomicLong reservedMemory = new AtomicLong();
+    private static final AtomicLong totalCapacity = new AtomicLong();
+    private static final AtomicLong count = new AtomicLong();
+    private static volatile boolean memoryLimitSet = false;
+    // max. number of sleeps during try-reserving with exponentially
+    // increasing delay before throwing OutOfMemoryError:
+    // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
+    // which means that OOME will be thrown after 0.5 s of trying
+    private static final int MAX_SLEEPS = 9;
 
     // These methods should be called whenever direct memory is allocated or
     // freed.  They allow the user to control the amount of direct memory
     // which a process may access.  All sizes are specified in bytes.
     static void reserveMemory(long size, int cap) {
-        synchronized (Bits.class) {
-            if (!memoryLimitSet && VM.isBooted()) {
-                maxMemory = VM.maxDirectMemory();
-                memoryLimitSet = true;
-            }
-            // -XX:MaxDirectMemorySize limits the total capacity rather than the
-            // actual memory usage, which will differ when buffers are page
-            // aligned.
-            if (cap <= maxMemory - totalCapacity) {
-                reservedMemory += size;
-                totalCapacity += cap;
-                count++;
+
+        if (!memoryLimitSet && VM.isBooted()) {
+            maxMemory = VM.maxDirectMemory();
+            memoryLimitSet = true;
+        }
+
+        // optimist!
+        if (tryReserveMemory(size, cap)) {
+            return;
+        }
+
+        final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
+
+        // retry while helping enqueue pending Reference objects
+        // which includes executing pending Cleaner(s) which includes
+        // Cleaner(s) that free direct buffer memory
+        while (jlra.tryHandlePendingReference()) {
+            if (tryReserveMemory(size, cap)) {
                 return;
             }
         }
 
         // trigger VM's Reference processing
         System.gc();
+
+        // a retry loop with exponential back-off delays
+        // (this gives VM some time to do it's job)
+        boolean interrupted = false;
         try {
-            Thread.sleep(100);
-        } catch (InterruptedException x) {
-            // Restore interrupt status
-            Thread.currentThread().interrupt();
-        }
-        synchronized (Bits.class) {
-            if (totalCapacity + cap > maxMemory)
-                throw new OutOfMemoryError("Direct buffer memory");
-            reservedMemory += size;
-            totalCapacity += cap;
-            count++;
-        }
+            long sleepTime = 1;
+            int sleeps = 0;
+            while (true) {
+                if (tryReserveMemory(size, cap)) {
+                    return;
+                }
+                if (sleeps >= MAX_SLEEPS) {
+                    break;
+                }
+                if (!jlra.tryHandlePendingReference()) {
+                    try {
+                        Thread.sleep(sleepTime);
+                        sleepTime <<= 1;
+                        sleeps++;
+                    } catch (InterruptedException e) {
+                        interrupted = true;
+                    }
+                }
+            }
 
+            // no luck
+            throw new OutOfMemoryError("Direct buffer memory");
+
+        } finally {
+            if (interrupted) {
+                // don't swallow interrupts
+                Thread.currentThread().interrupt();
+            }
+        }
     }
 
-    static synchronized void unreserveMemory(long size, int cap) {
-        if (reservedMemory > 0) {
-            reservedMemory -= size;
-            totalCapacity -= cap;
-            count--;
-            assert (reservedMemory > -1);
+    private static boolean tryReserveMemory(long size, int cap) {
+
+        // -XX:MaxDirectMemorySize limits the total capacity rather than the
+        // actual memory usage, which will differ when buffers are page
+        // aligned.
+        long totalCap;
+        while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
+            if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
+                reservedMemory.addAndGet(size);
+                count.incrementAndGet();
+                return true;
+            }
         }
+
+        return false;
     }
 
+
+    static void unreserveMemory(long size, int cap) {
+        long cnt = count.decrementAndGet();
+        long reservedMem = reservedMemory.addAndGet(-size);
+        long totalCap = totalCapacity.addAndGet(-cap);
+        assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
+    }
+    */
+
     // -- Monitoring of direct buffer usage --
 
-    // BEGIN Android-changed
+    // BEGIN Android-removed: Remove support for java.lang.management.
     /*
     static {
         // setup access to this package in SharedSecrets
@@ -739,7 +773,10 @@
         });
     }
     */
-    // END Android-changed
+    // END Android-removed: Remove support for java.lang.management.
+
+    // BEGIN Android-removed: Bulk get/put methods are unused on Android.
+    /*
 
     // -- Bulk get/put acceleration --
 
@@ -771,14 +808,14 @@
      *          destination address
      * @param   length
      *          number of bytes to copy
-     */
+     *
     static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
                               long dstAddr, long length)
     {
         long offset = srcBaseOffset + srcPos;
         while (length > 0) {
             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
-            unsafe.copyMemoryFromPrimitiveArray(src, offset, dstAddr, size);
+            unsafe.copyMemory(src, offset, null, dstAddr, size);
             length -= size;
             offset += size;
             dstAddr += size;
@@ -798,14 +835,14 @@
      *          offset within destination array of the first element to write
      * @param   length
      *          number of bytes to copy
-     */
+     *
     static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
                             long length)
     {
         long offset = dstBaseOffset + dstPos;
         while (length > 0) {
             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
-            unsafe.copyMemoryToPrimitiveArray(srcAddr, dst, offset, size);
+            unsafe.copyMemory(null, srcAddr, dst, offset, size);
             length -= size;
             srcAddr += size;
             offset += size;
@@ -838,5 +875,5 @@
                                          long length);
     static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
                                        long length);
-
+    */
 }
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index e4a8d0f..f29cb5d 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -221,7 +221,8 @@
     ByteBuffer(int mark, int pos, int lim, int cap,   // package-private
                  byte[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 0);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 0 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -250,10 +251,8 @@
      *          If the <tt>capacity</tt> is a negative integer
      */
     public static ByteBuffer allocateDirect(int capacity) {
-        if (capacity < 0) {
-            throw new IllegalArgumentException("capacity < 0: " + capacity);
-        }
-
+        // Android-changed: Android's DirectByteBuffers carry a MemoryRef.
+        // return new DirectByteBuffer(capacity);
         DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
         return new DirectByteBuffer(capacity, memoryRef);
     }
@@ -601,25 +600,24 @@
      *          If this buffer is read-only
      */
     public ByteBuffer put(ByteBuffer src) {
-        if (!isAccessible()) {
-            throw new IllegalStateException("buffer is inaccessible");
-        }
-        if (src == this) {
+        if (src == this)
             throw new IllegalArgumentException();
-        }
-        if (isReadOnly) {
+        if (isReadOnly())
             throw new ReadOnlyBufferException();
-        }
         int n = src.remaining();
-        if (n > remaining()) {
+        if (n > remaining())
             throw new BufferOverflowException();
-        }
 
+        // Android-changed: improve ByteBuffer.put(ByteBuffer) performance through bulk copy.
+        /*
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        */
         // Note that we use offset instead of arrayOffset because arrayOffset is specified to
         // throw for read only buffers. Our use of arrayOffset here is provably safe, we only
         // use it to read *from* readOnly buffers.
         if (this.hb != null && src.hb != null) {
-            // System.arraycopy is intrinsified by art and therefore tiny bit faster than memmove
+            // System.arraycopy is intrinsified by ART and therefore tiny bit faster than memmove
             System.arraycopy(src.hb, src.position() + src.offset, hb, position() + offset, n);
         } else {
             // Use the buffer object (and the raw memory address) if it's a direct buffer. Note that
@@ -1086,13 +1084,10 @@
      */
     public abstract char getChar(int index);
 
-    char getCharUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract char getCharUnchecked(int index);
+    abstract void getUnchecked(int pos, char[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing a char
@@ -1119,13 +1114,10 @@
      */
     public abstract ByteBuffer putChar(int index, char value);
 
-    void putCharUnchecked(int index, char value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, char[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putCharUnchecked(int index, char value);
+    abstract void putUnchecked(int pos, char[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as a char buffer.
@@ -1201,13 +1193,10 @@
      */
     public abstract short getShort(int index);
 
-    short getShortUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract short getShortUnchecked(int index);
+    abstract void getUnchecked(int pos, short[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing a short
@@ -1234,13 +1223,10 @@
      */
     public abstract ByteBuffer putShort(int index, short value);
 
-    void putShortUnchecked(int index, short value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, short[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putShortUnchecked(int index, short value);
+    abstract void putUnchecked(int pos, short[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as a short buffer.
@@ -1316,13 +1302,10 @@
      */
     public abstract int getInt(int index);
 
-    int getIntUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract int getIntUnchecked(int index);
+    abstract void getUnchecked(int pos, int[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing an int
@@ -1349,13 +1332,10 @@
      */
     public abstract ByteBuffer putInt(int index, int value);
 
-    void putIntUnchecked(int index, int value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, int[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putIntUnchecked(int index, int value);
+    abstract void putUnchecked(int pos, int[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as an int buffer.
@@ -1431,13 +1411,10 @@
      */
     public abstract long getLong(int index);
 
-    long getLongUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract long getLongUnchecked(int index);
+    abstract void getUnchecked(int pos, long[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing a long
@@ -1464,13 +1441,10 @@
      */
     public abstract ByteBuffer putLong(int index, long value);
 
-    void putLongUnchecked(int index, long value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, long[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putLongUnchecked(int index, long value);
+    abstract void putUnchecked(int pos, long[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as a long buffer.
@@ -1546,13 +1520,10 @@
      */
     public abstract float getFloat(int index);
 
-    float getFloatUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract float getFloatUnchecked(int index);
+    abstract void getUnchecked(int pos, float[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing a float
@@ -1579,13 +1550,10 @@
      */
     public abstract ByteBuffer putFloat(int index, float value);
 
-    void putFloatUnchecked(int index, float value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, float[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putFloatUnchecked(int index, float value);
+    abstract void putUnchecked(int pos, float[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as a float buffer.
@@ -1661,13 +1629,10 @@
      */
     public abstract double getDouble(int index);
 
-    double getDoubleUnchecked(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract double getDoubleUnchecked(int index);
+    abstract void getUnchecked(int pos, double[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Absolute <i>put</i> method for writing a double
@@ -1694,13 +1659,10 @@
      */
     public abstract ByteBuffer putDouble(int index, double value);
 
-    void putDoubleUnchecked(int index, double value) {
-        throw new UnsupportedOperationException();
-    }
-
-    void putUnchecked(int pos, double[] dst, int srcOffset, int length) {
-        throw new UnsupportedOperationException();
-    }
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putDoubleUnchecked(int index, double value);
+    abstract void putUnchecked(int pos, double[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
 
     /**
      * Creates a view of this byte buffer as a double buffer.
@@ -1720,6 +1682,7 @@
      */
     public abstract DoubleBuffer asDoubleBuffer();
 
+    // BEGIN Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
     /**
      * @hide
      */
@@ -1733,4 +1696,5 @@
     public void setAccessible(boolean value) {
         throw new UnsupportedOperationException();
     }
+    // END Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
 }
diff --git a/ojluni/src/main/java/java/nio/CharBuffer.java b/ojluni/src/main/java/java/nio/CharBuffer.java
index 61265d7..fa7423e 100644
--- a/ojluni/src/main/java/java/nio/CharBuffer.java
+++ b/ojluni/src/main/java/java/nio/CharBuffer.java
@@ -135,7 +135,8 @@
     CharBuffer(int mark, int pos, int lim, int cap,   // package-private
                  char[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 1);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 1 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -532,9 +533,14 @@
      * <pre>
      *     src.get(a, 0, a.length) </pre>
      *
-     * @return This buffer
-     * @throws BufferUnderflowException If there are fewer than <tt>length</tt> chars
-     *                                  remaining in this buffer
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> chars
+     *          remaining in this buffer
      */
     public CharBuffer get(char[] dst) {
         return get(dst, 0, dst.length);
@@ -587,6 +593,8 @@
     public CharBuffer put(CharBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
@@ -739,22 +747,17 @@
     public CharBuffer put(String src, int start, int end) {
         checkBounds(start, end - start, src.length());
 
-        // Android-changed: Don't bother making changes to the buffer if there's nothing
-        // to write. This is questionable behaviour but code expects it.
+        // BEGIN Android-added: Don't check readonly/overflow if there's nothing to write.
+        // This is questionable behaviour but code expects it.
         if (start == end) {
             return this;
         }
+        // END Android-added: Don't check readonly/overflow if there's nothing to write.
 
-        // Android-changed: Throw ReadOnlyBufferException as soon as possible.
-        if (isReadOnly()) {
+        if (isReadOnly())
             throw new ReadOnlyBufferException();
-        }
-
-        // Android-changed: Throw as early as we can if there isn't enough space.
-        if ((end - start) > remaining()) {
+        if (end - start > remaining())
             throw new BufferOverflowException();
-        }
-
         for (int i = start; i < end; i++)
             this.put(src.charAt(i));
         return this;
@@ -1219,8 +1222,7 @@
 
     @Override
     public IntStream chars() {
-        CharBuffer self = this;
-        return StreamSupport.intStream(() -> new CharBufferSpliterator(self),
+        return StreamSupport.intStream(() -> new CharBufferSpliterator(this),
             Buffer.SPLITERATOR_CHARACTERISTICS, false);
     }
 }
diff --git a/ojluni/src/main/java/java/nio/DirectByteBuffer.java b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
index badde5a..f12fd7b 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -34,8 +34,8 @@
 import sun.misc.Cleaner;
 import sun.nio.ch.DirectBuffer;
 
-/** @hide */
 // Not final because it is extended in tests.
+/** @hide */
 public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
 
     /**
@@ -250,6 +250,14 @@
     }
 
     @Override
+    public ByteBuffer put(ByteBuffer src) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return super.put(src);
+    }
+
+    @Override
     public final ByteBuffer put(byte x) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
diff --git a/ojluni/src/main/java/java/nio/DoubleBuffer.java b/ojluni/src/main/java/java/nio/DoubleBuffer.java
index d0a0c15..9c3ff87 100644
--- a/ojluni/src/main/java/java/nio/DoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/DoubleBuffer.java
@@ -108,7 +108,8 @@
     DoubleBuffer(int mark, int pos, int lim, int cap,   // package-private
                  double[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 3);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 3 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -464,6 +465,8 @@
     public DoubleBuffer put(DoubleBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
@@ -784,9 +787,7 @@
     public int compareTo(DoubleBuffer that) {
         int n = this.position() + Math.min(this.remaining(), that.remaining());
         for (int i = this.position(), j = that.position(); i < n; i++, j++) {
-            // Android-changed: Call through to Double.compare() instead of
-            // duplicating code pointlessly.
-            int cmp = Double.compare(this.get(i), that.get(j));
+            int cmp = compare(this.get(i), that.get(j));
             if (cmp != 0)
                 return cmp;
         }
diff --git a/ojluni/src/main/java/java/nio/FloatBuffer.java b/ojluni/src/main/java/java/nio/FloatBuffer.java
index 90e65ff..04eac35 100644
--- a/ojluni/src/main/java/java/nio/FloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/FloatBuffer.java
@@ -108,7 +108,8 @@
     FloatBuffer(int mark, int pos, int lim, int cap,   // package-private
                  float[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 2);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 2 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -464,6 +465,8 @@
     public FloatBuffer put(FloatBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/IntBuffer.java b/ojluni/src/main/java/java/nio/IntBuffer.java
index a0004ba..a8cfff8 100644
--- a/ojluni/src/main/java/java/nio/IntBuffer.java
+++ b/ojluni/src/main/java/java/nio/IntBuffer.java
@@ -109,7 +109,8 @@
     IntBuffer(int mark, int pos, int lim, int cap,   // package-private
                  int[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 2);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 2 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -465,6 +466,8 @@
     public IntBuffer put(IntBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/LongBuffer.java b/ojluni/src/main/java/java/nio/LongBuffer.java
index 80e506c..c64b8f5 100644
--- a/ojluni/src/main/java/java/nio/LongBuffer.java
+++ b/ojluni/src/main/java/java/nio/LongBuffer.java
@@ -108,7 +108,8 @@
     LongBuffer(int mark, int pos, int lim, int cap,   // package-private
                  long[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 3);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 3 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -464,6 +465,8 @@
     public LongBuffer put(LongBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/ShortBuffer.java b/ojluni/src/main/java/java/nio/ShortBuffer.java
index 6903b54..13a689f 100644
--- a/ojluni/src/main/java/java/nio/ShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ShortBuffer.java
@@ -108,7 +108,8 @@
     ShortBuffer(int mark, int pos, int lim, int cap,   // package-private
                  short[] hb, int offset)
     {
-        super(mark, pos, lim, cap, 1);
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 1 /* elementSizeShift */);
         this.hb = hb;
         this.offset = offset;
     }
@@ -464,6 +465,8 @@
     public ShortBuffer put(ShortBuffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
diff --git a/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java b/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
index 8e265d6..34065ee 100644
--- a/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
+++ b/ojluni/src/main/java/java/nio/charset/CharsetDecoder.java
@@ -87,9 +87,9 @@
  * <a name="cae"></a>
  *
  * <p> How a decoding error is handled depends upon the action requested for
- * that type of error, which is described by an instance of the {@linkplain
+ * that type of error, which is described by an instance of the {@link
  * CodingErrorAction} class.  The possible error actions are to {@linkplain
- * CodingErrorAction#IGNORE ignore} the erroneous input, {@link
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
  * CodingErrorAction#REPORT report} the error to the invoker via
  * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
  * replace} the erroneous input with the current value of the
@@ -164,7 +164,7 @@
      * Initializes a new decoder.  The new decoder will have the given
      * chars-per-byte and replacement values.
      *
-     * * @param  cs
+     * @param  cs
      *         The charset that created this decoder
      *
      * @param  averageCharsPerByte
@@ -253,7 +253,12 @@
      *          which is never <tt>null</tt> and is never empty
      */
     public final String replacement() {
+
         return replacement;
+
+
+
+
     }
 
     /**
@@ -296,6 +301,7 @@
 
 
 
+
         implReplaceWith(this.replacement);
         return this;
     }
@@ -452,7 +458,7 @@
     /**
      * Returns the maximum number of characters that will be produced for each
      * byte of input.  This value may be used to compute the worst-case size
-     * of the output buffer required for a given input sequence. </p>
+     * of the output buffer required for a given input sequence.
      *
      * @return  The maximum number of characters that will be produced per
      *          byte of input
@@ -978,6 +984,12 @@
 
 
 
+
+
+
+
+
+
     private void throwIllegalStateException(int from, int to) {
         throw new IllegalStateException("Current state = " + stateNames[from]
                                         + ", new state = " + stateNames[to]);
diff --git a/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java b/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
index 38962af..9124282 100644
--- a/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
+++ b/ojluni/src/main/java/java/nio/charset/IllegalCharsetNameException.java
@@ -46,7 +46,7 @@
     private String charsetName;
 
     /**
-     * Constructs an instance of this class. </p>
+     * Constructs an instance of this class.
      *
      * @param  charsetName
      *         The illegal charset name
@@ -57,7 +57,7 @@
     }
 
     /**
-     * Retrieves the illegal charset name. </p>
+     * Retrieves the illegal charset name.
      *
      * @return  The illegal charset name
      */
diff --git a/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java b/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
index 6c04cb1..1774fc0 100644
--- a/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
+++ b/ojluni/src/main/java/java/nio/charset/UnsupportedCharsetException.java
@@ -46,7 +46,7 @@
     private String charsetName;
 
     /**
-     * Constructs an instance of this class. </p>
+     * Constructs an instance of this class.
      *
      * @param  charsetName
      *         The name of the unsupported charset
@@ -57,7 +57,7 @@
     }
 
     /**
-     * Retrieves the name of the unsupported charset. </p>
+     * Retrieves the name of the unsupported charset.
      *
      * @return  The name of the unsupported charset
      */
diff --git a/ojluni/src/main/java/java/security/cert/X509CRL.java b/ojluni/src/main/java/java/security/cert/X509CRL.java
index a233b44..927852b 100644
--- a/ojluni/src/main/java/java/security/cert/X509CRL.java
+++ b/ojluni/src/main/java/java/security/cert/X509CRL.java
@@ -241,16 +241,17 @@
     public void verify(PublicKey key, Provider sigProvider)
         throws CRLException, NoSuchAlgorithmException,
         InvalidKeyException, SignatureException {
-        // BEGIN Android-changed
-        // TODO(31294527): was X509CRLImpl.verify(this, key, sigProvider);
+        // Android-changed: Eliminate infinite recursion in default implementation.
         // As the javadoc says, this "default implementation" was introduced as to avoid breaking
         // providers that generate concrete subclasses of this class.
         // The method X509Impl in the original definition calls this method, thus entering an
-        // infinite loop. This strange behaviour was checked to be not specific to libcore by
-        // running a test with vogar --mode=jvm .
+        // infinite recursive loop. This strange behaviour was checked to be not specific to
+        // libcore by running a test with vogar --mode=jvm .  See b/31294527.
+        // This is fixed upstream in OpenJDK 10.
+        //
+        // X509CRLImpl.verify(this, key, sigProvider);
         throw new UnsupportedOperationException(
                 "X509CRL instance doesn't not support X509CRL#verify(PublicKey, Provider)");
-        // END Android-changed
     }
 
     /**
diff --git a/ojluni/src/main/java/java/security/cert/X509Certificate.java b/ojluni/src/main/java/java/security/cert/X509Certificate.java
index 042eefd..f7cb9ef 100644
--- a/ojluni/src/main/java/java/security/cert/X509Certificate.java
+++ b/ojluni/src/main/java/java/security/cert/X509Certificate.java
@@ -673,11 +673,11 @@
     public void verify(PublicKey key, Provider sigProvider)
         throws CertificateException, NoSuchAlgorithmException,
         InvalidKeyException, SignatureException {
-        // Android-changed: Use Certificate default implementation that
-        // throws UnsupportedOperationException.
+        // Android-changed: Eliminate infinite recursion in default implementation.
         // The method X509CertImpl calls this method, thus entering an
-        // infinite loop. This strange behaviour was checked to be not
-        // specific to libcore by running a test with vogar --mode=jvm
+        // infinite recursive loop. This strange behaviour was checked to be not
+        // specific to libcore by running a test with vogar --mode=jvm.
+        // This is fixed upstream in OpenJDK 10.
         //
         // X509CertImpl.verify(this, key, sigProvider);
         super.verify(key, sigProvider);
diff --git a/ojluni/src/main/java/java/sql/CallableStatement.java b/ojluni/src/main/java/java/sql/CallableStatement.java
index b4769e3..d58c88b 100644
--- a/ojluni/src/main/java/java/sql/CallableStatement.java
+++ b/ojluni/src/main/java/java/sql/CallableStatement.java
@@ -296,6 +296,7 @@
      *             or <code>getBigDecimal(String parameterName)</code>
      * @see #setBigDecimal
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     BigDecimal getBigDecimal(int parameterIndex, int scale)
         throws SQLException;
@@ -2438,4 +2439,6 @@
      */
      void setNClob(String parameterName, Reader reader)
        throws SQLException;
+
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/Connection.java b/ojluni/src/main/java/java/sql/Connection.java
index 3acfd12..b742388 100644
--- a/ojluni/src/main/java/java/sql/Connection.java
+++ b/ojluni/src/main/java/java/sql/Connection.java
@@ -1303,4 +1303,5 @@
  Struct createStruct(String typeName, Object[] attributes)
 throws SQLException;
 
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/DatabaseMetaData.java b/ojluni/src/main/java/java/sql/DatabaseMetaData.java
index 98101ce..8e7441c 100644
--- a/ojluni/src/main/java/java/sql/DatabaseMetaData.java
+++ b/ojluni/src/main/java/java/sql/DatabaseMetaData.java
@@ -3574,4 +3574,5 @@
      */
     int functionReturnsTable    = 2;
 
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/Date.java b/ojluni/src/main/java/java/sql/Date.java
index a64a42f..b96828a 100644
--- a/ojluni/src/main/java/java/sql/Date.java
+++ b/ojluni/src/main/java/java/sql/Date.java
@@ -52,7 +52,8 @@
      * @param day 1 to 31
      * @deprecated instead use the constructor <code>Date(long date)</code>
      */
-    @Deprecated // Android-added
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public Date(int year, int month, int day) {
         super(year, month, day);
     }
@@ -172,6 +173,7 @@
 
     // Override all the time operations inherited from java.util.Date;
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -179,11 +181,13 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #setHours
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public int getHours() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -191,11 +195,13 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #setMinutes
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public int getMinutes() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -203,11 +209,13 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #setSeconds
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public int getSeconds() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -215,11 +223,13 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #getHours
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public void setHours(int i) {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -227,11 +237,13 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #getMinutes
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public void setMinutes(int i) {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL Date
     * values do not have a time component.
@@ -239,7 +251,8 @@
     * @exception java.lang.IllegalArgumentException if this method is invoked
     * @see #getSeconds
     */
-    @Deprecated // Android-added: changed javadoc to include deprecation note.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public void setSeconds(int i) {
         throw new java.lang.IllegalArgumentException();
     }
diff --git a/ojluni/src/main/java/java/sql/Driver.java b/ojluni/src/main/java/java/sql/Driver.java
index a9bdc7d..3970b1c 100644
--- a/ojluni/src/main/java/java/sql/Driver.java
+++ b/ojluni/src/main/java/java/sql/Driver.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2014 The Android Open Source Project
  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -153,4 +154,5 @@
      */
     boolean jdbcCompliant();
 
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/DriverManager.java b/ojluni/src/main/java/java/sql/DriverManager.java
index e7d9c94..a1c378a 100644
--- a/ojluni/src/main/java/java/sql/DriverManager.java
+++ b/ojluni/src/main/java/java/sql/DriverManager.java
@@ -26,8 +26,6 @@
 
 package java.sql;
 
-import dalvik.system.VMStack;
-
 import java.util.Iterator;
 import java.util.ServiceLoader;
 import java.security.AccessController;
@@ -35,7 +33,9 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
+// Android-changed line 2 of the javadoc to "{@code DataSource}".
 /**
  * <P>The basic service for managing a set of JDBC drivers.<br>
  * <B>NOTE:</B> The {@code DataSource} interface, new in the
@@ -80,7 +80,6 @@
  * @see Driver
  * @see Connection
  */
-// Android-changed line 2 of the javadoc to "{@code DataSource}"
 public class DriverManager {
 
 
@@ -188,7 +187,7 @@
     @CallerSensitive
     public static Connection getConnection(String url,
         java.util.Properties info) throws SQLException {
-        return (getConnection(url, info, VMStack.getCallingClassLoader()));
+        return (getConnection(url, info, Reflection.getCallerClass()));
     }
 
     /**
@@ -216,7 +215,7 @@
             info.put("password", password);
         }
 
-        return (getConnection(url, info, VMStack.getCallingClassLoader()));
+        return (getConnection(url, info, Reflection.getCallerClass()));
     }
 
     /**
@@ -234,7 +233,7 @@
         throws SQLException {
 
         java.util.Properties info = new java.util.Properties();
-        return (getConnection(url, info, VMStack.getCallingClassLoader()));
+        return (getConnection(url, info, Reflection.getCallerClass()));
     }
 
     /**
@@ -254,14 +253,14 @@
 
         println("DriverManager.getDriver(\"" + url + "\")");
 
-        ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
+        Class<?> callerClass = Reflection.getCallerClass();
 
         // Walk through the loaded registeredDrivers attempting to locate someone
         // who understands the given URL.
         for (DriverInfo aDriver : registeredDrivers) {
             // If the caller does not have permission to load the driver then
             // skip it.
-            if(isDriverAllowed(aDriver.driver, callerClassLoader)) {
+            if(isDriverAllowed(aDriver.driver, callerClass)) {
                 try {
                     if(aDriver.driver.acceptsURL(url)) {
                         // Success!
@@ -326,7 +325,7 @@
 
         DriverInfo aDriver = new DriverInfo(driver);
         if(registeredDrivers.contains(aDriver)) {
-            if (isDriverAllowed(driver, VMStack.getCallingClassLoader())) {
+            if (isDriverAllowed(driver, Reflection.getCallerClass())) {
                  registeredDrivers.remove(aDriver);
             } else {
                 // If the caller does not have permission to load the driver then
@@ -351,13 +350,13 @@
     public static java.util.Enumeration<Driver> getDrivers() {
         java.util.Vector<Driver> result = new java.util.Vector<Driver>();
 
-        ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
+        Class<?> callerClass = Reflection.getCallerClass();
 
         // Walk through the loaded registeredDrivers.
         for(DriverInfo aDriver : registeredDrivers) {
             // If the caller does not have permission to load the driver then
             // skip it.
-            if(isDriverAllowed(aDriver.driver, callerClassLoader)) {
+            if(isDriverAllowed(aDriver.driver, callerClass)) {
                 result.addElement(aDriver.driver);
             } else {
                 println("    skipping: " + aDriver.getClass().getName());
@@ -389,6 +388,7 @@
         return (loginTimeout);
     }
 
+    // Android-changed: Added reason to @deprecated to improve the documentation.
     /**
      * Sets the logging/tracing PrintStream that is used
      * by the <code>DriverManager</code>
@@ -408,7 +408,8 @@
      * @see SecurityManager#checkPermission
      * @see #getLogStream
      */
-    @Deprecated // Android-added, also changed deprecation comment to include a reason.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public static void setLogStream(java.io.PrintStream out) {
 
         SecurityManager sec = System.getSecurityManager();
@@ -423,6 +424,7 @@
             logWriter = null;
     }
 
+    // Android-changed: Added reason to @deprecated to improve the documentation.
     /**
      * Retrieves the logging/tracing PrintStream that is used by the <code>DriverManager</code>
      * and all drivers.
@@ -431,7 +433,8 @@
      * @deprecated Use {@code getLogWriter} instead.
      * @see #setLogStream
      */
-    @Deprecated // Android-added, also changed deprecation comment to include a reason.
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
+    @Deprecated
     public static java.io.PrintStream getLogStream() {
         return logStream;
     }
@@ -454,6 +457,13 @@
 
     //------------------------------------------------------------------------
 
+    // Indicates whether the class object that would be created if the code calling
+    // DriverManager is accessible.
+    private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
+        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
+        return isDriverAllowed(driver, callerCL);
+    }
+
     private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
         boolean result = false;
         if(driver != null) {
@@ -536,13 +546,14 @@
 
     //  Worker method called by the public getConnection() methods.
     private static Connection getConnection(
-        String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
+        String url, java.util.Properties info, Class<?> caller) throws SQLException {
         /*
          * When callerCl is null, we should check the application's
          * (which is invoking this class indirectly)
          * classloader, so that the JDBC driver class outside rt.jar
          * can be loaded from here.
          */
+        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
         synchronized (DriverManager.class) {
             // synchronize loading of the correct classloader.
             if (callerCL == null) {
diff --git a/ojluni/src/main/java/java/sql/PreparedStatement.java b/ojluni/src/main/java/java/sql/PreparedStatement.java
index 0763390..ef57f69 100644
--- a/ojluni/src/main/java/java/sql/PreparedStatement.java
+++ b/ojluni/src/main/java/java/sql/PreparedStatement.java
@@ -317,6 +317,7 @@
     void setAsciiStream(int parameterIndex, java.io.InputStream x, int length)
             throws SQLException;
 
+    // Android-changed: Added reason to @deprecated to improve the documentation.
     /**
      * Sets the designated parameter to the given input stream, which
      * will have the specified number of bytes.
@@ -343,8 +344,9 @@
      * this method is called on a closed <code>PreparedStatement</code>
      * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
      * this method
-     * @deprecated Deprecated.
+     * @deprecated Use setCharacterStream
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     void setUnicodeStream(int parameterIndex, java.io.InputStream x,
                           int length) throws SQLException;
diff --git a/ojluni/src/main/java/java/sql/ResultSet.java b/ojluni/src/main/java/java/sql/ResultSet.java
index 0b1f6a0..f9ca407 100644
--- a/ojluni/src/main/java/java/sql/ResultSet.java
+++ b/ojluni/src/main/java/java/sql/ResultSet.java
@@ -343,6 +343,7 @@
      */
     double getDouble(int columnIndex) throws SQLException;
 
+    // Android-changed: Added reason to @deprecated to improve the documentation.
     /**
      * Retrieves the value of the designated column in the current row
      * of this <code>ResultSet</code> object as
@@ -360,6 +361,7 @@
      * @deprecated Use {@code getBigDecimal(int columnIndex)}
      *             or {@code getBigDecimal(String columnLabel)}
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException;
 
@@ -480,6 +482,7 @@
      * @deprecated use <code>getCharacterStream</code> in place of
      *              <code>getUnicodeStream</code>
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException;
 
@@ -631,6 +634,7 @@
      */
     double getDouble(String columnLabel) throws SQLException;
 
+    // Android-changed: Added reason to @deprecated to improve the documentation.
     /**
      * Retrieves the value of the designated column in the current row
      * of this <code>ResultSet</code> object as
@@ -648,6 +652,7 @@
      * @deprecated Use {@code getBigDecimal(int columnIndex)}
      *             or {@code getBigDecimal(String columnLabel)}
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException;
 
@@ -766,6 +771,7 @@
      * this method
      * @deprecated use <code>getCharacterStream</code> instead
      */
+    // Android-added: @Deprecated annotation from OpenJDK8u121-b13 to fix build warnings.
     @Deprecated
     java.io.InputStream getUnicodeStream(String columnLabel) throws SQLException;
 
@@ -4083,4 +4089,5 @@
      */
     void updateNClob(String columnLabel,  Reader reader) throws SQLException;
 
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/SQLPermission.java b/ojluni/src/main/java/java/sql/SQLPermission.java
index 505202c..d90cf64 100644
--- a/ojluni/src/main/java/java/sql/SQLPermission.java
+++ b/ojluni/src/main/java/java/sql/SQLPermission.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2014 The Android Open Source Project
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -23,6 +24,7 @@
  * questions.
  */
 
+
 package java.sql;
 
 import java.security.*;
diff --git a/ojluni/src/main/java/java/sql/SQLXML.java b/ojluni/src/main/java/java/sql/SQLXML.java
index 88e3baa..e27edf5 100644
--- a/ojluni/src/main/java/java/sql/SQLXML.java
+++ b/ojluni/src/main/java/java/sql/SQLXML.java
@@ -33,6 +33,8 @@
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see javax.xml.stream
 /**
  * The mapping in the JavaTM programming language for the SQL XML type.
  * XML is a built-in type that stores an XML value
@@ -183,7 +185,6 @@
  * JDBC driver supports the data type.
  *
  * @see javax.xml.parsers
- * @see javax.xml.stream
  * @see javax.xml.transform
  * @see javax.xml.xpath
  * @since 1.6
diff --git a/ojluni/src/main/java/java/sql/Statement.java b/ojluni/src/main/java/java/sql/Statement.java
index 40cd97c..5915114 100644
--- a/ojluni/src/main/java/java/sql/Statement.java
+++ b/ojluni/src/main/java/java/sql/Statement.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2014 The Android Open Source Project
  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1030,4 +1031,5 @@
         boolean isPoolable()
                 throws SQLException;
 
+    // Android-removed: JDBC 4.1 methods were removed immediately after the initial import.
 }
diff --git a/ojluni/src/main/java/java/sql/Time.java b/ojluni/src/main/java/java/sql/Time.java
index 4960ce5..1300003 100644
--- a/ojluni/src/main/java/java/sql/Time.java
+++ b/ojluni/src/main/java/java/sql/Time.java
@@ -144,6 +144,7 @@
 
     // Override all the date operations inherited from java.util.Date;
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a year component.
@@ -152,12 +153,12 @@
     *           method is invoked
     * @see #setYear
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public int getYear() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a month component.
@@ -166,12 +167,12 @@
     *           method is invoked
     * @see #setMonth
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public int getMonth() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a day component.
@@ -179,12 +180,12 @@
     * @exception java.lang.IllegalArgumentException if this
     *           method is invoked
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public int getDay() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a date component.
@@ -193,12 +194,12 @@
     *           method is invoked
     * @see #setDate
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public int getDate() {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a year component.
@@ -207,12 +208,12 @@
     *           method is invoked
     * @see #getYear
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public void setYear(int i) {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a month component.
@@ -221,12 +222,12 @@
     *           method is invoked
     * @see #getMonth
     */
-    // Android-changed javadoc, @deprecated tag now has a reason.
     @Deprecated
     public void setMonth(int i) {
         throw new java.lang.IllegalArgumentException();
     }
 
+   // Android-changed: Moved @deprecated to include a deprecation reason in the documentation.
    /**
     * @deprecated This method is deprecated and should not be used because SQL <code>TIME</code>
     * values do not have a date component.
diff --git a/ojluni/src/main/java/java/text/DecimalFormat.java b/ojluni/src/main/java/java/text/DecimalFormat.java
index 2cb1473..93ed4a3 100644
--- a/ojluni/src/main/java/java/text/DecimalFormat.java
+++ b/ojluni/src/main/java/java/text/DecimalFormat.java
@@ -49,8 +49,6 @@
 import java.util.Currency;
 import java.util.Locale;
 import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import libcore.icu.LocaleData;
diff --git a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
index 070fd1c..6686d8b 100644
--- a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
@@ -46,7 +46,6 @@
 import java.io.Serializable;
 import java.util.Currency;
 import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
 import libcore.icu.ICU;
 import libcore.icu.LocaleData;
 
diff --git a/ojluni/src/main/java/java/text/MessageFormat.java b/ojluni/src/main/java/java/text/MessageFormat.java
index b900824..4a48e9c 100644
--- a/ojluni/src/main/java/java/text/MessageFormat.java
+++ b/ojluni/src/main/java/java/text/MessageFormat.java
@@ -692,7 +692,9 @@
     public void setFormat(int formatElementIndex, Format newFormat) {
         // Android-added: prevent setting unused formatters.
         if (formatElementIndex > maxOffset) {
-            throw new ArrayIndexOutOfBoundsException(maxOffset, formatElementIndex);
+            // Note: maxOffset is maximum index, not the length.
+            throw new ArrayIndexOutOfBoundsException(
+                    "maxOffset=" + maxOffset + "; formatElementIndex=" + formatElementIndex);
         }
         formats[formatElementIndex] = newFormat;
     }
diff --git a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
index 69e35d6..736a8fc 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
@@ -102,7 +102,6 @@
 import java.time.temporal.ValueRange;
 import java.time.temporal.WeekFields;
 import java.time.zone.ZoneRulesProvider;
-import java.util.AbstractMap;
 import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -212,6 +211,10 @@
         }
 
         // Android-changed: get format string from ICU.
+        // LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+        //         .getLocaleResources(locale);
+        // String pattern = lr.getJavaTimeDateTimePattern(
+        //         convertStyle(timeStyle), convertStyle(dateStyle), chrono.getCalendarType());
         String pattern = Calendar.getDateTimeFormatString(
                 ULocale.forLocale(locale), chrono.getCalendarType(),
                 convertStyle(dateStyle), convertStyle(timeStyle));
@@ -3675,8 +3678,22 @@
             SoftReference<Map<Locale, String[]>> ref = cache.get(id);
             Map<Locale, String[]> perLocale = null;
             if (ref == null || (perLocale = ref.get()) == null ||
-                    (names = perLocale.get(locale)) == null) {
+                (names = perLocale.get(locale)) == null) {
                 // BEGIN Android-changed: use ICU TimeZoneNames instead of TimeZoneNameUtility.
+                /*
+                names = TimeZoneNameUtility.retrieveDisplayNames(id, locale);
+                if (names == null) {
+                    return null;
+                }
+                names = Arrays.copyOfRange(names, 0, 7);
+                names[5] =
+                    TimeZoneNameUtility.retrieveGenericDisplayName(id, TimeZone.LONG, locale);
+                if (names[5] == null) {
+                    names[5] = names[0]; // use the id
+                }
+                names[6] =
+                    TimeZoneNameUtility.retrieveGenericDisplayName(id, TimeZone.SHORT, locale);
+                */
                 TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
                 names = new String[TYPES.length + 1];
                 // Zeroth index used for id, other indexes based on NameType constant + 1.
@@ -3764,13 +3781,43 @@
             Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
                 isCaseSensitive ? cachedTree : cachedTreeCI;
 
-            Entry<Integer, SoftReference<PrefixTree>> entry;
-            // BEGIN Android-changed: use ICU TimeZoneNames to get Zone names.
-            PrefixTree tree;
+            Entry<Integer, SoftReference<PrefixTree>> entry = null;
+            PrefixTree tree = null;
+            String[][] zoneStrings = null;
             if ((entry = cached.get(locale)) == null ||
                 (entry.getKey() != regionIdsSize ||
                 (tree = entry.getValue().get()) == null)) {
                 tree = PrefixTree.newTree(context);
+                // BEGIN Android-changed: use ICU TimeZoneNames to get Zone names.
+                /*
+                zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
+                for (String[] names : zoneStrings) {
+                    String zid = names[0];
+                    if (!regionIds.contains(zid)) {
+                        continue;
+                    }
+                    tree.add(zid, zid);    // don't convert zid -> metazone
+                    zid = ZoneName.toZid(zid, locale);
+                    int i = textStyle == TextStyle.FULL ? 1 : 2;
+                    for (; i < names.length; i += 2) {
+                        tree.add(names[i], zid);
+                    }
+                }
+                // if we have a set of preferred zones, need a copy and
+                // add the preferred zones again to overwrite
+                if (preferredZones != null) {
+                    for (String[] names : zoneStrings) {
+                        String zid = names[0];
+                        if (!preferredZones.contains(zid) || !regionIds.contains(zid)) {
+                            continue;
+                        }
+                        int i = textStyle == TextStyle.FULL ? 1 : 2;
+                        for (; i < names.length; i += 2) {
+                            tree.add(names[i], zid);
+                       }
+                    }
+                }
+                */
                 TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
                 long now = System.currentTimeMillis();
                 TimeZoneNames.NameType[] types =
@@ -3800,9 +3847,9 @@
                                 tree.add(names[i], zid);
                             }
                         }
-                        // END Android-changed: use ICU TimeZoneNames to get Zone names.
                     }
                 }
+                // END Android-changed: use ICU TimeZoneNames to get Zone names.
                 cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
             }
             return tree;
@@ -4369,7 +4416,9 @@
          * @throws NullPointerException if chrono or locale is null
          */
         private String getChronologyName(Chronology chrono, Locale locale) {
-            // Android-changed: Use ICU LocaleDisplayNames.
+            // Android-changed: Use ICU LocaleDisplayNames. http://b/28832222
+            // String key = "calendarname." + chrono.getCalendarType();
+            // String name = DateTimeTextProvider.getLocalizedResource(key, locale);
             LocaleDisplayNames displayNames = LocaleDisplayNames.getInstance(ULocale.forLocale(locale));
             String name = displayNames.keyValueDisplayName("calendar", chrono.getCalendarType());
             return name != null ? name : chrono.getId();
diff --git a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
index 2ef9df8..260196a 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
@@ -430,7 +430,28 @@
         }
 
         if (field == IsoFields.QUARTER_OF_YEAR) {
-            // Android-changed: Use ICU resources.
+            // BEGIN Android-changed: Use ICU resources.
+            /*
+            // The order of keys must correspond to the TextStyle.values() order.
+            final String[] keys = {
+                "QuarterNames",
+                "standalone.QuarterNames",
+                "QuarterAbbreviations",
+                "standalone.QuarterAbbreviations",
+                "QuarterNarrows",
+                "standalone.QuarterNarrows",
+            };
+            for (int i = 0; i < keys.length; i++) {
+                String[] names = getLocalizedResource(keys[i], locale);
+                if (names != null) {
+                    Map<Long, String> map = new HashMap<>();
+                    for (int q = 0; q < names.length; q++) {
+                        map.put((long) (q + 1), names[q]);
+                    }
+                    styleMap.put(TextStyle.values()[i], map);
+                }
+            }
+            */
             ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle
                     .getBundleInstance(ICUData.ICU_BASE_NAME, locale);
             ICUResourceBundle quartersRb = rb.getWithFallback("calendar/gregorian/quarters");
@@ -442,13 +463,14 @@
             styleMap.put(TextStyle.SHORT_STANDALONE, extractQuarters(standaloneRb, "abbreviated"));
             styleMap.put(TextStyle.NARROW, extractQuarters(formatRb, "narrow"));
             styleMap.put(TextStyle.NARROW_STANDALONE, extractQuarters(standaloneRb, "narrow"));
+            // END Android-changed: Use ICU resources.
             return new LocaleStore(styleMap);
         }
 
         return "";  // null marker for map
     }
 
-    // Android-added: extractQuarters to extract Map of quarter names from ICU resource bundle.
+    // BEGIN Android-added: Extracts a Map of quarter names from ICU resource bundle.
     private static Map<Long, String> extractQuarters(ICUResourceBundle rb, String key) {
         String[] names = rb.getWithFallback(key).getStringArray();
         Map<Long, String> map = new HashMap<>();
@@ -457,6 +479,7 @@
         }
         return map;
     }
+    // END Android-added: Extracts a Map of quarter names from ICU resource bundle.
 
     /**
      * Helper method to create an immutable entry.
@@ -469,7 +492,24 @@
         return new SimpleImmutableEntry<>(text, field);
     }
 
-    // Android-removed: unused helper method getLocalizedResource.
+    // BEGIN Android-removed: Android uses ICU resources and has no LocaleProviderAdapter.
+    /**
+     * Returns the localized resource of the given key and locale, or null
+     * if no localized resource is available.
+     *
+     * @param key  the key of the localized resource, not null
+     * @param locale  the locale, not null
+     * @return the localized resource, or null if not available
+     * @throws NullPointerException if key or locale is null
+     */
+    // @SuppressWarnings("unchecked")
+    // static <T> T getLocalizedResource(String key, Locale locale) {
+    //     LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+    //                                 .getLocaleResources(locale);
+    //     ResourceBundle rb = lr.getJavaTimeFormatData();
+    //     return rb.containsKey(key) ? (T) rb.getObject(key) : null;
+    // }
+    // END Android-removed: Android uses ICU resources and has no LocaleProviderAdapter.
 
     /**
      * Stores the text for a single locale.
diff --git a/ojluni/src/main/java/java/util/Arrays.java b/ojluni/src/main/java/java/util/Arrays.java
index 72c5f93..3ffead0 100644
--- a/ojluni/src/main/java/java/util/Arrays.java
+++ b/ojluni/src/main/java/java/util/Arrays.java
@@ -78,7 +78,7 @@
      * tasks that makes parallel speedups unlikely.
      * @hide
      */
-    // Android-changed: make public (used by harmony ArraysTest)
+    // Android-changed: Make MIN_ARRAY_SORT_GRAN public and @hide (used by harmony ArraysTest)
     public static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
 
     // Suppresses default constructor, ensuring non-instantiability.
@@ -124,20 +124,6 @@
         }
     }
 
-    // BEGIN Android-added: checkOffsetAndCount() helper method for AIOOBE enforcement.
-    /**
-     * Checks that the range described by {@code offset} and {@code count} doesn't exceed
-     * {@code arrayLength}.
-     * @hide
-     */
-    public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
-        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
-            throw new ArrayIndexOutOfBoundsException(arrayLength, offset,
-                    count);
-        }
-    }
-    // END Android-added: checkOffsetAndCount() helper method for AIOOBE enforcement.
-
     /*
      * Sorting methods. Note that all public "sort" methods take the
      * same form: Performing argument checks if necessary, and then
@@ -1201,6 +1187,8 @@
      * Sorting of complex type arrays.
      */
 
+    // Android-removed: LegacyMergeSort class (unused on Android).
+
     /**
      * Sorts the specified array of objects into ascending order, according
      * to the {@linkplain Comparable natural ordering} of its elements.
@@ -1244,13 +1232,15 @@
      *         {@link Comparable} contract
      */
     public static void sort(Object[] a) {
-        // Android-changed: LegacyMergeSort is no longer supported
+        // Android-removed: LegacyMergeSort support
         // if (LegacyMergeSort.userRequested)
         //     legacyMergeSort(a);
         // else
             ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
     }
 
+    // Android-removed: legacyMergeSort() (unused on Android)
+
     /**
      * Sorts the specified range of the specified array of objects into
      * ascending order, according to the
@@ -1305,13 +1295,15 @@
      */
     public static void sort(Object[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        // Android-changed: LegacyMergeSort is no longer supported
+        // Android-removed: LegacyMergeSort support
         // if (LegacyMergeSort.userRequested)
         //     legacyMergeSort(a, fromIndex, toIndex);
         // else
             ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
     }
 
+    // Android-removed: legacyMergeSort() (unused on Android)
+
     /**
      * Tuning parameter: list size at or below which insertion sort will be
      * used in preference to mergesort.
@@ -1425,7 +1417,7 @@
         if (c == null) {
             sort(a);
         } else {
-            // Android-changed: LegacyMergeSort is no longer supported
+        // Android-removed: LegacyMergeSort support
             // if (LegacyMergeSort.userRequested)
             //     legacyMergeSort(a, c);
             // else
@@ -1433,6 +1425,8 @@
         }
     }
 
+    // Android-removed: legacyMergeSort() (unused on Android)
+
     /**
      * Sorts the specified range of the specified array of objects according
      * to the order induced by the specified comparator.  The range to be
@@ -1491,7 +1485,7 @@
             sort(a, fromIndex, toIndex);
         } else {
             rangeCheck(a.length, fromIndex, toIndex);
-            // Android-changed: LegacyMergeSort is no longer supported
+            // Android-removed: LegacyMergeSort support
             // if (LegacyMergeSort.userRequested)
             //     legacyMergeSort(a, fromIndex, toIndex, c);
             // else
@@ -1499,6 +1493,9 @@
         }
     }
 
+    // Android-removed: legacyMergeSort() (unused on Android)
+    // Android-removed: mergeSort() (unused on Android)
+
     // Parallel prefix
 
     /**
@@ -4113,7 +4110,7 @@
 
         for (Object element : a) {
             int elementHash = 0;
-            // BEGIN Android-changed: getComponentType() is faster than instanceof()
+            // BEGIN Android-changed: getComponentType() is faster than instanceof
             if (element != null) {
                 Class<?> cl = element.getClass().getComponentType();
                 if (cl == null)
@@ -4196,8 +4193,7 @@
 
             if (e1 == e2)
                 continue;
-            // Android-changed: Return early if e2 == null
-            if (e1 == null || e2 == null)
+            if (e1 == null)
                 return false;
 
             // Figure out whether the two elements are equal
@@ -4210,34 +4206,29 @@
     }
 
     static boolean deepEquals0(Object e1, Object e2) {
-        // BEGIN Android-changed: getComponentType() is faster than instanceof()
-        Class<?> cl1 = e1.getClass().getComponentType();
-        Class<?> cl2 = e2.getClass().getComponentType();
-
-        if (cl1 != cl2) {
-            return false;
-        }
-        if (e1 instanceof Object[])
-            return deepEquals ((Object[]) e1, (Object[]) e2);
-        else if (cl1 == byte.class)
-            return equals((byte[]) e1, (byte[]) e2);
-        else if (cl1 == short.class)
-            return equals((short[]) e1, (short[]) e2);
-        else if (cl1 == int.class)
-            return equals((int[]) e1, (int[]) e2);
-        else if (cl1 == long.class)
-            return equals((long[]) e1, (long[]) e2);
-        else if (cl1 == char.class)
-            return equals((char[]) e1, (char[]) e2);
-        else if (cl1 == float.class)
-            return equals((float[]) e1, (float[]) e2);
-        else if (cl1 == double.class)
-            return equals((double[]) e1, (double[]) e2);
-        else if (cl1 == boolean.class)
-            return equals((boolean[]) e1, (boolean[]) e2);
+        assert e1 != null;
+        boolean eq;
+        if (e1 instanceof Object[] && e2 instanceof Object[])
+            eq = deepEquals ((Object[]) e1, (Object[]) e2);
+        else if (e1 instanceof byte[] && e2 instanceof byte[])
+            eq = equals((byte[]) e1, (byte[]) e2);
+        else if (e1 instanceof short[] && e2 instanceof short[])
+            eq = equals((short[]) e1, (short[]) e2);
+        else if (e1 instanceof int[] && e2 instanceof int[])
+            eq = equals((int[]) e1, (int[]) e2);
+        else if (e1 instanceof long[] && e2 instanceof long[])
+            eq = equals((long[]) e1, (long[]) e2);
+        else if (e1 instanceof char[] && e2 instanceof char[])
+            eq = equals((char[]) e1, (char[]) e2);
+        else if (e1 instanceof float[] && e2 instanceof float[])
+            eq = equals((float[]) e1, (float[]) e2);
+        else if (e1 instanceof double[] && e2 instanceof double[])
+            eq = equals((double[]) e1, (double[]) e2);
+        else if (e1 instanceof boolean[] && e2 instanceof boolean[])
+            eq = equals((boolean[]) e1, (boolean[]) e2);
         else
-            return e1.equals(e2);
-        // END Android-changed: getComponentType() is faster than instanceof()
+            eq = e1.equals(e2);
+        return eq;
     }
 
     /**
diff --git a/ojluni/src/main/java/java/util/Base64.java b/ojluni/src/main/java/java/util/Base64.java
index 61f68d3..be98fad 100644
--- a/ojluni/src/main/java/java/util/Base64.java
+++ b/ojluni/src/main/java/java/util/Base64.java
@@ -788,6 +788,9 @@
         public void write(byte[] b, int off, int len) throws IOException {
             if (closed)
                 throw new IOException("Stream is closed");
+            // Android-changed: Upstream fix to avoid overflow.
+            // This upstream fix is from beyond OpenJDK8u121-b13. http://b/62368386
+            // if (off < 0 || len < 0 || off + len > b.length)
             if (off < 0 || len < 0 || len > b.length - off)
                 throw new ArrayIndexOutOfBoundsException();
             if (len == 0)
diff --git a/ojluni/src/main/java/java/util/Collections.java b/ojluni/src/main/java/java/util/Collections.java
index af5237d..d2de25d 100644
--- a/ojluni/src/main/java/java/util/Collections.java
+++ b/ojluni/src/main/java/java/util/Collections.java
@@ -112,8 +112,10 @@
     private static final int REPLACEALL_THRESHOLD     =   11;
     private static final int INDEXOFSUBLIST_THRESHOLD =   35;
 
-    // Android-changed: Warn about Collections.sort() being built on top
-    // of List.sort() when it used to be the other way round in Nougat.
+    // Android-added: List.sort() vs. Collections.sort() app compat.
+    // Added a warning in the documentation.
+    // Collections.sort() calls List.sort() for apps targeting API version >= 26
+    // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
     /**
      * Sorts the specified list into ascending order, according to the
      * {@linkplain Comparable natural ordering} of its elements.
@@ -150,14 +152,17 @@
      */
     @SuppressWarnings("unchecked")
     public static <T extends Comparable<? super T>> void sort(List<T> list) {
-        // Android-changed: Call sort(list, null) here to be consistent
-        // with that method's (Android changed) behavior.
+        // Android-changed: List.sort() vs. Collections.sort() app compat.
+        // Call sort(list, null) here to be consistent with that method's
+        // (changed on Android) behavior.
         // list.sort(null);
         sort(list, null);
     }
 
-    // Android-changed: Warn about Collections.sort() being built on top
-    // of List.sort() when it used to be the other way round in Nougat.
+    // Android-added: List.sort() vs. Collections.sort() app compat.
+    // Added a warning in the documentation.
+    // Collections.sort() calls List.sort() for apps targeting API version >= 26
+    // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
     /**
      * Sorts the specified list according to the order induced by the
      * specified comparator.  All elements in the list must be <i>mutually
@@ -194,7 +199,7 @@
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
     public static <T> void sort(List<T> list, Comparator<? super T> c) {
-        // BEGIN Android-changed: Compat behavior for apps targeting APIs <= 25.
+        // BEGIN Android-changed: List.sort() vs. Collections.sort() app compat.
         // list.sort(c);
         int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
         if (targetSdkVersion > 25) {
@@ -214,7 +219,7 @@
                 i.set((T) a[j]);
             }
         }
-        // END Android-changed: Compat behavior for apps targeting APIs <= 25.
+        // END Android-changed: List.sort() vs. Collections.sort() app compat.
     }
 
 
@@ -1705,8 +1710,10 @@
                     public void remove() {
                         throw new UnsupportedOperationException();
                     }
-                    // Android-note: This seems pretty inconsistent. Unlike other subclasses, we aren't
-                    // delegating to the subclass iterator here. Seems like an oversight.
+                    // Android-note: Oversight of Iterator.forEachRemaining().
+                    // This seems pretty inconsistent. Unlike other subclasses,
+                    // we aren't delegating to the subclass iterator here.
+                    // Seems like an oversight. http://b/110351017
                 };
             }
 
@@ -3119,7 +3126,8 @@
                 public boolean hasNext() { return it.hasNext(); }
                 public E next()          { return it.next(); }
                 public void remove()     {        it.remove(); }};
-            // Android-note: Should we delegate to it for forEachRemaining ?
+            // Android-note: Oversight of Iterator.forEachRemaining().
+            // http://b/110351017
         }
 
         public boolean add(E e)          { return c.add(typeCheck(e)); }
@@ -3804,7 +3812,8 @@
                     public Map.Entry<K,V> next() {
                         return checkedEntry(i.next(), valueType);
                     }
-                    // Android-note: forEachRemaining is missing checks.
+                    // Android-note: Oversight of Iterator.forEachRemaining().
+                    // http://b/110351017
                 };
             }
 
diff --git a/ojluni/src/main/java/java/util/Currency.java b/ojluni/src/main/java/java/util/Currency.java
index 88606aa..a154dc6 100644
--- a/ojluni/src/main/java/java/util/Currency.java
+++ b/ojluni/src/main/java/java/util/Currency.java
@@ -58,24 +58,216 @@
      */
     private final String currencyCode;
 
+    // BEGIN Android-changed: Use ICU.
+    // We do not keep track of defaultFractionDigits and numericCode separately.
+    /*
+    /**
+     * Default fraction digits for this currency.
+     * Set from currency data tables.
+     *
+    transient private final int defaultFractionDigits;
+
+    /**
+     * ISO 4217 numeric code for this currency.
+     * Set from currency data tables.
+     *
+    transient private final int numericCode;
+    */
+    private transient final android.icu.util.Currency icuCurrency;
+    // END Android-changed: Use ICU.
+
+
     // class data: instance map
 
     private static ConcurrentMap<String, Currency> instances = new ConcurrentHashMap<>(7);
     private static HashSet<Currency> available;
 
-    // Android-changed: Implement Currency on top of ICU throughout.
-    // We do not keep track of defaultFractionDigits and numericCode separately here.
-    private transient final android.icu.util.Currency icuCurrency;
+    // BEGIN Android-removed: Use ICU.
+    // We don't need any of these static fields nor the static initializer.
+    /*
+    // Class data: currency data obtained from currency.data file.
+    // Purpose:
+    // - determine valid country codes
+    // - determine valid currency codes
+    // - map country codes to currency codes
+    // - obtain default fraction digits for currency codes
+    //
+    // sc = special case; dfd = default fraction digits
+    // Simple countries are those where the country code is a prefix of the
+    // currency code, and there are no known plans to change the currency.
+    //
+    // table formats:
+    // - mainTable:
+    //   - maps country code to 32-bit int
+    //   - 26*26 entries, corresponding to [A-Z]*[A-Z]
+    //   - \u007F -> not valid country
+    //   - bits 20-31: unused
+    //   - bits 10-19: numeric code (0 to 1023)
+    //   - bit 9: 1 - special case, bits 0-4 indicate which one
+    //            0 - simple country, bits 0-4 indicate final char of currency code
+    //   - bits 5-8: fraction digits for simple countries, 0 for special cases
+    //   - bits 0-4: final char for currency code for simple country, or ID of special case
+    // - special case IDs:
+    //   - 0: country has no currency
+    //   - other: index into sc* arrays + 1
+    // - scCutOverTimes: cut-over time in millis as returned by
+    //   System.currentTimeMillis for special case countries that are changing
+    //   currencies; Long.MAX_VALUE for countries that are not changing currencies
+    // - scOldCurrencies: old currencies for special case countries
+    // - scNewCurrencies: new currencies for special case countries that are
+    //   changing currencies; null for others
+    // - scOldCurrenciesDFD: default fraction digits for old currencies
+    // - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for
+    //   countries that are not changing currencies
+    // - otherCurrencies: concatenation of all currency codes that are not the
+    //   main currency of a simple country, separated by "-"
+    // - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order
+
+    static int formatVersion;
+    static int dataVersion;
+    static int[] mainTable;
+    static long[] scCutOverTimes;
+    static String[] scOldCurrencies;
+    static String[] scNewCurrencies;
+    static int[] scOldCurrenciesDFD;
+    static int[] scNewCurrenciesDFD;
+    static int[] scOldCurrenciesNumericCode;
+    static int[] scNewCurrenciesNumericCode;
+    static String otherCurrencies;
+    static int[] otherCurrenciesDFD;
+    static int[] otherCurrenciesNumericCode;
+
+    // handy constants - must match definitions in GenerateCurrencyData
+    // magic number
+    private static final int MAGIC_NUMBER = 0x43757244;
+    // number of characters from A to Z
+    private static final int A_TO_Z = ('Z' - 'A') + 1;
+    // entry for invalid country codes
+    private static final int INVALID_COUNTRY_ENTRY = 0x0000007F;
+    // entry for countries without currency
+    private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x00000200;
+    // mask for simple case country entries
+    private static final int SIMPLE_CASE_COUNTRY_MASK = 0x00000000;
+    // mask for simple case country entry final character
+    private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x0000001F;
+    // mask for simple case country entry default currency digits
+    private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x000001E0;
+    // shift count for simple case country entry default currency digits
+    private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
+    // maximum number for simple case country entry default currency digits
+    private static final int SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS = 9;
+    // mask for special case country entries
+    private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
+    // mask for special case country index
+    private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
+    // delta from entry index component in main table to index into special case tables
+    private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
+    // mask for distinguishing simple and special case countries
+    private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
+    // mask for the numeric code of the currency
+    private static final int NUMERIC_CODE_MASK = 0x000FFC00;
+    // shift count for the numeric code of the currency
+    private static final int NUMERIC_CODE_SHIFT = 10;
+
+    // Currency data format version
+    private static final int VALID_FORMAT_VERSION = 2;
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                String homeDir = System.getProperty("java.home");
+                try {
+                    String dataFile = homeDir + File.separator +
+                            "lib" + File.separator + "currency.data";
+                    try (DataInputStream dis = new DataInputStream(
+                             new BufferedInputStream(
+                             new FileInputStream(dataFile)))) {
+                        if (dis.readInt() != MAGIC_NUMBER) {
+                            throw new InternalError("Currency data is possibly corrupted");
+                        }
+                        formatVersion = dis.readInt();
+                        if (formatVersion != VALID_FORMAT_VERSION) {
+                            throw new InternalError("Currency data format is incorrect");
+                        }
+                        dataVersion = dis.readInt();
+                        mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
+                        int scCount = dis.readInt();
+                        scCutOverTimes = readLongArray(dis, scCount);
+                        scOldCurrencies = readStringArray(dis, scCount);
+                        scNewCurrencies = readStringArray(dis, scCount);
+                        scOldCurrenciesDFD = readIntArray(dis, scCount);
+                        scNewCurrenciesDFD = readIntArray(dis, scCount);
+                        scOldCurrenciesNumericCode = readIntArray(dis, scCount);
+                        scNewCurrenciesNumericCode = readIntArray(dis, scCount);
+                        int ocCount = dis.readInt();
+                        otherCurrencies = dis.readUTF();
+                        otherCurrenciesDFD = readIntArray(dis, ocCount);
+                        otherCurrenciesNumericCode = readIntArray(dis, ocCount);
+                    }
+                } catch (IOException e) {
+                    throw new InternalError(e);
+                }
+
+                // look for the properties file for overrides
+                String propsFile = System.getProperty("java.util.currency.data");
+                if (propsFile == null) {
+                    propsFile = homeDir + File.separator + "lib" +
+                        File.separator + "currency.properties";
+                }
+                try {
+                    File propFile = new File(propsFile);
+                    if (propFile.exists()) {
+                        Properties props = new Properties();
+                        try (FileReader fr = new FileReader(propFile)) {
+                            props.load(fr);
+                        }
+                        Set<String> keys = props.stringPropertyNames();
+                        Pattern propertiesPattern =
+                            Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
+                                "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
+                                "\\d{2}:\\d{2})?");
+                        for (String key : keys) {
+                           replaceCurrencyData(propertiesPattern,
+                               key.toUpperCase(Locale.ROOT),
+                               props.getProperty(key).toUpperCase(Locale.ROOT));
+                        }
+                    }
+                } catch (IOException e) {
+                    info("currency.properties is ignored because of an IOException", e);
+                }
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Constants for retrieving localized names from the name providers.
+     *
+    private static final int SYMBOL = 0;
+    private static final int DISPLAYNAME = 1;
+    */
+
 
     /**
      * Constructs a <code>Currency</code> instance. The constructor is private
      * so that we can insure that there's never more than one instance for a
      * given currency.
      */
+    // BEGIN Android-changed: Use ICU.
+    // We do not keep track of defaultFractionDigits and numericCode separately.
+    /*
+    private Currency(String currencyCode, int defaultFractionDigits, int numericCode) {
+        this.currencyCode = currencyCode;
+        this.defaultFractionDigits = defaultFractionDigits;
+        this.numericCode = numericCode;
+    }
+    */
     private Currency(android.icu.util.Currency icuCurrency) {
         this.icuCurrency = icuCurrency;
         this.currencyCode = icuCurrency.getCurrencyCode();
     }
+    // END Android-changed: Use ICU.
 
     /**
      * Returns the <code>Currency</code> instance for the given currency code.
@@ -87,7 +279,8 @@
      * a supported ISO 4217 code.
      */
     public static Currency getInstance(String currencyCode) {
-        // BEGIN Android-changed: use ICU
+        // BEGIN Android-changed: Use ICU.
+        // Upstream uses a private static helper method, implemented differently.
         Currency instance = instances.get(currencyCode);
         if (instance != null) {
             return instance;
@@ -98,7 +291,7 @@
             return null;
         }
         Currency currencyVal = new Currency(icuInstance);
-        // END Android-changed
+        // END Android-changed: Use ICU.
         instance = instances.putIfAbsent(currencyCode, currencyVal);
         return (instance != null ? instance : currencyVal);
     }
@@ -125,11 +318,50 @@
      * is not a supported ISO 3166 country code.
      */
     public static Currency getInstance(Locale locale) {
-        // BEGIN Android-changed: use ICU
+        String country = locale.getCountry();
+        if (country == null) {
+            throw new NullPointerException();
+        }
+
+        // BEGIN Android-changed: Use ICU.
+        /*
+        if (country.length() != 2) {
+            throw new IllegalArgumentException();
+        }
+
+        char char1 = country.charAt(0);
+        char char2 = country.charAt(1);
+        int tableEntry = getMainTableEntry(char1, char2);
+        if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
+                    && tableEntry != INVALID_COUNTRY_ENTRY) {
+            char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
+            int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
+            int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
+            StringBuilder sb = new StringBuilder(country);
+            sb.append(finalChar);
+            return getInstance(sb.toString(), defaultFractionDigits, numericCode);
+        } else {
+            // special cases
+            if (tableEntry == INVALID_COUNTRY_ENTRY) {
+                throw new IllegalArgumentException();
+            }
+            if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
+                return null;
+            } else {
+                int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
+                if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
+                    return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index],
+                        scOldCurrenciesNumericCode[index]);
+                } else {
+                    return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index],
+                        scNewCurrenciesNumericCode[index]);
+                }
+            }
+        }
+        */
         android.icu.util.Currency icuInstance =
                 android.icu.util.Currency.getInstance(locale);
         String variant = locale.getVariant();
-        String country = locale.getCountry();
         if (!variant.isEmpty() && (variant.equals("EURO") || variant.equals("HK") ||
                 variant.equals("PREEURO"))) {
             country = country + "_" + variant;
@@ -142,7 +374,7 @@
             return null;
         }
         return getInstance(currencyCode);
-        // END Android-changed
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -158,10 +390,37 @@
     public static Set<Currency> getAvailableCurrencies() {
         synchronized(Currency.class) {
             if (available == null) {
-                // BEGIN Android-changed: use ICU
+                // BEGIN Android-changed: Use ICU.
+                /*
+                available = new HashSet<>(256);
+
+                // Add simple currencies first
+                for (char c1 = 'A'; c1 <= 'Z'; c1 ++) {
+                    for (char c2 = 'A'; c2 <= 'Z'; c2 ++) {
+                        int tableEntry = getMainTableEntry(c1, c2);
+                        if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
+                             && tableEntry != INVALID_COUNTRY_ENTRY) {
+                            char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
+                            int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
+                            int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
+                            StringBuilder sb = new StringBuilder();
+                            sb.append(c1);
+                            sb.append(c2);
+                            sb.append(finalChar);
+                            available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode));
+                        }
+                    }
+                }
+
+                // Now add other currencies
+                StringTokenizer st = new StringTokenizer(otherCurrencies, "-");
+                while (st.hasMoreElements()) {
+                    available.add(getInstance((String)st.nextElement()));
+                }
+                */
+                available = new HashSet<>();
                 Set<android.icu.util.Currency> icuAvailableCurrencies
                         = android.icu.util.Currency.getAvailableCurrencies();
-                available = new HashSet<>();
                 for (android.icu.util.Currency icuCurrency : icuAvailableCurrencies) {
                     Currency currency = getInstance(icuCurrency.getCurrencyCode());
                     if (currency == null) {
@@ -170,7 +429,7 @@
                     }
                     available.add(currency);
                 }
-                // END Android-changed
+                // END Android-changed: Use ICU.
             }
         }
 
@@ -218,12 +477,25 @@
      * @exception NullPointerException if <code>locale</code> is null
      */
     public String getSymbol(Locale locale) {
-        // BEGIN Android-changed: use ICU
+        // BEGIN Android-changed: Use ICU.
+        /*
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
+        String symbol = pool.getLocalizedObject(
+                                CurrencyNameGetter.INSTANCE,
+                                locale, currencyCode, SYMBOL);
+        if (symbol != null) {
+            return symbol;
+        }
+
+        // use currency code as symbol of last resort
+        return currencyCode;
+        */
         if (locale == null) {
             throw new NullPointerException("locale == null");
         }
         return icuCurrency.getSymbol(locale);
-        // END Android-changed
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -236,12 +508,13 @@
      * @return the default number of fraction digits used with this currency
      */
     public int getDefaultFractionDigits() {
-        // BEGIN Android-changed: use ICU
+        // BEGIN Android-changed: Use ICU.
+        // return defaultFractionDigits;
         if (icuCurrency.getCurrencyCode().equals("XXX")) {
             return -1;
         }
         return icuCurrency.getDefaultFractionDigits();
-        // END Android-changed
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -251,8 +524,8 @@
      * @since 1.7
      */
     public int getNumericCode() {
-        // Android-changed: use ICU
-        // was: return numericCode;
+        // Android-changed: Use ICU.
+        // return numericCode;
         return icuCurrency.getNumericCode();
     }
 
@@ -286,7 +559,20 @@
      * @since 1.7
      */
     public String getDisplayName(Locale locale) {
-        // Android-changed: use ICU
+        // Android-changed: Use ICU.
+        /*
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
+        String result = pool.getLocalizedObject(
+                                CurrencyNameGetter.INSTANCE,
+                                locale, currencyCode, DISPLAYNAME);
+        if (result != null) {
+            return result;
+        }
+
+        // use currency code as symbol of last resort
+        return currencyCode;
+        */
         return icuCurrency.getDisplayName(Objects.requireNonNull(locale));
     }
 
@@ -297,7 +583,8 @@
      */
     @Override
     public String toString() {
-        // Android-changed: use ICU
+        // Android-changed: Use ICU.
+        // return currencyCode;
         return icuCurrency.toString();
     }
 
@@ -307,4 +594,7 @@
     private Object readResolve() {
         return getInstance(currencyCode);
     }
+
+    // Android-removed: Use ICU.
+    // Removed a bunch of private helper methods that are unused on Android.
 }
diff --git a/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java b/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
index 599bd18..222d967 100644
--- a/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/DoubleSummaryStatistics.java
@@ -25,6 +25,7 @@
 package java.util;
 
 import java.util.function.DoubleConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index 5e9c028..b5c7997 100644
--- a/ojluni/src/main/java/java/util/Formatter.java
+++ b/ojluni/src/main/java/java/util/Formatter.java
@@ -61,6 +61,7 @@
 import sun.misc.DoubleConsts;
 import sun.misc.FormattedFloatingDecimal;
 
+// Android-changed: Use localized exponent separator for %e.
 /**
  * An interpreter for printf-style format strings.  This class provides support
  * for layout justification and alignment, common formats for numeric, string,
diff --git a/ojluni/src/main/java/java/util/IntSummaryStatistics.java b/ojluni/src/main/java/java/util/IntSummaryStatistics.java
index d16f224..f93436e 100644
--- a/ojluni/src/main/java/java/util/IntSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/IntSummaryStatistics.java
@@ -25,6 +25,7 @@
 package java.util;
 
 import java.util.function.IntConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/List.java b/ojluni/src/main/java/java/util/List.java
index 9cadac1..09970c9 100644
--- a/ojluni/src/main/java/java/util/List.java
+++ b/ojluni/src/main/java/java/util/List.java
@@ -414,9 +414,10 @@
         }
     }
 
-    // Android-changed: Warn about Collections.sort() being built on top
-    // of List.sort() rather than the other way round when targeting an
-    // API version > 25.
+    // Android-added: List.sort() vs. Collections.sort() app compat.
+    // Added a warning in the documentation.
+    // Collections.sort() calls List.sort() for apps targeting API version >= 26
+    // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
     /**
      * Sorts this list according to the order induced by the specified
      * {@link Comparator}.
diff --git a/ojluni/src/main/java/java/util/Locale.java b/ojluni/src/main/java/java/util/Locale.java
index c96bb13..49d7bea 100644
--- a/ojluni/src/main/java/java/util/Locale.java
+++ b/ojluni/src/main/java/java/util/Locale.java
@@ -945,21 +945,23 @@
         return getDefault();
     }
 
-    // BEGIN Android-changed: initDefault changes
-    //  1.) In initDefault(), user.locale gets priority
-    //  2.) In both initDefault methods, use System.getProperty() instead
-    //      of legacy AccessController / GetPropertyAction security code.
     /**
      * @hide visible for testing.
      */
+    // Android-changed: Make initDefault() @hide public for testing.
+    // private static Locale initDefault() {
     public static Locale initDefault() {
+        // BEGIN Android-added: In initDefault(), prioritize user.locale.
         // user.locale gets priority
         final String languageTag = System.getProperty("user.locale", "");
         if (!languageTag.isEmpty()) {
             return Locale.forLanguageTag(languageTag);
         }
+        // END Android-added: In initDefault(), prioritize user.locale.
 
-        // user.locale is empty
+        // BEGIN Android-changed: Short-circuit legacy security code.
+        // Use System.getProperty(name, default) instead of
+        // AccessController.doPrivileged(new GetPropertyAction(name, default)).
         String language, region, script, country, variant;
         language = System.getProperty("user.language", "en");
         // for compatibility, check for old user.region property
@@ -980,21 +982,35 @@
             country = System.getProperty("user.country", "");
             variant = System.getProperty("user.variant", "");
         }
+        // END Android-changed: Short-circuit legacy security code.
 
         return getInstance(language, script, country, variant, null);
     }
 
     private static Locale initDefault(Locale.Category category) {
-        // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
+        // Android-added: Add NoImagePreloadHolder to allow compile-time initialization.
         final Locale defaultLocale = NoImagePreloadHolder.defaultLocale;
+        // BEGIN Android-changed: Short-circuit legacy security code.
+        /*
+        return getInstance(
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
+            null);
+        */
         return getInstance(
             System.getProperty(category.languageKey, defaultLocale.getLanguage()),
             System.getProperty(category.scriptKey, defaultLocale.getScript()),
             System.getProperty(category.countryKey, defaultLocale.getCountry()),
             System.getProperty(category.variantKey, defaultLocale.getVariant()),
             null);
+        // END Android-changed: Short-circuit legacy security code.
     }
-    // END Android-changed: initDefault changes
 
     /**
      * Sets the default locale for this instance of the Java Virtual Machine.
@@ -1091,7 +1107,7 @@
      * @return An array of installed locales.
      */
     public static Locale[] getAvailableLocales() {
-        // Android-changed: Switched to use ICU.
+        // Android-changed: Use ICU.
         // return LocaleServiceProviderPool.getAllAvailableLocales();
         return ICU.getAvailableLocales();
     }
@@ -1108,7 +1124,15 @@
      * @return An array of ISO 3166 two-letter country codes.
      */
     public static String[] getISOCountries() {
-        // Android-changed: Switched to use ICU.
+        // Android-changed: Use ICU.
+        /*
+        if (isoCountries == null) {
+            isoCountries = getISO2Table(LocaleISOData.isoCountryTable);
+        }
+        String[] result = new String[isoCountries.length];
+        System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
+        return result;
+        */
         return ICU.getISOCountries();
     }
 
@@ -1129,10 +1153,31 @@
      * @return Am array of ISO 639 two-letter language codes.
      */
     public static String[] getISOLanguages() {
-        // Android-changed: Switched to use ICU.
+        // Android-changed: Use ICU.
+        /*
+        if (isoLanguages == null) {
+            isoLanguages = getISO2Table(LocaleISOData.isoLanguageTable);
+        }
+        String[] result = new String[isoLanguages.length];
+        System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
+        return result;
+        */
         return ICU.getISOLanguages();
     }
 
+    // Android-removed: Use ICU.
+    // Private helper method getISO2Table(), unused on Android.
+    /*
+    private static String[] getISO2Table(String table) {
+        int len = table.length() / 5;
+        String[] isoTable = new String[len];
+        for (int i = 0, j = 0; i < len; i++, j += 5) {
+            isoTable[i] = table.substring(j, j + 2);
+        }
+        return isoTable;
+    }
+    */
+
     /**
      * Returns the language code of this Locale.
      *
@@ -1676,19 +1721,18 @@
         if (lang.length() == 3) {
             return lang;
         }
-        // BEGIN Android-added
-        // return "" for empty languages for the sake of backwards compatibility.
+        // BEGIN Android-added: app compat: Use "" as ISO3 for empty languages.
         else if (lang.isEmpty()) {
             return "";
         }
-        // END Android-added
+        // END Android-added: app compat: Use "" as ISO3 for empty languages.
 
         // BEGIN Android-changed: Use ICU.
         // String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
         // if (language3 == null) {
         String language3 = ICU.getISO3Language(lang);
         if (!lang.isEmpty() && language3.isEmpty()) {
-        // END Android-changed
+        // END Android-changed: Use ICU.
             throw new MissingResourceException("Couldn't find 3-letter language code for "
                     + lang, "FormatData_" + toString(), "ShortLanguage");
         }
@@ -1709,7 +1753,9 @@
      * three-letter country abbreviation is not available for this locale.
      */
     public String getISO3Country() throws MissingResourceException {
-        // BEGIN Android-changed: Use ICU. Also return "" for missing regions.
+        // BEGIN Android-changed: Use ICU. Also, use "" as ISO3 for missing regions.
+        // String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable);
+        // if (country3 == null) {
         final String region = baseLocale.getRegion();
         // Note that this will return an UN.M49 region code
         if (region.length() == 3) {
@@ -1721,13 +1767,38 @@
         // Prefix "en-" because ICU doesn't really care about what the language is.
         String country3 = ICU.getISO3Country("en-" + region);
         if (!region.isEmpty() && country3.isEmpty()) {
+        // END Android-changed: Use ICU. Also, use "" as ISO3 for missing regions.
             throw new MissingResourceException("Couldn't find 3-letter country code for "
                     + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
         }
-        // END Android-changed
         return country3;
     }
 
+    // Android-removed: Use ICU.
+    // getISO3Code() is unused on Android.
+    /*
+    private static String getISO3Code(String iso2Code, String table) {
+        int codeLength = iso2Code.length();
+        if (codeLength == 0) {
+            return "";
+        }
+
+        int tableLength = table.length();
+        int index = tableLength;
+        if (codeLength == 2) {
+            char c1 = iso2Code.charAt(0);
+            char c2 = iso2Code.charAt(1);
+            for (index = 0; index < tableLength; index += 5) {
+                if (table.charAt(index) == c1
+                    && table.charAt(index + 1) == c2) {
+                    break;
+                }
+            }
+        }
+        return index < tableLength ? table.substring(index + 2, index + 5) : null;
+    }
+    */
+
     /**
      * Returns a name for the locale's language that is appropriate for display to the
      * user.
@@ -1750,8 +1821,30 @@
         return getDisplayLanguage(getDefault(Category.DISPLAY));
     }
 
-    // BEGIN Android-changed: Use ICU; documentation; backwards compatibility hacks;
-    // added private helper methods.
+    // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+    // Use ICU; documentation; backwards compatibility hacks; added private helper methods.
+    /*
+    /**
+     * Returns a name for the locale's language that is appropriate for display to the
+     * user.
+     * If possible, the name returned will be localized according to inLocale.
+     * For example, if the locale is fr_FR and inLocale
+     * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
+     * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
+     * If the name returned cannot be localized according to inLocale,
+     * (say, we don't have a Japanese name for Croatian),
+     * this function falls back on the English name, and finally
+     * on the ISO code as a last-resort value.  If the locale doesn't specify a language,
+     * this function returns the empty string.
+     *
+     * @param inLocale The locale for which to retrieve the display language.
+     * @return The name of the display language appropriate to the given locale.
+     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
+     *
+    public String getDisplayLanguage(Locale inLocale) {
+        return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
+    }
+    */
     /**
      * Returns the name of this locale's language, localized to {@code locale}.
      * If the language name is unknown, the language code is returned.
@@ -1816,7 +1909,7 @@
 
         return true;
     }
-    // END Android-changed
+    // END Android-changed: Documentation and behavior of getDisplay*().
 
     /**
      * Returns a name for the the locale's script that is appropriate for display to
@@ -1846,6 +1939,7 @@
      */
     public String getDisplayScript(Locale inLocale) {
         // BEGIN Android-changed: Use ICU.
+        // return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
         String scriptCode = baseLocale.getScript();
         if (scriptCode.isEmpty()) {
             return "";
@@ -1857,7 +1951,7 @@
         }
 
         return result;
-        // END Android-changed
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -1882,7 +1976,52 @@
         return getDisplayCountry(getDefault(Category.DISPLAY));
     }
 
-    // BEGIN Android-changed: Use ICU; documentation; added private helper methods.
+    // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+    // Use ICU; documentation; added private helper methods.
+    /*
+    /**
+     * Returns a name for the locale's country that is appropriate for display to the
+     * user.
+     * If possible, the name returned will be localized according to inLocale.
+     * For example, if the locale is fr_FR and inLocale
+     * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
+     * inLocale is fr_FR, getDisplayCountry() will return "Etats-Unis".
+     * If the name returned cannot be localized according to inLocale.
+     * (say, we don't have a Japanese name for Croatia),
+     * this function falls back on the English name, and finally
+     * on the ISO code as a last-resort value.  If the locale doesn't specify a country,
+     * this function returns the empty string.
+     *
+     * @param inLocale The locale for which to retrieve the display country.
+     * @return The name of the country appropriate to the given locale.
+     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
+     *
+    public String getDisplayCountry(Locale inLocale) {
+        return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
+    }
+
+    private String getDisplayString(String code, Locale inLocale, int type) {
+        if (code.length() == 0) {
+            return "";
+        }
+
+        if (inLocale == null) {
+            throw new NullPointerException();
+        }
+
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
+        String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
+        String result = pool.getLocalizedObject(
+                                LocaleNameGetter.INSTANCE,
+                                inLocale, key, type, code);
+            if (result != null) {
+                return result;
+            }
+
+        return code;
+    }
+    */
     /**
      * Returns the name of this locale's country, localized to {@code locale}.
      * Returns the empty string if this locale does not correspond to a specific
@@ -1959,7 +2098,7 @@
 
         return true;
     }
-    // END Android-changed: Use ICU; documentation; added private helper methods.
+    // END Android-changed: Documentation and behavior of getDisplay*().
 
     /**
      * Returns a name for the locale's variant code that is appropriate for display to the
@@ -1982,8 +2121,24 @@
      * @return The name of the display variant code appropriate to the given locale.
      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
      */
-    // BEGIN Android-changed: Use ICU; added private helper methods.
     public String getDisplayVariant(Locale inLocale) {
+// BEGIN Android-changed: Documentation and behavior of getDisplay*().
+// Use ICU; added private helper methods.
+/*
+        if (baseLocale.getVariant().length() == 0)
+            return "";
+
+        LocaleResources lr = LocaleProviderAdapter.forJRE().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"));
+    }
+*/
         String variantCode = baseLocale.getVariant();
         if (variantCode.isEmpty()) {
             return "";
@@ -2046,7 +2201,7 @@
 
         return false;
     }
-    // END Android-changed
+// END Android-changed: Documentation and behavior of getDisplay*().
 
     /**
      * Returns a name for the locale that is appropriate for display to the
@@ -2071,7 +2226,115 @@
         return getDisplayName(getDefault(Category.DISPLAY));
     }
 
-    // BEGIN Android-changed: Use ICU.
+    // BEGIN Android-changed: Documentation and behavior of getDisplay*().
+    /*
+    /**
+     * 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:
+     * <blockquote>
+     * language (script, country, variant)<br>
+     * language (country)<br>
+     * language (variant)<br>
+     * script (country)<br>
+     * country<br>
+     * </blockquote>
+     * depending on which fields are specified in the locale.  If the
+     * language, script, country, and variant fields are all empty,
+     * this function returns the empty string.
+     *
+     * @param inLocale The locale for which to retrieve the display name.
+     * @return The name of the locale appropriate to display.
+     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
+     *
+    public String getDisplayName(Locale inLocale) {
+        LocaleResources lr =  LocaleProviderAdapter.forJRE().getLocaleResources(inLocale);
+
+        String languageName = getDisplayLanguage(inLocale);
+        String scriptName = getDisplayScript(inLocale);
+        String countryName = getDisplayCountry(inLocale);
+        String[] variantNames = getDisplayVariantArray(inLocale);
+
+        // 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.
+        // Typically, the format is "MainName (Qualifier, Qualifier)" but this
+        // depends on what pattern is stored in the display locale.
+        String   mainName       = null;
+        String[] qualifierNames = null;
+
+        // The main name is the language, or if there is no language, the script,
+        // then if no script, the country. If there is no language/script/country
+        // (an anomalous situation) then the display name is simply the variant's
+        // display name.
+        if (languageName.length() == 0 && scriptName.length() == 0 && countryName.length() == 0) {
+            if (variantNames.length == 0) {
+                return "";
+            } else {
+                return formatList(variantNames, listPattern, listCompositionPattern);
+            }
+        }
+        ArrayList<String> names = new ArrayList<>(4);
+        if (languageName.length() != 0) {
+            names.add(languageName);
+        }
+        if (scriptName.length() != 0) {
+            names.add(scriptName);
+        }
+        if (countryName.length() != 0) {
+            names.add(countryName);
+        }
+        if (variantNames.length != 0) {
+            names.addAll(Arrays.asList(variantNames));
+        }
+
+        // The first one in the main name
+        mainName = names.get(0);
+
+        // Others are qualifiers
+        int numNames = names.size();
+        qualifierNames = (numNames > 1) ?
+                names.subList(1, numNames).toArray(new String[numNames - 1]) : new String[0];
+
+        // Create an array whose first element is the number of remaining
+        // elements.  This serves as a selector into a ChoiceFormat pattern from
+        // the resource.  The second and third elements are the main name and
+        // the qualifier; if there are no qualifiers, the third element is
+        // unused by the format pattern.
+        Object[] displayNames = {
+            new Integer(qualifierNames.length != 0 ? 2 : 1),
+            mainName,
+            // We could also just call formatList() and have it handle the empty
+            // 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
+        };
+
+        if (displayNamePattern != null) {
+            return new MessageFormat(displayNamePattern).format(displayNames);
+        }
+        else {
+            // If we cannot get the message format pattern, then we use a simple
+            // hard-coded pattern.  This should not occur in practice unless the
+            // installation is missing some core files (FormatData etc.).
+            StringBuilder result = new StringBuilder();
+            result.append((String)displayNames[1]);
+            if (displayNames.length > 2) {
+                result.append(" (");
+                result.append((String)displayNames[2]);
+                result.append(')');
+            }
+            return result.toString();
+        }
+    }
+    */
     /**
      * Returns this locale's language name, country name, and variant, localized
      * to {@code locale}. The exact output form depends on whether this locale
@@ -2133,7 +2396,7 @@
         }
         return buffer.toString();
     }
-    // END Android-changed: Use ICU.
+    // END Android-changed: Documentation and behavior of getDisplay*().
 
     /**
      * Overrides Cloneable.
@@ -2203,6 +2466,7 @@
     private transient volatile int hashCodeValue = 0;
 
     // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
+    // private volatile static Locale defaultLocale = initDefault();
     private static class NoImagePreloadHolder {
         public volatile static Locale defaultLocale = initDefault();
     }
@@ -2211,6 +2475,30 @@
 
     private transient volatile String languageTag;
 
+    // BEGIN Android-removed: Private helper getDisplayVariantArray() unused on Android.
+    /*
+    /**
+     * Return an array of the display names of the variant.
+     * @param bundle the ResourceBundle to use to get the display names
+     * @return an array of display names, possible of zero length.
+     *
+    private String[] getDisplayVariantArray(Locale inLocale) {
+        // Split the variant name into tokens separated by '_'.
+        StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_");
+        String[] names = new String[tokenizer.countTokens()];
+
+        // 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(),
+                                inLocale, DISPLAY_VARIANT);
+        }
+
+        return names;
+    }
+    */
+    // END Android-removed: Private helper getDisplayVariantArray() unused on Android.
+
     /**
      * Format a list using given pattern strings.
      * If either of the patterns is null, then a the list is
@@ -2421,7 +2709,43 @@
     }
 
     // Android-removed: Drop nested private class LocaleNameGetter.
-    // BEGIN Android-added: Add adjustLanguageCode(); for internal use only.
+    /*
+    /**
+     * Obtains a localized locale names from a LocaleNameProvider
+     * implementation.
+     *
+    private static class LocaleNameGetter
+        implements LocaleServiceProviderPool.LocalizedObjectGetter<LocaleNameProvider, String> {
+        private static final LocaleNameGetter INSTANCE = new LocaleNameGetter();
+
+        @Override
+        public String getObject(LocaleNameProvider localeNameProvider,
+                                Locale locale,
+                                String key,
+                                Object... params) {
+            assert params.length == 2;
+            int type = (Integer)params[0];
+            String code = (String)params[1];
+
+            switch(type) {
+            case DISPLAY_LANGUAGE:
+                return localeNameProvider.getDisplayLanguage(code, locale);
+            case DISPLAY_COUNTRY:
+                return localeNameProvider.getDisplayCountry(code, locale);
+            case DISPLAY_VARIANT:
+                return localeNameProvider.getDisplayVariant(code, locale);
+            case DISPLAY_SCRIPT:
+                return localeNameProvider.getDisplayScript(code, locale);
+            default:
+                assert false; // shouldn't happen
+            }
+
+            return null;
+        }
+    }
+    */
+
+    // BEGIN Android-added: adjustLanguageCode(), for internal use only.
     /** @hide for internal use only. */
     public static String adjustLanguageCode(String languageCode) {
         String adjusted = languageCode.toLowerCase(Locale.US);
@@ -2437,7 +2761,7 @@
 
         return adjusted;
     }
-    // END Android-added
+    // END Android-added: adjustLanguageCode(), for internal use only.
 
     /**
      * Enum for locale categories.  These locale categories are used to get/set
@@ -2775,11 +3099,12 @@
          * @see #setExtension(char, String)
          */
         public Builder removeUnicodeLocaleAttribute(String attribute) {
-            // BEGIN Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
+            // BEGIN Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE.
+            // This could probably be contributed back to upstream. http://b/110752069
             if (attribute == null) {
                 throw new NullPointerException("attribute == null");
             }
-            // END Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
+            // END Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE.
 
             try {
                 localeBuilder.removeUnicodeLocaleAttribute(attribute);
diff --git a/ojluni/src/main/java/java/util/LongSummaryStatistics.java b/ojluni/src/main/java/java/util/LongSummaryStatistics.java
index 2ba3959..085aa29 100644
--- a/ojluni/src/main/java/java/util/LongSummaryStatistics.java
+++ b/ojluni/src/main/java/java/util/LongSummaryStatistics.java
@@ -26,6 +26,7 @@
 
 import java.util.function.IntConsumer;
 import java.util.function.LongConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
diff --git a/ojluni/src/main/java/java/util/OptionalInt.java b/ojluni/src/main/java/java/util/OptionalInt.java
index 7907328..61cac03 100644
--- a/ojluni/src/main/java/java/util/OptionalInt.java
+++ b/ojluni/src/main/java/java/util/OptionalInt.java
@@ -87,7 +87,6 @@
      */
     private OptionalInt(int value) {
         this.isPresent = true;
-
         this.value = value;
     }
 
diff --git a/ojluni/src/main/java/java/util/Properties.java b/ojluni/src/main/java/java/util/Properties.java
index 3d6f1db..b413abb 100644
--- a/ojluni/src/main/java/java/util/Properties.java
+++ b/ojluni/src/main/java/java/util/Properties.java
@@ -36,7 +36,8 @@
 import java.io.OutputStreamWriter;
 import java.io.BufferedWriter;
 
-// Android-changed: Removed dead native2ascii links
+// Android-removed: Dead native2ascii links.
+// These links are also gone in OpenJDK 9.
 /**
  * The {@code Properties} class represents a persistent set of
  * properties. The {@code Properties} can be saved to a stream
@@ -360,9 +361,9 @@
                     valueStart = keyLen + 1;
                     hasSep = true;
                     break;
-                }
-                // Android-changed: use of Character.isWhitespace(c) b/25998006
-                else if (Character.isWhitespace(c) && !precedingBackslash) {
+                // Android-changed: Treat all whitespace the same. http://b/25998006
+                // } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
+                } else if (Character.isWhitespace(c) && !precedingBackslash) {
                     valueStart = keyLen + 1;
                     break;
                 }
@@ -375,7 +376,8 @@
             }
             while (valueStart < limit) {
                 c = lr.lineBuf[valueStart];
-                // Android-changed: use of Character.isWhitespace(c) b/25998006
+                // Android-changed: Treat all whitespace the same. http://b/25998006
+                // if (c != ' ' && c != '\t' &&  c != '\f') {
                 if (!Character.isWhitespace(c)) {
                     if (!hasSep && (c == '=' ||  c == ':')) {
                         hasSep = true;
@@ -456,7 +458,8 @@
                     }
                 }
                 if (skipWhiteSpace) {
-                    // Android-changed: use of Character.isWhitespace(c) b/25998006
+                    // Android-changed: Treat all whitespace the same. http://b/25998006
+                    // if (c == ' ' || c == '\t' || c == '\f') {
                     if (Character.isWhitespace(c)) {
                         continue;
                     }
@@ -1141,4 +1144,89 @@
     private static final char[] hexDigit = {
         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
     };
+
+    // Android-removed: Keep OpenJDK7u40's XmlUtils.
+    // XmlSupport's system property based XmlPropertiesProvider
+    // selection does not make sense on Android and has too many
+    // dependencies on classes that are not available on Android.
+    /*
+    /**
+     * Supporting class for loading/storing properties in XML format.
+     *
+     * <p> The {@code load} and {@code store} methods defined here delegate to a
+     * system-wide {@code XmlPropertiesProvider}. On first invocation of either
+     * method then the system-wide provider is located as follows: </p>
+     *
+     * <ol>
+     *   <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
+     *   is defined then it is taken to be the full-qualified name of a concrete
+     *   provider class. The class is loaded with the system class loader as the
+     *   initiating loader. If it cannot be loaded or instantiated using a zero
+     *   argument constructor then an unspecified error is thrown. </li>
+     *
+     *   <li> If the system property is not defined then the service-provider
+     *   loading facility defined by the {@link ServiceLoader} class is used to
+     *   locate a provider with the system class loader as the initiating
+     *   loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
+     *   type. If this process fails then an unspecified error is thrown. If
+     *   there is more than one service provider installed then it is
+     *   not specified as to which provider will be used. </li>
+     *
+     *   <li> If the provider is not found by the above means then a system
+     *   default provider will be instantiated and used. </li>
+     * </ol>
+     *
+    private static class XmlSupport {
+
+        private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
+            String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
+            if (cn == null)
+                return null;
+            try {
+                Class<?> c = Class.forName(cn, true, cl);
+                return (XmlPropertiesProvider)c.newInstance();
+            } catch (ClassNotFoundException |
+                     IllegalAccessException |
+                     InstantiationException x) {
+                throw new ServiceConfigurationError(null, x);
+            }
+        }
+
+        private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
+            Iterator<XmlPropertiesProvider> iterator =
+                 ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
+            return iterator.hasNext() ? iterator.next() : null;
+        }
+
+        private static XmlPropertiesProvider loadProvider() {
+            return AccessController.doPrivileged(
+                new PrivilegedAction<XmlPropertiesProvider>() {
+                    public XmlPropertiesProvider run() {
+                        ClassLoader cl = ClassLoader.getSystemClassLoader();
+                        XmlPropertiesProvider provider = loadProviderFromProperty(cl);
+                        if (provider != null)
+                            return provider;
+                        provider = loadProviderAsService(cl);
+                        if (provider != null)
+                            return provider;
+                        return new jdk.internal.util.xml.BasicXmlPropertiesProvider();
+                }});
+        }
+
+        private static final XmlPropertiesProvider PROVIDER = loadProvider();
+
+        static void load(Properties props, InputStream in)
+            throws IOException, InvalidPropertiesFormatException
+        {
+            PROVIDER.load(props, in);
+        }
+
+        static void save(Properties props, OutputStream os, String comment,
+                         String encoding)
+            throws IOException
+        {
+            PROVIDER.store(props, os, comment, encoding);
+        }
+    }
+    */
 }
diff --git a/ojluni/src/main/java/java/util/ResourceBundle.java b/ojluni/src/main/java/java/util/ResourceBundle.java
index 6fff252..dd07452 100644
--- a/ojluni/src/main/java/java/util/ResourceBundle.java
+++ b/ojluni/src/main/java/java/util/ResourceBundle.java
@@ -59,13 +59,16 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.jar.JarEntry;
 
-import dalvik.system.VMStack;
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 import sun.util.locale.BaseLocale;
 import sun.util.locale.LocaleObjectCache;
 
 
-// Android-changed: Removed reference to ResourceBundleControlProvider.
+// Android-removed: Support for ResourceBundleControlProvider.
+// Removed references to ResourceBundleControlProvider from the documentation.
+// The service provider interface ResourceBundleControlProvider is not
+// available on Android.
 /**
  *
  * Resource bundles contain locale-specific objects.  When your program needs a
@@ -360,7 +363,7 @@
      */
     private volatile Set<String> keySet;
 
-    // Android-changed: Removed use of ResourceBundleControlProvider.
+    // Android-removed: Support for ResourceBundleControlProvider.
     /*
     private static final List<ResourceBundleControlProvider> providers;
 
@@ -464,11 +467,8 @@
      * Automatic determination of the ClassLoader to be used to load
      * resources on behalf of the client.
      */
-    private static ClassLoader getLoader(ClassLoader cl) {
-        // Android-changed: On Android, this method takes a ClassLoader argument:
-        // Callers call {@code getLoader(VMStack.getCallingClassLoader())}
-        // instead of {@code getLoader(Reflection.getCallerClass())}.
-        // ClassLoader cl = caller == null ? null : caller.getClassLoader();
+    private static ClassLoader getLoader(Class<?> caller) {
+        ClassLoader cl = caller == null ? null : caller.getClassLoader();
         if (cl == null) {
             // When the caller's loader is the boot class loader, cl is null
             // here. In that case, ClassLoader.getSystemClassLoader() may
@@ -769,9 +769,7 @@
     public static final ResourceBundle getBundle(String baseName)
     {
         return getBundleImpl(baseName, Locale.getDefault(),
-                             // Android-changed: use of VMStack.getCallingClassLoader()
-                             getLoader(VMStack.getCallingClassLoader()),
-                             // getLoader(Reflection.getCallerClass()),
+                             getLoader(Reflection.getCallerClass()),
                              getDefaultControl(baseName));
     }
 
@@ -813,9 +811,7 @@
     public static final ResourceBundle getBundle(String baseName,
                                                  Control control) {
         return getBundleImpl(baseName, Locale.getDefault(),
-                             // Android-changed: use of VMStack.getCallingClassLoader()
-                             getLoader(VMStack.getCallingClassLoader()),
-                             // getLoader(Reflection.getCallerClass()),
+                             getLoader(Reflection.getCallerClass()),
                              control);
     }
 
@@ -845,9 +841,7 @@
                                                  Locale locale)
     {
         return getBundleImpl(baseName, locale,
-                             // Android-changed: use of VMStack.getCallingClassLoader()
-                             getLoader(VMStack.getCallingClassLoader()),
-                             // getLoader(Reflection.getCallerClass()),
+                             getLoader(Reflection.getCallerClass()),
                              getDefaultControl(baseName));
     }
 
@@ -892,13 +886,12 @@
     public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
                                                  Control control) {
         return getBundleImpl(baseName, targetLocale,
-                             // Android-changed: use of VMStack.getCallingClassLoader()
-                             getLoader(VMStack.getCallingClassLoader()),
-                             // getLoader(Reflection.getCallerClass()),
+                             getLoader(Reflection.getCallerClass()),
                              control);
     }
 
-    // Android-changed: Removed references to ResourceBundleControlProvider.
+    // Android-removed: Support for ResourceBundleControlProvider.
+    // Removed documentation referring to that SPI.
     /**
      * Gets a resource bundle using the specified base name, locale, and class
      * loader.
@@ -1301,7 +1294,17 @@
     }
 
     private static Control getDefaultControl(String baseName) {
-        // Android-changed: Removed used of ResourceBundleControlProvider.
+        // Android-removed: Support for ResourceBundleControlProvider.
+        /*
+        if (providers != null) {
+            for (ResourceBundleControlProvider provider : providers) {
+                Control control = provider.getControl(baseName);
+                if (control != null) {
+                    return control;
+                }
+            }
+        }
+        */
         return Control.INSTANCE;
     }
 
@@ -1737,9 +1740,7 @@
      */
     @CallerSensitive
     public static final void clearCache() {
-        // Android-changed: use of VMStack.getCallingClassLoader()
-        clearCache(getLoader(VMStack.getCallingClassLoader()));
-        // clearCache(getLoader(Reflection.getCallerClass()));
+        clearCache(getLoader(Reflection.getCallerClass()));
     }
 
     /**
@@ -2681,9 +2682,9 @@
                 if (stream != null) {
                     try {
                         // Android-changed: Use UTF-8 for property based resources. b/26879578
+                        // bundle = new PropertyResourceBundle(stream);
                         bundle = new PropertyResourceBundle(
                                 new InputStreamReader(stream, StandardCharsets.UTF_8));
-                        // bundle = new PropertyResourceBundle(stream);
                     } finally {
                         stream.close();
                     }
diff --git a/ojluni/src/main/java/java/util/Scanner.java b/ojluni/src/main/java/java/util/Scanner.java
index a1ce699..15ad8e8 100644
--- a/ojluni/src/main/java/java/util/Scanner.java
+++ b/ojluni/src/main/java/java/util/Scanner.java
@@ -422,17 +422,21 @@
     private int SIMPLE_GROUP_INDEX = 5;
     private String buildIntegerPatternString() {
         String radixDigits = digits.substring(0, radix);
-        // Android-changed: Support non-decimal starting digits. (i.e, a-z are valid radix digits).
-        String nonZeroRadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
-
         // \\p{javaDigit} is not guaranteed to be appropriate
         // here but what can we do? The final authority will be
         // whatever parse method is invoked, so ultimately the
         // Scanner will do the right thing
         String digit = "((?i)["+radixDigits+"]|\\p{javaDigit})";
-        // Android-changed: Support non-decimal starting digits.
-        String groupedNumeral = "("+nonZeroRadixDigits+digit+"?"+digit+"?("+
+        // BEGIN Android-changed: Support non-decimal starting digits.
+        // Ie., in addition to 1-9, a-z are also valid radix digits.
+        /*
+        String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
                                 groupSeparator+digit+digit+digit+")+)";
+        */
+        String non0RadixDigits = "((?i)[" + digits.substring(1, radix) + "]|(" + non0Digit + "))";
+        String groupedNumeral = "("+non0RadixDigits+digit+"?"+digit+"?("+
+                                groupSeparator+digit+digit+digit+")+)";
+        // END Android-changed: Support non-decimal starting digits.
         // digit++ is the possessive form which is necessary for reducing
         // backtracking that would otherwise cause unacceptable performance
         String numeral = "(("+ digit+"++)|"+groupedNumeral+")";
@@ -827,7 +831,8 @@
         // Restore current position and limit for reading
         buf.limit(buf.position());
         buf.position(p);
-        // Android-changed: The matcher implementation eagerly calls toString() so we'll have
+        // Android-added: reset() the matcher after reading.
+        // The matcher implementation eagerly calls toString() so we'll have
         // to update its input whenever the buffer limit, position etc. changes.
         matcher.reset(buf);
     }
@@ -1274,10 +1279,11 @@
     // The next operation should occur in the specified radix but
     // the default is left untouched.
     private void setRadix(int radix) {
-        // Android-changed: Complain loudly if a bogus radix is being set.
+        // BEGIN Android-added: Complain loudly if a bogus radix is being set.
         if (radix > Character.MAX_RADIX) {
             throw new IllegalArgumentException("radix == " + radix);
         }
+        // END Android-added: Complain loudly if a bogus radix is being set.
 
         if (this.radix != radix) {
             // Force rebuilding and recompilation of radix dependent patterns
@@ -2274,9 +2280,10 @@
             result = "NaN";
         if (result.equals(infinityString))
             result = "Infinity";
-        // Android-changed: Match the infinity symbol.
+        // BEGIN Android-added: Match the infinity symbol.
         if (result.equals("\u221E"))
             result = "Infinity";
+        // END Android-added: Match the infinity symbol.
         if (isNegative)
             result = "-" + result;
 
diff --git a/ojluni/src/main/java/java/util/TimeZone.java b/ojluni/src/main/java/java/util/TimeZone.java
index de4d4d1..9fbf348 100644
--- a/ojluni/src/main/java/java/util/TimeZone.java
+++ b/ojluni/src/main/java/java/util/TimeZone.java
@@ -39,16 +39,18 @@
 
 package java.util;
 
-import org.apache.harmony.luni.internal.util.TimezoneGetter;
 import android.icu.text.TimeZoneNames;
 import java.io.IOException;
 import java.io.Serializable;
 import java.time.ZoneId;
+import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import libcore.io.IoUtils;
 import libcore.util.ZoneInfoDB;
 
+import dalvik.system.RuntimeHooks;
+
 /**
  * <code>TimeZone</code> represents a time zone offset, and also figures out daylight
  * savings.
@@ -704,8 +706,8 @@
      */
     static synchronized TimeZone getDefaultRef() {
         if (defaultTimeZone == null) {
-            TimezoneGetter tzGetter = TimezoneGetter.getInstance();
-            String zoneName = (tzGetter != null) ? tzGetter.getId() : null;
+            Supplier<String> tzGetter = RuntimeHooks.getTimeZoneIdSupplier();
+            String zoneName = (tzGetter != null) ? tzGetter.get() : null;
             if (zoneName != null) {
                 zoneName = zoneName.trim();
             }
diff --git a/ojluni/src/main/java/java/util/Vector.java b/ojluni/src/main/java/java/util/Vector.java
index 895430b..61eeb21 100644
--- a/ojluni/src/main/java/java/util/Vector.java
+++ b/ojluni/src/main/java/java/util/Vector.java
@@ -1122,8 +1122,8 @@
      * An optimized version of AbstractList.Itr
      */
     private class Itr implements Iterator<E> {
-        // Android-changed: changes around elementCount, introduced limit.
-        // b/27430229 AOSP commit 6e5b758a4438d2c154dd11a5c04d14a5d2fc907c
+        // Android-added: Change CME behavior: Use added limit field, not elementCount.
+        // http://b/27430229 AOSP commit 6e5b758a4438d2c154dd11a5c04d14a5d2fc907c
         //
         // The "limit" of this iterator. This is the size of the list at the time the
         // iterator was created. Adding & removing elements will invalidate the iteration
@@ -1137,6 +1137,8 @@
         int expectedModCount = modCount;
 
         public boolean hasNext() {
+            // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+            // return cursor != elementCount;
             return cursor < limit;
         }
 
@@ -1144,6 +1146,8 @@
             synchronized (Vector.this) {
                 checkForComodification();
                 int i = cursor;
+                // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+                // if (i >= elementCount)
                 if (i >= limit)
                     throw new NoSuchElementException();
                 cursor = i + 1;
@@ -1158,6 +1162,7 @@
                 checkForComodification();
                 Vector.this.remove(lastRet);
                 expectedModCount = modCount;
+                // Android-added: Change CME behavior: Use added limit field, not elementCount.
                 limit--;
             }
             cursor = lastRet;
@@ -1168,6 +1173,8 @@
         public void forEachRemaining(Consumer<? super E> action) {
             Objects.requireNonNull(action);
             synchronized (Vector.this) {
+                // Android-changed: Change CME behavior: Use added limit field, not elementCount.
+                // final int size = elementCount;
                 final int size = limit;
                 int i = cursor;
                 if (i >= size) {
@@ -1241,6 +1248,7 @@
                 checkForComodification();
                 Vector.this.add(i, e);
                 expectedModCount = modCount;
+                // Android-added: Change CME behavior: Use added limit field, not elementCount.
                 limit++;
             }
             cursor = i + 1;
diff --git a/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
index b1de4f6..976bfe4 100644
--- a/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
+++ b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
@@ -42,6 +42,8 @@
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+// Android-note: Class javadoc changed to remove references to hidden OpenJDK 9 methods.
+
 /**
  * A {@link Future} that may be explicitly completed (setting its
  * value and status), and may be used as a {@link CompletionStage},
@@ -2405,9 +2407,8 @@
      * @param <U> the type of the value
      * @return a new CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public <U> CompletableFuture<U> newIncompleteFuture() {
         return new CompletableFuture<U>();
     }
@@ -2422,9 +2423,8 @@
      *
      * @return the executor
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public Executor defaultExecutor() {
         return ASYNC_POOL;
     }
@@ -2442,9 +2442,8 @@
      *
      * @return the new CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletableFuture<T> copy() {
         return uniCopyStage();
     }
@@ -2461,9 +2460,8 @@
      *
      * @return the new CompletionStage
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletionStage<T> minimalCompletionStage() {
         return uniAsMinimalStage();
     }
@@ -2478,9 +2476,8 @@
      * @param executor the executor to use for asynchronous execution
      * @return this CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier,
                                               Executor executor) {
         if (supplier == null || executor == null)
@@ -2498,9 +2495,8 @@
      * to complete this CompletableFuture
      * @return this CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier) {
         return completeAsync(supplier, defaultExecutor());
     }
@@ -2516,9 +2512,8 @@
      *        {@code timeout} parameter
      * @return this CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit) {
         if (unit == null)
             throw new NullPointerException();
@@ -2539,9 +2534,8 @@
      *        {@code timeout} parameter
      * @return this CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public CompletableFuture<T> completeOnTimeout(T value, long timeout,
                                                   TimeUnit unit) {
         if (unit == null)
@@ -2565,9 +2559,8 @@
      * @param executor the base executor
      * @return the new delayed executor
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public static Executor delayedExecutor(long delay, TimeUnit unit,
                                            Executor executor) {
         if (unit == null || executor == null)
@@ -2586,9 +2579,8 @@
      *        {@code delay} parameter
      * @return the new delayed executor
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public static Executor delayedExecutor(long delay, TimeUnit unit) {
         if (unit == null)
             throw new NullPointerException();
@@ -2604,9 +2596,8 @@
      * @param <U> the type of the value
      * @return the completed CompletionStage
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public static <U> CompletionStage<U> completedStage(U value) {
         return new MinimalStage<U>((value == null) ? NIL : value);
     }
@@ -2619,9 +2610,8 @@
      * @param <U> the type of the value
      * @return the exceptionally completed CompletableFuture
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
         if (ex == null) throw new NullPointerException();
         return new CompletableFuture<U>(new AltResult(ex));
@@ -2636,9 +2626,8 @@
      * @param <U> the type of the value
      * @return the exceptionally completed CompletionStage
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     public static <U> CompletionStage<U> failedStage(Throwable ex) {
         if (ex == null) throw new NullPointerException();
         return new MinimalStage<U>(new AltResult(ex));
diff --git a/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index 2b51d91..5407963 100644
--- a/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/ojluni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -1242,6 +1242,7 @@
      * @return the set view
      */
     // Android-changed: Return type for backwards compat. Was KeySetView<K,V>. http://b/28099367
+    @dalvik.annotation.codegen.CovariantReturnType(returnType = KeySetView.class, presentAfter = 28)
     public Set<K> keySet() {
         KeySetView<K,V> ks;
         return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
@@ -2562,7 +2563,8 @@
      * A padded cell for distributing counts.  Adapted from LongAdder
      * and Striped64.  See their internal docs for explanation.
      */
-    //@jdk.internal.vm.annotation.Contended // Android-removed
+    // Android-removed: @Contended, this hint is not used by the Android runtime.
+    //@jdk.internal.vm.annotation.Contended
     static final class CounterCell {
         volatile long value;
         CounterCell(long x) { value = x; }
diff --git a/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java b/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
index f65371aa..a29208e 100644
--- a/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
+++ b/ojluni/src/main/java/java/util/concurrent/CountedCompleter.java
@@ -42,7 +42,7 @@
  * presence of subtask stalls and blockage than are other forms of
  * ForkJoinTasks, but are less intuitive to program.  Uses of
  * CountedCompleter are similar to those of other completion based
- * components
+ * components (such as {@link java.nio.channels.CompletionHandler})
  * except that multiple <em>pending</em> completions may be necessary
  * to trigger the completion action {@link #onCompletion(CountedCompleter)},
  * not just one.
diff --git a/ojluni/src/main/java/java/util/concurrent/Exchanger.java b/ojluni/src/main/java/java/util/concurrent/Exchanger.java
index b1e9324..f01a705 100644
--- a/ojluni/src/main/java/java/util/concurrent/Exchanger.java
+++ b/ojluni/src/main/java/java/util/concurrent/Exchanger.java
@@ -306,7 +306,8 @@
      * Nodes hold partially exchanged data, plus other per-thread
      * bookkeeping. Padded via @Contended to reduce memory contention.
      */
-    //@jdk.internal.vm.annotation.Contended // Android-removed
+    // Android-removed: @Contended, this hint is not used by the Android runtime.
+    //@jdk.internal.vm.annotation.Contended
     static final class Node {
         int index;              // Arena index
         int bound;              // Last recorded value of Exchanger.bound
diff --git a/ojluni/src/main/java/java/util/concurrent/Executors.java b/ojluni/src/main/java/java/util/concurrent/Executors.java
index 9244136..565fdeb 100644
--- a/ojluni/src/main/java/java/util/concurrent/Executors.java
+++ b/ojluni/src/main/java/java/util/concurrent/Executors.java
@@ -341,6 +341,7 @@
         return new DelegatedScheduledExecutorService(executor);
     }
 
+    // Android-changed: Removed references to SecurityManager from javadoc.
     /**
      * Returns a default thread factory used to create new threads.
      * This factory creates all new threads used by an Executor in the
@@ -358,6 +359,7 @@
         return new DefaultThreadFactory();
     }
 
+    // Android-changed: Dropped documentation for legacy security code.
     /**
      * Legacy security code; do not use.
      */
@@ -424,6 +426,7 @@
             public Object call() throws Exception { return action.run(); }};
     }
 
+    // Android-changed: Dropped documentation for legacy security code.
     /**
      * Legacy security code; do not use.
      */
@@ -433,6 +436,7 @@
         return new PrivilegedCallable<T>(callable);
     }
 
+    // Android-changed: Dropped documentation for legacy security code.
     /**
      * Legacy security code; do not use.
      */
@@ -497,19 +501,20 @@
         final ClassLoader ccl;
 
         PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
-            // BEGIN Android-removed
-            // SecurityManager sm = System.getSecurityManager();
-            // if (sm != null) {
-            //     // Calls to getContextClassLoader from this class
-            //     // never trigger a security check, but we check
-            //     // whether our callers have this permission anyways.
-            //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+            // Android-removed: System.getSecurityManager always returns null.
+            /*
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // Calls to getContextClassLoader from this class
+                // never trigger a security check, but we check
+                // whether our callers have this permission anyways.
+                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 
-            //     // Whether setContextClassLoader turns out to be necessary
-            //     // or not, we fail fast if permission is not available.
-            //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
-            // }
-            // END Android-removed
+                // Whether setContextClassLoader turns out to be necessary
+                // or not, we fail fast if permission is not available.
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            }
+            */
             this.task = task;
             this.acc = AccessController.getContext();
             this.ccl = Thread.currentThread().getContextClassLoader();
@@ -579,18 +584,19 @@
 
         PrivilegedThreadFactory() {
             super();
-            // BEGIN Android-removed
-            // SecurityManager sm = System.getSecurityManager();
-            // if (sm != null) {
-            //     // Calls to getContextClassLoader from this class
-            //     // never trigger a security check, but we check
-            //     // whether our callers have this permission anyways.
-            //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+            // Android-removed: System.getSecurityManager always returns null.
+            /*
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // Calls to getContextClassLoader from this class
+                // never trigger a security check, but we check
+                // whether our callers have this permission anyways.
+                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 
-            //     // Fail fast
-            //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
-            // }
-            // END Android-removed
+                // Fail fast
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            }
+            */
             this.acc = AccessController.getContext();
             this.ccl = Thread.currentThread().getContextClassLoader();
         }
diff --git a/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java b/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
index 9cf9b2d..04ad7d7 100644
--- a/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
+++ b/ojluni/src/main/java/java/util/concurrent/ForkJoinPool.java
@@ -162,7 +162,8 @@
  * @since 1.7
  * @author Doug Lea
  */
-//@jdk.internal.vm.annotation.Contended   // Android-removed
+// Android-removed: @Contended, this hint is not used by the Android runtime.
+//@jdk.internal.vm.annotation.Contended
 public class ForkJoinPool extends AbstractExecutorService {
 
     /*
@@ -781,7 +782,8 @@
      * arrays sharing cache lines. The @Contended annotation alerts
      * JVMs to try to keep instances apart.
      */
-    //@jdk.internal.vm.annotation.Contended   // Android-removed
+    // Android-removed: @Contended, this hint is not used by the Android runtime.
+    //@jdk.internal.vm.annotation.Contended
     static final class WorkQueue {
 
         /**
@@ -820,7 +822,8 @@
         volatile Thread parker;    // == owner during call to park; else null
         volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
 
-      // @jdk.internal.vm.annotation.Contended("group2") // segregate // Android-removed
+      // Android-removed: @Contended, this hint is not used by the Android runtime.
+      // @jdk.internal.vm.annotation.Contended("group2") // segregate
         volatile ForkJoinTask<?> currentSteal; // nonnull when running some task
 
         WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
diff --git a/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java b/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
index 1f25549..efccfa5 100644
--- a/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
+++ b/ojluni/src/main/java/java/util/concurrent/ForkJoinTask.java
@@ -1300,9 +1300,8 @@
      *
      * @return a task, or {@code null} if none are available
      * @since 9
-     * @hide
+     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
-    // Android-changed: hidden
     protected static ForkJoinTask<?> pollSubmission() {
         Thread t;
         return ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
diff --git a/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java b/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
index 03fa594..195f8ac 100644
--- a/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
+++ b/ojluni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
@@ -461,6 +461,7 @@
 
     // stream methods, coded in a way intended to better isolate for
     // maintenance purposes the small differences across forms.
+
     /**
      * Returns a stream producing the given {@code streamSize} number of
      * pseudorandom {@code int} values.
diff --git a/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
index b7d2246..b0096a4 100644
--- a/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
+++ b/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -1545,6 +1545,7 @@
         return handler;
     }
 
+    // Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
     /**
      * Sets the core number of threads.  This overrides any value set
      * in the constructor.  If the new value is smaller than the
@@ -1556,15 +1557,15 @@
      * @throws IllegalArgumentException if {@code corePoolSize < 0}
      * @see #getCorePoolSize
      */
-     // Android-changed: Reverted code that threw an IAE when
-     // {@code corePoolSize} is greater than the {@linkplain #getMaximumPoolSize()
-     // maximum pool size}. This is due to defective code in a commonly used third
-     // party library that does something like :
-     //
-     // exec.setCorePoolSize(N);
-     // exec.setMaxPoolSize(N);
     public void setCorePoolSize(int corePoolSize) {
+        // BEGIN Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
+        // This reverts a change that threw an IAE on that condition. This is due to defective code
+        // in a commonly used third party library that does something like exec.setCorePoolSize(N)
+        // before doing exec.setMaxPoolSize(N).
+        //
+        // if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
         if (corePoolSize < 0)
+        // END Android-changed: Tolerate maximumPoolSize >= corePoolSize during setCorePoolSize().
             throw new IllegalArgumentException();
         int delta = corePoolSize - this.corePoolSize;
         this.corePoolSize = corePoolSize;
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index 8812a8c..cdc1c5b 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -35,7 +35,6 @@
 
 package java.util.concurrent.atomic;
 
-import dalvik.system.VMStack; // Android-added
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
@@ -85,7 +84,7 @@
     public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
                                                               String fieldName) {
         return new AtomicIntegerFieldUpdaterImpl<U>
-            (tclass, fieldName, VMStack.getStackClass1()); // Android-changed
+            (tclass, fieldName, Reflection.getCallerClass());
     }
 
     /**
@@ -384,27 +383,33 @@
             final Field field;
             final int modifiers;
             try {
+                // Android-changed: Skip privilege escalation which is a noop on Android.
+                /*
                 field = AccessController.doPrivileged(
                     new PrivilegedExceptionAction<Field>() {
                         public Field run() throws NoSuchFieldException {
                             return tclass.getDeclaredField(fieldName);
                         }
                     });
+                */
+                field = tclass.getDeclaredField(fieldName);
                 modifiers = field.getModifiers();
-                // BEGIN Android-removed
-                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-                //     caller, tclass, null, modifiers);
-                // ClassLoader cl = tclass.getClassLoader();
-                // ClassLoader ccl = caller.getClassLoader();
-                // if ((ccl != null) && (ccl != cl) &&
-                //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-                // }
-                // END Android-removed
-            // BEGIN Android-removed
-            // } catch (PrivilegedActionException pae) {
-            //     throw new RuntimeException(pae.getException());
-            // END Android-removed
+                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                    caller, tclass, null, modifiers);
+                // BEGIN Android-removed: Skip checkPackageAccess which is a noop on Android.
+                /*
+                ClassLoader cl = tclass.getClassLoader();
+                ClassLoader ccl = caller.getClassLoader();
+                if ((ccl != null) && (ccl != cl) &&
+                    ((cl == null) || !isAncestor(cl, ccl))) {
+                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                }
+                */
+            // BEGIN Android-removed: Skip privilege escalation which is a noop on Android.
+            /*
+            } catch (PrivilegedActionException pae) {
+                throw new RuntimeException(pae.getException());
+            */
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -420,23 +425,24 @@
             this.offset = U.objectFieldOffset(field);
         }
 
-        // BEGIN Android-removed
-        // /**
-        //  * Returns true if the second classloader can be found in the first
-        //  * classloader's delegation chain.
-        //  * Equivalent to the inaccessible: first.isAncestor(second).
-        //  */
-        // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
-        //     ClassLoader acl = first;
-        //     do {
-        //         acl = acl.getParent();
-        //         if (second == acl) {
-        //             return true;
-        //         }
-        //     } while (acl != null);
-        //     return false;
-        // }
-        // END Android-removed
+        // Android-removed: isAncestor's only usage was removed above.
+        /*
+        /**
+         * Returns true if the second classloader can be found in the first
+         * classloader's delegation chain.
+         * Equivalent to the inaccessible: first.isAncestor(second).
+         *
+        private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+            ClassLoader acl = first;
+            do {
+                acl = acl.getParent();
+                if (second == acl) {
+                    return true;
+                }
+            } while (acl != null);
+            return false;
+        }
+        */
 
         /**
          * Checks that target argument is instance of cclass.  On
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index 73c4e3e..447a642 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -35,7 +35,6 @@
 
 package java.util.concurrent.atomic;
 
-import dalvik.system.VMStack; // Android-added
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
@@ -84,7 +83,7 @@
     @CallerSensitive
     public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
                                                            String fieldName) {
-      Class<?> caller = VMStack.getStackClass1(); // Android-changed
+        Class<?> caller = Reflection.getCallerClass();
         if (AtomicLong.VM_SUPPORTS_LONG_CAS)
             return new CASUpdater<U>(tclass, fieldName, caller);
         else
@@ -382,22 +381,33 @@
             final Field field;
             final int modifiers;
             try {
-                field = tclass.getDeclaredField(fieldName); // Android-changed
+                // Android-changed: Skip privilege escalation which is a noop on Android.
+                /*
+                field = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Field>() {
+                        public Field run() throws NoSuchFieldException {
+                            return tclass.getDeclaredField(fieldName);
+                        }
+                    });
+                */
+                field = tclass.getDeclaredField(fieldName);
                 modifiers = field.getModifiers();
-                // BEGIN Android-removed
-                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-                //     caller, tclass, null, modifiers);
-                // ClassLoader cl = tclass.getClassLoader();
-                // ClassLoader ccl = caller.getClassLoader();
-                // if ((ccl != null) && (ccl != cl) &&
-                //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-                // }
-                // END Android-removed
-            // BEGIN Android-removed
-            // } catch (PrivilegedActionException pae) {
-            //     throw new RuntimeException(pae.getException());
-            // END Android-removed
+                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                    caller, tclass, null, modifiers);
+                // Android-removed: Skip checkPackageAccess which is a noop on Android.
+                /*
+                ClassLoader cl = tclass.getClassLoader();
+                ClassLoader ccl = caller.getClassLoader();
+                if ((ccl != null) && (ccl != cl) &&
+                    ((cl == null) || !isAncestor(cl, ccl))) {
+                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                }
+                */
+            // Android-removed: Skip privilege escalation which is a noop on Android.
+            /*
+            } catch (PrivilegedActionException pae) {
+                throw new RuntimeException(pae.getException());
+            */
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -512,22 +522,33 @@
             Field field = null;
             int modifiers = 0;
             try {
-                field = tclass.getDeclaredField(fieldName); // Android-changed
+                // Android-changed: Skip privilege escalation which is a noop on Android.
+                /*
+                field = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Field>() {
+                        public Field run() throws NoSuchFieldException {
+                            return tclass.getDeclaredField(fieldName);
+                        }
+                    });
+                */
+                field = tclass.getDeclaredField(fieldName);
                 modifiers = field.getModifiers();
-                // BEGIN Android-removed
-                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-                //     caller, tclass, null, modifiers);
-                // ClassLoader cl = tclass.getClassLoader();
-                // ClassLoader ccl = caller.getClassLoader();
-                // if ((ccl != null) && (ccl != cl) &&
-                //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-                // }
-                // END Android-removed
-            // BEGIN Android-removed
-            // } catch (PrivilegedActionException pae) {
-            //     throw new RuntimeException(pae.getException());
-            // END Android-removed
+                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                    caller, tclass, null, modifiers);
+                // Android-removed: Skip checkPackageAccess which is a noop on Android.
+                /*
+                ClassLoader cl = tclass.getClassLoader();
+                ClassLoader ccl = caller.getClassLoader();
+                if ((ccl != null) && (ccl != cl) &&
+                    ((cl == null) || !isAncestor(cl, ccl))) {
+                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                }
+                */
+            // Android-removed: Skip privilege escalation which is a noop on Android.
+            /*
+            } catch (PrivilegedActionException pae) {
+                throw new RuntimeException(pae.getException());
+            */
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -604,21 +625,22 @@
         }
     }
 
-    // BEGIN Android-removed
-    // /**
-    //  * Returns true if the second classloader can be found in the first
-    //  * classloader's delegation chain.
-    //  * Equivalent to the inaccessible: first.isAncestor(second).
-    //  */
-    // static boolean isAncestor(ClassLoader first, ClassLoader second) {
-    //     ClassLoader acl = first;
-    //     do {
-    //         acl = acl.getParent();
-    //         if (second == acl) {
-    //             return true;
-    //         }
-    //     } while (acl != null);
-    //     return false;
-    // }
-    // END Android-removed
+    // Android-removed: isAncestor's only usage was removed above.
+    /*
+    /**
+     * Returns true if the second classloader can be found in the first
+     * classloader's delegation chain.
+     * Equivalent to the inaccessible: first.isAncestor(second).
+     *
+    static boolean isAncestor(ClassLoader first, ClassLoader second) {
+        ClassLoader acl = first;
+        do {
+            acl = acl.getParent();
+            if (second == acl) {
+                return true;
+            }
+        } while (acl != null);
+        return false;
+    }
+    */
 }
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index 5164f36..17423ad 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -35,7 +35,6 @@
 
 package java.util.concurrent.atomic;
 
-import dalvik.system.VMStack; // Android-added
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
@@ -107,7 +106,7 @@
                                                                     Class<W> vclass,
                                                                     String fieldName) {
         return new AtomicReferenceFieldUpdaterImpl<U,W>
-            (tclass, vclass, fieldName, VMStack.getStackClass1()); // Android-changed
+            (tclass, vclass, fieldName, Reflection.getCallerClass());
     }
 
     /**
@@ -317,23 +316,34 @@
             final Class<?> fieldClass;
             final int modifiers;
             try {
-                field = tclass.getDeclaredField(fieldName); // Android-changed
+                // Android-changed: Skip privilege escalation which is a noop on Android.
+                /*
+                field = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Field>() {
+                        public Field run() throws NoSuchFieldException {
+                            return tclass.getDeclaredField(fieldName);
+                        }
+                    });
+                */
+                field = tclass.getDeclaredField(fieldName);
                 modifiers = field.getModifiers();
-                // BEGIN Android-removed
-                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-                //     caller, tclass, null, modifiers);
-                // ClassLoader cl = tclass.getClassLoader();
-                // ClassLoader ccl = caller.getClassLoader();
-                // if ((ccl != null) && (ccl != cl) &&
-                //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-                // }
-                // END Android-removed
+                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                    caller, tclass, null, modifiers);
+                // Android-removed: Skip checkPackageAccess which is a noop on Android.
+                /*
+                ClassLoader cl = tclass.getClassLoader();
+                ClassLoader ccl = caller.getClassLoader();
+                if ((ccl != null) && (ccl != cl) &&
+                    ((cl == null) || !isAncestor(cl, ccl))) {
+                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                }
+                */
                 fieldClass = field.getType();
-            // BEGIN Android-removed
-            // } catch (PrivilegedActionException pae) {
-            //     throw new RuntimeException(pae.getException());
-            // END Android-removed
+            // Android-removed: Skip privilege escalation which is a noop on Android.
+            /*
+            } catch (PrivilegedActionException pae) {
+                throw new RuntimeException(pae.getException());
+            */
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -352,23 +362,24 @@
             this.offset = U.objectFieldOffset(field);
         }
 
-        // BEGIN Android-removed
-        // /**
-        //  * Returns true if the second classloader can be found in the first
-        //  * classloader's delegation chain.
-        //  * Equivalent to the inaccessible: first.isAncestor(second).
-        //  */
-        // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
-        //     ClassLoader acl = first;
-        //     do {
-        //         acl = acl.getParent();
-        //         if (second == acl) {
-        //             return true;
-        //         }
-        //     } while (acl != null);
-        //     return false;
-        // }
-        // END Android-removed
+        // Android-removed: isAncestor's only usage was removed above.
+        /*
+        /**
+         * Returns true if the second classloader can be found in the first
+         * classloader's delegation chain.
+         * Equivalent to the inaccessible: first.isAncestor(second).
+         *
+        private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+            ClassLoader acl = first;
+            do {
+                acl = acl.getParent();
+                if (second == acl) {
+                    return true;
+                }
+            } while (acl != null);
+            return false;
+        }
+        */
 
         /**
          * Checks that target argument is instance of cclass.  On
diff --git a/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java b/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
index e52729a..2a8f327 100644
--- a/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
+++ b/ojluni/src/main/java/java/util/concurrent/atomic/Striped64.java
@@ -119,7 +119,8 @@
      * JVM intrinsics note: It would be possible to use a release-only
      * form of CAS here, if it were provided.
      */
-    // @jdk.internal.vm.annotation.Contended // Android-removed
+    // Android-removed: @Contended, this hint is not used by the Android runtime.
+    // @jdk.internal.vm.annotation.Contended
     static final class Cell {
         volatile long value;
         Cell(long x) { value = x; }
diff --git a/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 894de90..602b5ce 100644
--- a/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/ojluni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -886,6 +886,8 @@
      * @param arg the acquire argument
      * @return {@code true} if interrupted while waiting
      */
+    // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+    // @ReservedStackAccess
     final boolean acquireQueued(final Node node, int arg) {
         try {
             boolean interrupted = false;
@@ -1218,6 +1220,8 @@
      *        {@link #tryAcquire} but is otherwise uninterpreted and
      *        can represent anything you like.
      */
+    // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+    // @ReservedStackAccess
     public final void acquire(int arg) {
         if (!tryAcquire(arg) &&
             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
@@ -1281,6 +1285,8 @@
      *        can represent anything you like.
      * @return the value returned from {@link #tryRelease}
      */
+    // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+    // @ReservedStackAccess
     public final boolean release(int arg) {
         if (tryRelease(arg)) {
             Node h = head;
@@ -1361,6 +1367,8 @@
      *        and can represent anything you like.
      * @return the value returned from {@link #tryReleaseShared}
      */
+    // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+    // @ReservedStackAccess
     public final boolean releaseShared(int arg) {
         if (tryReleaseShared(arg)) {
             doReleaseShared();
diff --git a/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
index 9df2505..3c1c492 100644
--- a/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
+++ b/ojluni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
@@ -127,6 +127,8 @@
          * Performs non-fair tryLock.  tryAcquire is implemented in
          * subclasses, but both need nonfair try for trylock method.
          */
+        // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+        // @ReservedStackAccess
         final boolean nonfairTryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
@@ -146,6 +148,8 @@
             return false;
         }
 
+        // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+        // @ReservedStackAccess
         protected final boolean tryRelease(int releases) {
             int c = getState() - releases;
             if (Thread.currentThread() != getExclusiveOwnerThread())
@@ -203,6 +207,8 @@
          * Performs lock.  Try immediate barge, backing up to normal
          * acquire on failure.
          */
+        // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+        // @ReservedStackAccess
         final void lock() {
             if (compareAndSetState(0, 1))
                 setExclusiveOwnerThread(Thread.currentThread());
@@ -229,6 +235,8 @@
          * Fair version of tryAcquire.  Don't grant access unless
          * recursive call or no waiters or is first.
          */
+        // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
+        // @ReservedStackAccess
         protected final boolean tryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
diff --git a/ojluni/src/main/java/java/util/jar/Attributes.java b/ojluni/src/main/java/java/util/jar/Attributes.java
index 9193542..dd279a5 100644
--- a/ojluni/src/main/java/java/util/jar/Attributes.java
+++ b/ojluni/src/main/java/java/util/jar/Attributes.java
@@ -528,7 +528,7 @@
          * <code>Name</code> object for <code>Manifest-Version</code>
          * manifest attribute. This attribute indicates the version number
          * of the manifest standard to which a JAR file's manifest conforms.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR Manifest">
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR_Manifest">
          *      Manifest and Signature Specification</a>
          */
         public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
@@ -536,7 +536,7 @@
         /**
          * <code>Name</code> object for <code>Signature-Version</code>
          * manifest attribute used when signing JAR files.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR Manifest">
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#JAR_Manifest">
          *      Manifest and Signature Specification</a>
          */
         public static final Name SIGNATURE_VERSION = new Name("Signature-Version");
@@ -669,10 +669,5 @@
          *      Java Product Versioning Specification</a>
          */
         public static final Name SPECIFICATION_VENDOR = new Name("Specification-Vendor");
-
-        /**
-         * @hide
-         */
-        public static final Name NAME = new Name("Name");
     }
 }
diff --git a/ojluni/src/main/java/java/util/jar/JarFile.java b/ojluni/src/main/java/java/util/jar/JarFile.java
index cf8acd8..342e341 100644
--- a/ojluni/src/main/java/java/util/jar/JarFile.java
+++ b/ojluni/src/main/java/java/util/jar/JarFile.java
@@ -67,7 +67,8 @@
  */
 public
 class JarFile extends ZipFile {
-    static final String META_DIR = "META-INF/";
+    // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+    // private SoftReference<Manifest> manRef;
     private Manifest manifest;
     private JarEntry manEntry;
     private JarVerifier jv;
@@ -79,6 +80,14 @@
     // true if manifest checked for special attributes
     private volatile boolean hasCheckedSpecialAttributes;
 
+    // Android-removed: SharedSecrets.setJavaUtilJarAccess
+    /*
+    // Set up JavaUtilJarAccess in SharedSecrets
+    static {
+        SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
+    }
+    */
+
     /**
      * The JAR manifest file name.
      */
@@ -174,8 +183,15 @@
         return getManifestFromReference();
     }
 
+    // BEGIN Android-changed: Fix JarFile to be thread safe. http://b/27826114
+    // A volatile field might also work instead of synchronized. http://b/81505612
+    // private Manifest getManifestFromReference() throws IOException {
     private synchronized Manifest getManifestFromReference() throws IOException {
-        if (manifest == null) {
+    // END Android-changed: Fix JarFile to be thread safe. http://b/27826114
+        // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+        // Manifest man = manRef != null ? manRef.get() : null;
+        Manifest man = manifest;
+        if (man == null) {
 
             JarEntry manEntry = getManEntry();
 
@@ -183,16 +199,19 @@
             if (manEntry != null) {
                 if (verify) {
                     byte[] b = getBytes(manEntry);
-                    manifest = new Manifest(new ByteArrayInputStream(b));
+                    man = new Manifest(new ByteArrayInputStream(b));
                     if (!jvInitialized) {
                         jv = new JarVerifier(b);
                     }
                 } else {
-                    manifest = new Manifest(super.getInputStream(manEntry));
+                    man = new Manifest(super.getInputStream(manEntry));
                 }
+                // Android-changed: Hold the Manifest via a hard reference. http://b/28692091
+                // manRef = new SoftReference<>(man);
+                manifest = man;
             }
         }
-        return manifest;
+        return man;
     }
 
     private native String[] getMetaInfEntryNames();
@@ -479,7 +498,11 @@
         CLASSPATH_OPTOSFT[9]=1;
     }
 
+    // BEGIN Android-changed: Fix JarFile to be thread safe. http://b/27826114
+    // A volatile field might also work instead of synchronized. http://b/81505612
+    // private JarEntry getManEntry() {
     private synchronized JarEntry getManEntry() {
+    // END Android-changed: Fix JarFile to be thread safe. http://b/27826114
         if (manEntry == null) {
             // First look up manifest entry using standard name
             manEntry = getJarEntry(MANIFEST_NAME);
@@ -501,11 +524,14 @@
         return manEntry;
     }
 
-    /**
-     * Returns {@code true} iff this JAR file has a manifest with the
-     * Class-Path attribute
-     * @hide
-     */
+   /**
+    * Returns {@code true} iff this JAR file has a manifest with the
+    * Class-Path attribute
+    * @hide
+    */
+    // Android-changed: Make hasClassPathAttribute() @hide public, for internal use.
+    // Used by URLClassPath.JarLoader.
+    // boolean hasClassPathAttribute() throws IOException {
     public boolean hasClassPathAttribute() throws IOException {
         checkForSpecialAttributes();
         return hasClassPathAttribute;
@@ -541,8 +567,8 @@
      */
     private void checkForSpecialAttributes() throws IOException {
         if (hasCheckedSpecialAttributes) return;
-        // Android-changed: Doesn't make sense on android:
-        //if (!isKnownNotToHaveSpecialAttributes()) {
+        // Android-changed: Special handling of well-known .jar files specific to OpenJDK.
+        // if (!isKnownNotToHaveSpecialAttributes()) {
         {
             JarEntry manEntry = getManEntry();
             if (manEntry != null) {
@@ -555,8 +581,9 @@
     }
 
 
-    // Android-changed: Doesn't make sense on android:
-    /*private static String javaHome;
+    // Android-removed: Special handling of well-known .jar files specific to OpenJDK.
+    /*
+    private static String javaHome;
     private static volatile String[] jarNames;
     private boolean isKnownNotToHaveSpecialAttributes() {
         // Optimize away even scanning of manifest for jar files we
@@ -596,9 +623,199 @@
             }
         }
         return false;
-    }*/
+    }
+    */
+
+    // Android-removed: Unused method ensureInitialization().
+    /*
+    private synchronized void ensureInitialization() {
+        try {
+            maybeInstantiateVerifier();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        if (jv != null && !jvInitialized) {
+            initializeVerifier();
+            jvInitialized = true;
+        }
+    }
+    */
 
     JarEntry newEntry(ZipEntry ze) {
         return new JarFileEntry(ze);
     }
+
+    // Android-removed: Unused methods entryNames(), entries2().
+    /*
+    Enumeration<String> entryNames(CodeSource[] cs) {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.entryNames(this, cs);
+        }
+
+        /*
+         * JAR file has no signed content. Is there a non-signing
+         * code source?
+         *
+        boolean includeUnsigned = false;
+        for (int i = 0; i < cs.length; i++) {
+            if (cs[i].getCodeSigners() == null) {
+                includeUnsigned = true;
+                break;
+            }
+        }
+        if (includeUnsigned) {
+            return unsignedEntryNames();
+        } else {
+            return new Enumeration<String>() {
+
+                public boolean hasMoreElements() {
+                    return false;
+                }
+
+                public String nextElement() {
+                    throw new NoSuchElementException();
+                }
+            };
+        }
+    }
+
+    /**
+     * Returns an enumeration of the zip file entries
+     * excluding internal JAR mechanism entries and including
+     * signed entries missing from the ZIP directory.
+     *
+    Enumeration<JarEntry> entries2() {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.entries2(this, super.entries());
+        }
+
+        // screen out entries which are never signed
+        final Enumeration<? extends ZipEntry> enum_ = super.entries();
+        return new Enumeration<JarEntry>() {
+
+            ZipEntry entry;
+
+            public boolean hasMoreElements() {
+                if (entry != null) {
+                    return true;
+                }
+                while (enum_.hasMoreElements()) {
+                    ZipEntry ze = enum_.nextElement();
+                    if (JarVerifier.isSigningRelated(ze.getName())) {
+                        continue;
+                    }
+                    entry = ze;
+                    return true;
+                }
+                return false;
+            }
+
+            public JarFileEntry nextElement() {
+                if (hasMoreElements()) {
+                    ZipEntry ze = entry;
+                    entry = null;
+                    return new JarFileEntry(ze);
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    CodeSource[] getCodeSources(URL url) {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.getCodeSources(this, url);
+        }
+
+        /*
+         * JAR file has no signed content. Is there a non-signing
+         * code source?
+         *
+        Enumeration<String> unsigned = unsignedEntryNames();
+        if (unsigned.hasMoreElements()) {
+            return new CodeSource[]{JarVerifier.getUnsignedCS(url)};
+        } else {
+            return null;
+        }
+    }
+
+    private Enumeration<String> unsignedEntryNames() {
+        final Enumeration<JarEntry> entries = entries();
+        return new Enumeration<String>() {
+
+            String name;
+
+            /*
+             * Grab entries from ZIP directory but screen out
+             * metadata.
+             *
+            public boolean hasMoreElements() {
+                if (name != null) {
+                    return true;
+                }
+                while (entries.hasMoreElements()) {
+                    String value;
+                    ZipEntry e = entries.nextElement();
+                    value = e.getName();
+                    if (e.isDirectory() || JarVerifier.isSigningRelated(value)) {
+                        continue;
+                    }
+                    name = value;
+                    return true;
+                }
+                return false;
+            }
+
+            public String nextElement() {
+                if (hasMoreElements()) {
+                    String value = name;
+                    name = null;
+                    return value;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    CodeSource getCodeSource(URL url, String name) {
+        ensureInitialization();
+        if (jv != null) {
+            if (jv.eagerValidation) {
+                CodeSource cs = null;
+                JarEntry je = getJarEntry(name);
+                if (je != null) {
+                    cs = jv.getCodeSource(url, this, je);
+                } else {
+                    cs = jv.getCodeSource(url, name);
+                }
+                return cs;
+            } else {
+                return jv.getCodeSource(url, name);
+            }
+        }
+
+        return JarVerifier.getUnsignedCS(url);
+    }
+
+    void setEagerValidation(boolean eager) {
+        try {
+            maybeInstantiateVerifier();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        if (jv != null) {
+            jv.setEagerValidation(eager);
+        }
+    }
+
+    List<Object> getManifestDigests() {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.getManifestDigests();
+        }
+        return new ArrayList<Object>();
+    }
+    */
 }
diff --git a/ojluni/src/main/java/java/util/jar/JarVerifier.java b/ojluni/src/main/java/java/util/jar/JarVerifier.java
index 4b243de..e0e7d55 100644
--- a/ojluni/src/main/java/java/util/jar/JarVerifier.java
+++ b/ojluni/src/main/java/java/util/jar/JarVerifier.java
@@ -333,6 +333,7 @@
         }
     }
 
+    // Android-changed: @deprecated tag needs a description. http://b/110781661
     /**
      * Return an array of java.security.cert.Certificate objects for
      * the given file in the jar.
@@ -447,11 +448,14 @@
                        InputStream is,
                        JarVerifier jv) throws IOException
         {
-            // Android-changed: Added to make sure inputs are not null. This allows to
-            // use is == null to detect closed verifier streams.
+            // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
+            // To know that null signals that the stream has been closed, we disallow
+            // it in the constructor. There's no need for anyone to pass null into this
+            // constructor, anyway.
             if (is == null) {
                 throw new NullPointerException("is == null");
             }
+            // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             this.is = is;
             this.jv = jv;
             this.mev = new ManifestEntryVerifier(man);
@@ -463,11 +467,11 @@
 
         public int read() throws IOException
         {
-            // Android-added.
+            // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             if (is == null) {
                 throw new IOException("stream closed");
             }
-
+            // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             if (numLeft > 0) {
                 int b = is.read();
                 jv.update(b, mev);
@@ -481,11 +485,11 @@
         }
 
         public int read(byte b[], int off, int len) throws IOException {
-            // Android-added.
+            // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             if (is == null) {
                 throw new IOException("stream closed");
             }
-
+            // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             if ((numLeft > 0) && (numLeft < len)) {
                 len = (int)numLeft;
             }
@@ -513,11 +517,11 @@
         }
 
         public int available() throws IOException {
-            // Android-added.
+            // BEGIN Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             if (is == null) {
                 throw new IOException("stream closed");
             }
-
+            // END Android-added: Throw IOE, not NPE, if stream is closed. http://b/110695212
             return is.available();
         }
 
diff --git a/ojluni/src/main/java/java/util/logging/FileHandler.java b/ojluni/src/main/java/java/util/logging/FileHandler.java
index 9cae655..24a7c75 100644
--- a/ojluni/src/main/java/java/util/logging/FileHandler.java
+++ b/ojluni/src/main/java/java/util/logging/FileHandler.java
@@ -598,13 +598,14 @@
                     continue;
                 } else if (ch2 == 'h') {
                     file = new File(System.getProperty("user.home"));
-                    // Android-changed: Don't make a special exemption for setuid programs.
-                    //
-                    // if (isSetUID()) {
-                    //     // Ok, we are in a set UID program.  For safety's sake
-                    //     // we disallow attempts to open files relative to %h.
-                    //     throw new IOException("can't use %h in set UID program");
-                    // }
+                    // Android-removed: Don't prohibit using user.home property in setuid programs.
+                    /*
+                    if (isSetUID()) {
+                        // Ok, we are in a set UID program.  For safety's sake
+                        // we disallow attempts to open files relative to %h.
+                        throw new IOException("can't use %h in set UID program");
+                    }
+                    */
                     ix++;
                     word = "";
                     continue;
@@ -735,9 +736,11 @@
         }
     }
 
-    // Android-changed: Not required.
+    // Android-removed: isSetUID's only caller is removed.
+    /*
     /**
      * check if we are in a set UID program.
-     */
-    // private static native boolean isSetUID();
+     *
+    private static native boolean isSetUID();
+    */
 }
diff --git a/ojluni/src/main/java/java/util/logging/Level.java b/ojluni/src/main/java/java/util/logging/Level.java
index c03b171..17b585b 100644
--- a/ojluni/src/main/java/java/util/logging/Level.java
+++ b/ojluni/src/main/java/java/util/logging/Level.java
@@ -262,8 +262,9 @@
     }
 
     private String computeLocalizedLevelName(Locale newLocale) {
-        // Android-changed: Use Thread.currentThread().getContextClassLoader(),
-        // otherwise we might get a BootClassLoader.
+        // Android-changed: Use Thread.currentThread().getContextClassLoader().
+        // Otherwise, we might get a BootClassLoader.
+        // ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale);
         ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale,
                                                      Thread.currentThread().getContextClassLoader());
         final String localizedName = rb.getString(name);
diff --git a/ojluni/src/main/java/java/util/logging/LogManager.java b/ojluni/src/main/java/java/util/logging/LogManager.java
index 7a08510..0d51b0f 100644
--- a/ojluni/src/main/java/java/util/logging/LogManager.java
+++ b/ojluni/src/main/java/java/util/logging/LogManager.java
@@ -185,6 +185,7 @@
                 try {
                     cname = System.getProperty("java.util.logging.manager");
                     if (cname != null) {
+                        // Android-changed: Extract logic into the getClassInstance() helper.
                         mgr = (LogManager) getClassInstance(cname).newInstance();
                     }
                 } catch (Exception ex) {
@@ -198,7 +199,7 @@
 
             }
         });
-     }
+    }
 
 
     // This private class is used as a shutdown hook.
@@ -487,7 +488,7 @@
     // Returns the LoggerContext for the user code (i.e. application or AppContext).
     // Loggers are isolated from each AppContext.
     private LoggerContext getUserContext() {
-        // Android-changed: No AWT specific hooks.
+        // Android-changed: Remove AWT specific hooks.
         return userContext;
     }
 
@@ -582,20 +583,13 @@
         return sysLogger;
     }
 
-    private static Class getClassInstance(String cname) {
-        Class clz = null;
-        if (cname != null) {
-            try {
-                clz = ClassLoader.getSystemClassLoader().loadClass(cname);
-            } catch (ClassNotFoundException ex) {
-                try {
-                    clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
-                } catch (ClassNotFoundException innerEx) {
-                    clz = null;
-                }
-            }
+    // Android-added: getClassInstance helper method, used in several places in this class.
+    private static Class getClassInstance(String cname) throws ClassNotFoundException {
+        try {
+            return ClassLoader.getSystemClassLoader().loadClass(cname);
+        } catch (ClassNotFoundException ex) {
+            return Thread.currentThread().getContextClassLoader().loadClass(cname);
         }
-        return clz;
     }
 
     // LoggerContext maintains the logger namespace per context.
@@ -641,7 +635,7 @@
         // the context requires default loggers, will be added to the context
         // logger's tree.
         final Logger getGlobalLogger() {
-            // Android-changed: s/deprecated/deprecation
+            // Android-changed: Fix SuppressWarnings from "deprecated" to "deprecation".
             @SuppressWarnings("deprecation") // avoids initialization cycles.
             final Logger global = Logger.global;
             return global;
@@ -743,19 +737,9 @@
             return addLocalLogger(logger, requiresDefaultLoggers());
         }
 
-        boolean addLocalLogger(Logger logger, LogManager manager) {
-            // no need to add default loggers if it's not required
-            return addLocalLogger(logger, requiresDefaultLoggers(), manager);
-        }
-
-        boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded) {
-            return addLocalLogger(logger, addDefaultLoggersIfNeeded, manager);
-        }
-
         // Add a logger to this context.  This method will only set its level
         // and process parent loggers.  It doesn't set its handlers.
-        synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded,
-                                            LogManager manager) {
+        synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded) {
             // addDefaultLoggersIfNeeded serves to break recursion when adding
             // default loggers. If we're adding one of the default loggers
             // (we're being called from ensureDefaultLogger()) then
@@ -957,7 +941,8 @@
                 for (int i = 0; i < names.length; i++) {
                     String word = names[i];
                     try {
-                        // Android-changed:
+                        // Android-changed: Fall back from the system to the context classloader.
+                        // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
                         Class<?> clz = getClassInstance(word);
                         Handler hdl = (Handler) clz.newInstance();
                         // Check if there is a property defining the
@@ -1155,7 +1140,7 @@
         }
         drainLoggerRefQueueBounded();
         LoggerContext cx = getUserContext();
-        if (cx.addLocalLogger(logger, this)) {
+        if (cx.addLocalLogger(logger)) {
             // Do we have a per logger handler too?
             // Note: this will add a 200ms penalty
             loadLoggerHandlers(logger, name, name + ".handlers");
@@ -1268,6 +1253,7 @@
                 // Instantiate the named class.  It is its constructor's
                 // responsibility to initialize the logging configuration, by
                 // calling readConfiguration(InputStream) with a suitable stream.
+                // Android-changed: Extract logic into the getClassInstance() helper.
                 getClassInstance(cname).newInstance();
                 return;
             } catch (Exception ex) {
@@ -1288,8 +1274,14 @@
             fname = f.getCanonicalPath();
         }
 
-        // Android-changed: Look in the boot class-path jar files for the logging.properties.
-        // It will not be present in the file system.
+        // BEGIN Android-changed: Look in the boot class-path jar files for the logging.properties.
+        // It may not be present in the file system.
+        /*
+        try (final InputStream in = new FileInputStream(fname)) {
+            final BufferedInputStream bin = new BufferedInputStream(in);
+            readConfiguration(bin);
+        }
+        */
         InputStream in;
         try {
             in = new FileInputStream(fname);
@@ -1308,6 +1300,7 @@
                 in.close();
             }
         }
+        // END Android-changed: Look in the boot class-path jar files for the logging.properties.
     }
 
     /**
@@ -1419,6 +1412,9 @@
         for (int i = 0; i < names.length; i++) {
             String word = names[i];
             try {
+                // Android-changed: Fall back from the system to the context classloader.
+                // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
+                // clz.newInstance();
                 getClassInstance(word).newInstance();
             } catch (Exception ex) {
                 System.err.println("Can't load config class \"" + word + "\"");
@@ -1531,6 +1527,9 @@
         String val = getProperty(name);
         try {
             if (val != null) {
+                // Android-changed: Fall back from the system to the context classloader.
+                // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
+                // return (Filter) clz.newInstance();
                 return (Filter) getClassInstance(val).newInstance();
             }
         } catch (Exception ex) {
@@ -1551,6 +1550,9 @@
         String val = getProperty(name);
         try {
             if (val != null) {
+                // Android-changed: Fall back from the system to the context classloader.
+                // Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
+                // return (Formatter) clz.newInstance();
                 return (Formatter) getClassInstance(val).newInstance();
             }
         } catch (Exception ex) {
@@ -1702,6 +1704,7 @@
 
     // Management Support
     private static LoggingMXBean loggingMXBean = null;
+    // Android-removed: References to java.lang.management in javadoc.
     /**
      * String representation of the {@code ObjectName} for the management interface
      * for the logging facility.
@@ -1710,12 +1713,10 @@
      *
      * @since 1.5
      */
-    // Android-changed: Remove reference to java.lang.management.ObjectName.
-    //
-    //@see java.lang.management.PlatformLoggingMXBean
     public final static String LOGGING_MXBEAN_NAME
         = "java.util.logging:type=Logging";
 
+    // Android-removed: References to java.lang.management in javadoc.
     /**
      * Returns <tt>LoggingMXBean</tt> for managing loggers.
      *
@@ -1723,17 +1724,6 @@
      *
      * @since 1.5
      */
-    // Android-removed docs areferring to java.lang.management.
-    //
-    // An alternative way to manage loggers is through the
-    // {@link java.lang.management.PlatformLoggingMXBean} interface
-    // that can be obtained by calling:
-    // <pre>
-    //     PlatformLoggingMXBean logging = {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class)
-    //        ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class);
-    // </pre>
-    //
-    // @see java.lang.management.PlatformLoggingMXBean
     public static synchronized LoggingMXBean getLoggingMXBean() {
         if (loggingMXBean == null) {
             loggingMXBean =  new Logging();
diff --git a/ojluni/src/main/java/java/util/logging/LogRecord.java b/ojluni/src/main/java/java/util/logging/LogRecord.java
index e5ead8b..3b0e518 100644
--- a/ojluni/src/main/java/java/util/logging/LogRecord.java
+++ b/ojluni/src/main/java/java/util/logging/LogRecord.java
@@ -528,6 +528,12 @@
                                 ClassLoader.getSystemClassLoader());
                 resourceBundle = bundle;
             } catch (MissingResourceException ex) {
+                // Android-changed: Fall back to context classloader before giving up.
+                /*
+                // This is not a good place to throw an exception,
+                // so we simply leave the resourceBundle null.
+                resourceBundle = null;
+                */
                 try {
                     resourceBundle = ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(),
                             Thread.currentThread().getContextClassLoader());
@@ -545,16 +551,24 @@
     // Private method to infer the caller's class and method names
     private void inferCaller() {
         needToInferCaller = false;
-        // Android-changed: Use VMStack.getThreadStackTrace.
+        // BEGIN Android-changed: Use VMStack.getThreadStackTrace.
+        /*
+        JavaLangAccess access = SharedSecrets.getJavaLangAccess();
+        Throwable throwable = new Throwable();
+        int depth = access.getStackTraceDepth(throwable);
+        */
         StackTraceElement[] stack = VMStack.getThreadStackTrace(Thread.currentThread());
         int depth = stack.length;
+        // END Android-changed: Use VMStack.getThreadStackTrace.
 
         boolean lookingForLogger = true;
         for (int ix = 0; ix < depth; ix++) {
             // Calling getStackTraceElement directly prevents the VM
             // from paying the cost of building the entire stack frame.
             //
-            // Android-changed: Use value from getThreadStackTrace.
+            // Android-changed: Use value from previous getThreadStackTrace call.
+            // StackTraceElement frame =
+            //     access.getStackTraceElement(throwable, ix);
             StackTraceElement frame = stack[ix];
             String cname = frame.getClassName();
             boolean isLoggerImpl = isLoggerImplFrame(cname);
diff --git a/ojluni/src/main/java/java/util/logging/Logger.java b/ojluni/src/main/java/java/util/logging/Logger.java
index 8cf98fe..61bbe4e 100644
--- a/ojluni/src/main/java/java/util/logging/Logger.java
+++ b/ojluni/src/main/java/java/util/logging/Logger.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
  * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -27,7 +26,6 @@
 
 package java.util.logging;
 
-import dalvik.system.VMStack;
 import java.lang.ref.WeakReference;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -39,6 +37,7 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Supplier;
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
 /**
  * A Logger object is used to log messages for a specific
@@ -441,7 +440,7 @@
                     return System.getProperty(key);
                 }
             });
-            return Boolean.parseBoolean(s);
+            return Boolean.valueOf(s);
         }
     }
 
@@ -500,9 +499,7 @@
         // would throw an IllegalArgumentException in the second call
         // because the wrapper would result in an attempt to replace
         // the existing "resourceBundleForFoo" with null.
-        //
-        // Android-changed: Use VMStack.getStackClass1.
-        return demandLogger(name, null, VMStack.getStackClass1());
+        return demandLogger(name, null, Reflection.getCallerClass());
     }
 
     /**
@@ -552,8 +549,7 @@
     // adding a new Logger object is handled by LogManager.addLogger().
     @CallerSensitive
     public static Logger getLogger(String name, String resourceBundleName) {
-        // Android-changed: Use VMStack.getStackClass1.
-        Class<?> callerClass = VMStack.getStackClass1();
+        Class<?> callerClass = Reflection.getCallerClass();
         Logger result = demandLogger(name, resourceBundleName, callerClass);
 
         // MissingResourceException or IllegalArgumentException can be
@@ -641,9 +637,8 @@
         LogManager manager = LogManager.getLogManager();
         // cleanup some Loggers that have been GC'ed
         manager.drainLoggerRefQueueBounded();
-        // Android-changed: Use VMStack.getStackClass1.
         Logger result = new Logger(null, resourceBundleName,
-                                   VMStack.getStackClass1(), manager, false);
+                                   Reflection.getCallerClass(), manager, false);
         result.anonymous = true;
         Logger root = manager.getLogger("");
         result.doSetParent(root);
@@ -1894,6 +1889,7 @@
         if (useCallersClassLoader) {
             // Try with the caller's ClassLoader
             ClassLoader callersClassLoader = getCallersClassLoader();
+
             if (callersClassLoader == null || callersClassLoader == cl) {
                 return null;
             }
diff --git a/ojluni/src/main/java/java/util/logging/LoggingMXBean.java b/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
index 0c67cc5..14777c0 100644
--- a/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
+++ b/ojluni/src/main/java/java/util/logging/LoggingMXBean.java
@@ -26,6 +26,7 @@
 
 package java.util.logging;
 
+// Android-removed: References to java.lang.management in javadoc.
 
 /**
  * The management interface for the logging facility.
@@ -44,28 +45,6 @@
  * @since   1.5
  *
  */
-
-// Android-removed: References to java.lang.management.
-//
-// It is recommended
-// to use the {@link java.lang.management.PlatformLoggingMXBean} management
-// interface that implements all attributes defined in this
-// {@code LoggingMXBean}.  The
-// {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class)
-// ManagementFactory.getPlatformMXBean} method can be used to obtain
-// the {@code PlatformLoggingMXBean} object representing the management
-// interface for logging.
-//
-// This instance is an {@link javax.management.MXBean MXBean} that
-// can be obtained by calling the {@link LogManager#getLoggingMXBean}
-// method or from the
-// {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
-// platform <tt>MBeanServer</tt>}.
-//
-// The instance registered in the platform {@code MBeanServer}
-// is also a {@link java.lang.management.PlatformLoggingMXBean}.
-//
-// @see java.lang.management.PlatformLoggingMXBean
 public interface LoggingMXBean {
 
     /**
diff --git a/ojluni/src/main/java/java/util/logging/MemoryHandler.java b/ojluni/src/main/java/java/util/logging/MemoryHandler.java
index 94153dc..704c155 100644
--- a/ojluni/src/main/java/java/util/logging/MemoryHandler.java
+++ b/ojluni/src/main/java/java/util/logging/MemoryHandler.java
@@ -129,12 +129,13 @@
                     + " does not specify a target");
         }
         Class<?> clz;
-
         try {
             clz = ClassLoader.getSystemClassLoader().loadClass(targetName);
             target = (Handler) clz.newInstance();
-        } catch (Exception ex) {
-            // Android-changed: Try to load the class from the context class loader.
+        // Android-changed: Fall back to the context classloader before giving up.
+        // } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+        //     throw new RuntimeException("MemoryHandler can't load handler target \"" + targetName + "\"" , e);
+        } catch (Exception e) {
             try {
                 clz = Thread.currentThread().getContextClassLoader()
                         .loadClass(targetName);
diff --git a/ojluni/src/main/java/java/util/logging/SimpleFormatter.java b/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
index 6433365..12412f1 100644
--- a/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
+++ b/ojluni/src/main/java/java/util/logging/SimpleFormatter.java
@@ -1,4 +1,4 @@
-/*g
+/*
  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
diff --git a/ojluni/src/main/java/java/util/logging/SocketHandler.java b/ojluni/src/main/java/java/util/logging/SocketHandler.java
index e571d68..2561e90 100644
--- a/ojluni/src/main/java/java/util/logging/SocketHandler.java
+++ b/ojluni/src/main/java/java/util/logging/SocketHandler.java
@@ -165,6 +165,7 @@
             throw new IllegalArgumentException("Null host name: " + host);
         }
 
+        // Android-added: Enforce cleartext policy.
         if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()) {
             throw new IOException("Cleartext traffic not permitted");
         }
diff --git a/ojluni/src/main/java/java/util/logging/XMLFormatter.java b/ojluni/src/main/java/java/util/logging/XMLFormatter.java
index f3bb335..ab95f58 100644
--- a/ojluni/src/main/java/java/util/logging/XMLFormatter.java
+++ b/ojluni/src/main/java/java/util/logging/XMLFormatter.java
@@ -152,6 +152,7 @@
             escape(sb, message);
             sb.append("</message>");
             sb.append("\n");
+        // Android-added: Include empty <message/> tag. http://b/25861348#comment17
         } else {
             sb.append("<message/>");
             sb.append("\n");
diff --git a/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java b/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
index e2e25f7..71616ee 100644
--- a/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
+++ b/ojluni/src/main/java/java/util/prefs/AbstractPreferences.java
@@ -167,11 +167,18 @@
     /**
      * Registered preference change listeners.
      */
+    // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+    // It's not clear if this change provides overall benefit; it might be
+    // reverted in future. Discussion: http://b/111195881
+    // private PreferenceChangeListener[] prefListeners =
+    //     new PreferenceChangeListener[0];
     private final ArrayList<PreferenceChangeListener> prefListeners = new ArrayList<>();
 
     /**
      * Registered node change listeners.
      */
+    // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+    // private NodeChangeListener[] nodeListeners = new NodeChangeListener[0];
     private final ArrayList<NodeChangeListener> nodeListeners = new ArrayList<>();
 
     /**
@@ -1036,6 +1043,14 @@
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
 
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            /*
+            // Copy-on-write
+            PreferenceChangeListener[] old = prefListeners;
+            prefListeners = new PreferenceChangeListener[old.length + 1];
+            System.arraycopy(old, 0, prefListeners, 0, old.length);
+            prefListeners[old.length] = pcl;
+            */
             prefListeners.add(pcl);
         }
         startEventDispatchThreadIfNecessary();
@@ -1045,11 +1060,27 @@
         synchronized(lock) {
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
-
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            // if ((prefListeners == null) || (prefListeners.length == 0))
             if (!prefListeners.contains(pcl)) {
                 throw new IllegalArgumentException("Listener not registered.");
             }
 
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            /*
+            // Copy-on-write
+            PreferenceChangeListener[] newPl =
+                new PreferenceChangeListener[prefListeners.length - 1];
+            int i = 0;
+            while (i < newPl.length && prefListeners[i] != pcl)
+                newPl[i] = prefListeners[i++];
+
+            if (i == newPl.length &&  prefListeners[i] != pcl)
+                throw new IllegalArgumentException("Listener not registered.");
+            while (i < newPl.length)
+                newPl[i] = prefListeners[++i];
+            prefListeners = newPl;
+            */
             prefListeners.remove(pcl);
         }
     }
@@ -1061,6 +1092,19 @@
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
 
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            /*
+            // Copy-on-write
+            if (nodeListeners == null) {
+                nodeListeners = new NodeChangeListener[1];
+                nodeListeners[0] = ncl;
+            } else {
+                NodeChangeListener[] old = nodeListeners;
+                nodeListeners = new NodeChangeListener[old.length + 1];
+                System.arraycopy(old, 0, nodeListeners, 0, old.length);
+                nodeListeners[old.length] = ncl;
+            }
+            */
             nodeListeners.add(ncl);
         }
         startEventDispatchThreadIfNecessary();
@@ -1070,11 +1114,29 @@
         synchronized(lock) {
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
-
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            // if ((nodeListeners == null) || (nodeListeners.length == 0))
             if (!nodeListeners.contains(ncl)) {
                 throw new IllegalArgumentException("Listener not registered.");
             }
 
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            /*
+            // Copy-on-write
+            int i = 0;
+            while (i < nodeListeners.length && nodeListeners[i] != ncl)
+                i++;
+            if (i == nodeListeners.length)
+                throw new IllegalArgumentException("Listener not registered.");
+            NodeChangeListener[] newNl =
+                new NodeChangeListener[nodeListeners.length - 1];
+            if (i != 0)
+                System.arraycopy(nodeListeners, 0, newNl, 0, i);
+            if (i != newNl.length)
+                System.arraycopy(nodeListeners, i + 1,
+                                 newNl, i, newNl.length - i);
+            nodeListeners = newNl;
+            */
             nodeListeners.remove(ncl);
         }
     }
@@ -1493,19 +1555,34 @@
         }
     }
 
+    // BEGIN Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+    // Changed documentation.
+    /*
+    /**
+     * Return this node's preference/node change listeners.  Even though
+     * we're using a copy-on-write lists, we use synchronized accessors to
+     * ensure information transmission from the writing thread to the
+     * reading thread.
+     *
+    */
     /**
      * Return this node's preference/node change listeners. All accesses to prefListeners
      * and nodeListeners are guarded by |lock|. We return a copy of the list so that the
      * EventQueue thread will iterate over a fixed snapshot of the listeners at the time of
      * this call.
      */
+    // END Android-changed: Copy-on-read List of listeners, not copy-on-write array.
     PreferenceChangeListener[] prefListeners() {
         synchronized(lock) {
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            // return prefListeners;
             return prefListeners.toArray(new PreferenceChangeListener[prefListeners.size()]);
         }
     }
     NodeChangeListener[] nodeListeners() {
         synchronized(lock) {
+            // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+            // return nodeListeners;
             return nodeListeners.toArray(new NodeChangeListener[nodeListeners.size()]);
         }
     }
@@ -1516,6 +1593,8 @@
      * listeners.  Invoked with this.lock held.
      */
     private void enqueuePreferenceChangeEvent(String key, String newValue) {
+        // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+        // if (prefListeners.length != 0) {
         if (!prefListeners.isEmpty()) {
             synchronized(eventQueue) {
                 eventQueue.add(new PreferenceChangeEvent(this, key, newValue));
@@ -1530,6 +1609,8 @@
      * this.lock held.
      */
     private void enqueueNodeAddedEvent(Preferences child) {
+        // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+        // if (nodeListeners.length != 0) {
         if (!nodeListeners.isEmpty()) {
             synchronized(eventQueue) {
                 eventQueue.add(new NodeAddedEvent(this, child));
@@ -1544,6 +1625,8 @@
      * this.lock held.
      */
     private void enqueueNodeRemovedEvent(Preferences child) {
+        // Android-changed: Copy-on-read List of listeners, not copy-on-write array.
+        // if (nodeListeners.length != 0) {
         if (!nodeListeners.isEmpty()) {
             synchronized(eventQueue) {
                 eventQueue.add(new NodeRemovedEvent(this, child));
diff --git a/ojluni/src/main/java/java/util/prefs/Preferences.java b/ojluni/src/main/java/java/util/prefs/Preferences.java
index aaf9950..2410c1d 100644
--- a/ojluni/src/main/java/java/util/prefs/Preferences.java
+++ b/ojluni/src/main/java/java/util/prefs/Preferences.java
@@ -224,11 +224,97 @@
  */
 public abstract class Preferences {
 
-    // Android-changed: Not final for testing.
-    private static PreferencesFactory factory = findPreferencesFactory();
+    // Android-changed: Allow Preferences.factory to be set by tests.
+    // private static final PreferencesFactory factory = factory();
+    private static PreferencesFactory factory = factory();
 
-    // Android-changed: Custom implementation of findPreferencesFactory.
-    private static PreferencesFactory findPreferencesFactory() {
+    // BEGIN Android-changed: Logic for constructing the default Preferences factory.
+    /*
+    private static PreferencesFactory factory() {
+        // 1. Try user-specified system property
+        String factoryName = AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(
+                        "java.util.prefs.PreferencesFactory");}});
+        if (factoryName != null) {
+            // FIXME: This code should be run in a doPrivileged and
+            // not use the context classloader, to avoid being
+            // dependent on the invoking thread.
+            // Checking AllPermission also seems wrong.
+            try {
+                return (PreferencesFactory)
+                    Class.forName(factoryName, false,
+                                  ClassLoader.getSystemClassLoader())
+                    .newInstance();
+            } catch (Exception ex) {
+                try {
+                    // workaround for javaws, plugin,
+                    // load factory class using non-system classloader
+                    SecurityManager sm = System.getSecurityManager();
+                    if (sm != null) {
+                        sm.checkPermission(new java.security.AllPermission());
+                    }
+                    return (PreferencesFactory)
+                        Class.forName(factoryName, false,
+                                      Thread.currentThread()
+                                      .getContextClassLoader())
+                        .newInstance();
+                } catch (Exception e) {
+                    throw new InternalError(
+                        "Can't instantiate Preferences factory "
+                        + factoryName, e);
+                }
+            }
+        }
+
+        return AccessController.doPrivileged(
+            new PrivilegedAction<PreferencesFactory>() {
+                public PreferencesFactory run() {
+                    return factory1();}});
+    }
+
+    private static PreferencesFactory factory1() {
+        // 2. Try service provider interface
+        Iterator<PreferencesFactory> itr = ServiceLoader
+            .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader())
+            .iterator();
+
+        // choose first provider instance
+        while (itr.hasNext()) {
+            try {
+                return itr.next();
+            } catch (ServiceConfigurationError sce) {
+                if (sce.getCause() instanceof SecurityException) {
+                    // Ignore the security exception, try the next provider
+                    continue;
+                }
+                throw sce;
+            }
+        }
+
+        // 3. Use platform-specific system-wide default
+        String osName = System.getProperty("os.name");
+        String platformFactory;
+        if (osName.startsWith("Windows")) {
+            platformFactory = "java.util.prefs.WindowsPreferencesFactory";
+        } else if (osName.contains("OS X")) {
+            platformFactory = "java.util.prefs.MacOSXPreferencesFactory";
+        } else {
+            platformFactory = "java.util.prefs.FileSystemPreferencesFactory";
+        }
+        try {
+            return (PreferencesFactory)
+                Class.forName(platformFactory, false,
+                              Preferences.class.getClassLoader()).newInstance();
+        } catch (Exception e) {
+            throw new InternalError(
+                "Can't instantiate platform default Preferences factory "
+                + platformFactory, e);
+        }
+    }
+    */
+    private static PreferencesFactory factory() {
         // Try the system property first...
         PreferencesFactory result = ServiceLoader.loadFromSystemProperty(PreferencesFactory.class);
         if (result != null) {
@@ -241,16 +327,16 @@
         // Finally return a default...
         return new FileSystemPreferencesFactory();
     }
+    // END Android-changed: Android-changed: Logic for constructing the default Preferences factory.
 
-    /**
-     * @hide for testing only.
-     */
-    // Android-changed: Allow this to be set for testing.
+    // BEGIN Android-added: Allow Preferences.factory to be set by tests.
+    /** @hide for testing only. */
     public static PreferencesFactory setPreferencesFactory(PreferencesFactory pf) {
         PreferencesFactory previous = factory;
         factory = pf;
         return previous;
     }
+    // END Android-added: Allow Preferences.factory to be set by tests.
 
     /**
      * Maximum length of string allowed as a key (80 characters).
@@ -267,6 +353,7 @@
      */
     public static final int MAX_NAME_LENGTH = 80;
 
+    // Android-added: Document Android's security restrictions on system/user preferences.
     /**
      * <strong>WARNING:</strong> On Android, the Preference nodes
      * corresponding to the "system" and "user" preferences are stored in sections
@@ -316,6 +403,7 @@
         return userRoot().node(nodeName(c));
     }
 
+    // Android-added: Document Android's security restrictions on system/user preferences.
     /**
      * <strong>WARNING:</strong> On Android, the Preference nodes
      * corresponding to the "system" and "user" preferences are stored in sections
@@ -391,6 +479,7 @@
      */
     private static Permission prefsPerm = new RuntimePermission("preferences");
 
+    // Android-added: Document Android's security restrictions on system/user preferences.
     /**
      * <strong>WARNING:</strong> On Android, the Preference nodes
      * corresponding to the "system" and "user" preferences are stored in sections
@@ -412,6 +501,7 @@
         return factory.userRoot();
     }
 
+    // Android-added: Document Android's security restrictions on system/user preferences.
     /**
      * <strong>WARNING:</strong> On Android, the Preference nodes
      * corresponding to the "system" and "user" preferences are stored in sections
diff --git a/ojluni/src/main/java/java/util/prefs/XmlSupport.java b/ojluni/src/main/java/java/util/prefs/XmlSupport.java
index d15cb90..a90ff19 100644
--- a/ojluni/src/main/java/java/util/prefs/XmlSupport.java
+++ b/ojluni/src/main/java/java/util/prefs/XmlSupport.java
@@ -207,17 +207,21 @@
                 " versions " + EXTERNAL_XML_VERSION + " or older. You may need" +
                 " to install a newer version of JDK.");
 
+            // BEGIN Android-changed: Filter out non-Element nodes.
+            // Use a selector to skip over CDATA / DATA elements.
+            // The selector is specific to children with tag name "root";
+            // export() always creates exactly one such child.
+            // Element xmlRoot = (Element) doc.getDocumentElement().
+            //                                    getChildNodes().item(0);
             Element xmlRoot = (Element) doc.getDocumentElement();
 
-            // Android-changed: Use a selector to skip over CDATA / DATA elements.
             NodeList elements = xmlRoot.getElementsByTagName("root");
             if (elements == null || elements.getLength() != 1) {
                 throw new InvalidPreferencesFormatException("invalid root node");
             }
 
             xmlRoot = (Element) elements.item(0);
-            // End android changes.
-
+            // END Android-changed: Filter out non-Element nodes.
             Preferences prefsRoot =
                 (xmlRoot.getAttribute("type").equals("user") ?
                             Preferences.userRoot() : Preferences.systemRoot());
@@ -281,38 +285,55 @@
             Transformer t = tf.newTransformer();
             t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
             t.setOutputProperty(OutputKeys.INDENT, "yes");
-
             //Transformer resets the "indent" info if the "result" is a StreamResult with
             //an OutputStream object embedded, creating a Writer object on top of that
             //OutputStream object however works.
             t.transform(new DOMSource(doc),
-                    new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8"))));
+                        new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8"))));
         } catch(TransformerException e) {
             throw new AssertionError(e);
         }
     }
 
-    private static List<Element> getChildElements(Element node) {
-        NodeList xmlKids = node.getChildNodes();
-        ArrayList<Element> elements = new ArrayList<>(xmlKids.getLength());
-        for (int i = 0; i < xmlKids.getLength(); ++i) {
-            if (xmlKids.item(i) instanceof Element) {
-                elements.add((Element) xmlKids.item(i));
-            }
+    // BEGIN Android-added: Filter out non-Element nodes.
+    static class NodeListAdapter implements NodeList {
+        private final List<? extends Node> delegate;
+
+        public NodeListAdapter(List<? extends Node> delegate) {
+            this.delegate = Objects.requireNonNull(delegate);
         }
 
-        return elements;
+        @Override public Node item(int index) {
+            if (index < 0 || index >= delegate.size()) {
+                return null;
+            }
+            return delegate.get(index);
+        }
+        @Override public int getLength() { return delegate.size(); }
     }
 
+    private static NodeList elementNodesOf(NodeList xmlKids) {
+        List<Element> elements = new ArrayList<>(xmlKids.getLength());
+        for (int i = 0; i < xmlKids.getLength(); ++i) {
+            Node node = xmlKids.item(i);
+            if (node instanceof Element) {
+                elements.add((Element) node);
+            }
+        }
+        return new NodeListAdapter(elements);
+    }
+    // END Android-added: Filter out non-Element nodes.
+
     /**
      * Recursively traverse the specified preferences node and store
      * the described preferences into the system or current user
      * preferences tree, as appropriate.
      */
     private static void ImportSubtree(Preferences prefsNode, Element xmlNode) {
-        // Android-changed: filter out non-element nodes.
-        List<Element> xmlKids = getChildElements(xmlNode);
-
+        NodeList xmlKids = xmlNode.getChildNodes();
+        // Android-added: Filter out non-Element nodes.
+        xmlKids = elementNodesOf(xmlKids);
+        int numXmlKids = xmlKids.getLength();
         /*
          * We first lock the node, import its contents and get
          * child nodes. Then we unlock the node and go to children
@@ -327,20 +348,19 @@
                 return;
 
             // Import any preferences at this node
-            // Android
-            Element firstXmlKid = xmlKids.get(0);
+            Element firstXmlKid = (Element) xmlKids.item(0);
             ImportPrefs(prefsNode, firstXmlKid);
-            prefsKids = new Preferences[xmlKids.size() - 1];
+            prefsKids = new Preferences[numXmlKids - 1];
 
             // Get involved children
-            for (int i=1; i < xmlKids.size(); i++) {
-                Element xmlKid = xmlKids.get(i);
+            for (int i=1; i < numXmlKids; i++) {
+                Element xmlKid = (Element) xmlKids.item(i);
                 prefsKids[i-1] = prefsNode.node(xmlKid.getAttribute("name"));
             }
         } // unlocked the node
         // import children
-        for (int i=1; i < xmlKids.size(); i++)
-            ImportSubtree(prefsKids[i-1], xmlKids.get(i));
+        for (int i=1; i < numXmlKids; i++)
+            ImportSubtree(prefsKids[i-1], (Element)xmlKids.item(i));
     }
 
     /**
@@ -349,11 +369,13 @@
      * preferences node.
      */
     private static void ImportPrefs(Preferences prefsNode, Element map) {
-        // Android-changed: Use getChildElements.
-        List<Element> entries = getChildElements(map);
-        for (int i=0, numEntries = entries.size(); i < numEntries; i++) {
-            Element entry = entries.get(i);
-            prefsNode.put(entry.getAttribute("key"), entry.getAttribute("value"));
+        NodeList entries = map.getChildNodes();
+        // Android-added: Filter out non-Element nodes.
+        entries = elementNodesOf(entries);
+        for (int i=0, numEntries = entries.getLength(); i < numEntries; i++) {
+            Element entry = (Element) entries.item(i);
+            prefsNode.put(entry.getAttribute("key"),
+                          entry.getAttribute("value"));
         }
     }
 
@@ -411,12 +433,14 @@
 
             NodeList entries = xmlMap.getChildNodes();
             for (int i=0, numEntries=entries.getLength(); i<numEntries; i++) {
-                // Android-added, android xml serializer generates one-char Text nodes with a single
-                // new-line character between expected Element nodes. openJdk code wasn't
-                // expecting anything else than Element node.
+                // BEGIN Android-added: Filter out non-Element nodes.
+                // Android xml serializer generates one-char Text nodes with a single
+                // new-line character between expected Element nodes. OpenJDK code wasn't
+                // expecting anything else than Element nodes.
                 if (!(entries.item(i) instanceof Element)) {
                     continue;
                 }
+                // END Android-added: Filter out non-Element nodes.
                 Element entry = (Element) entries.item(i);
                 m.put(entry.getAttribute("key"), entry.getAttribute("value"));
             }
diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java
index a665011..e92cb9d 100644
--- a/ojluni/src/main/java/java/util/regex/Matcher.java
+++ b/ojluni/src/main/java/java/util/regex/Matcher.java
@@ -30,8 +30,8 @@
 import libcore.util.NativeAllocationRegistry;
 
 /**
- * An engine that performs match operations on a {@link java.lang.CharSequence
- * </code>character sequence<code>} by interpreting a {@link Pattern}.
+ * An engine that performs match operations on a {@linkplain java.lang.CharSequence
+ * character sequence} by interpreting a {@link Pattern}.
  *
  * <p> A matcher is created from a pattern by invoking the pattern's {@link
  * Pattern#matcher matcher} method.  Once created, a matcher can be used to
@@ -105,6 +105,7 @@
  */
 
 public final class Matcher implements MatchResult {
+
     /**
      * The Pattern object that created this Matcher.
      */
@@ -112,7 +113,29 @@
     // This ensures that "this" and pattern remain reachable while we're using pattern.address
     // directly.
     @ReachabilitySensitive
-    private Pattern pattern;
+    private Pattern parentPattern;
+
+    /**
+     * Holds the offsets for the most recent match.
+     */
+    int[] groups;
+
+    /**
+     * The range within the sequence that is to be matched (between  0
+     * and text.length()).
+     */
+    int from, to;
+
+    /**
+     * Holds the input text.
+     */
+    String text;
+
+    /**
+     * Reflects whether a match has been found during the most recent find
+     * operation.
+     */
+    private boolean matchFound;
 
     /**
      * The address of the native peer.
@@ -130,54 +153,29 @@
             Matcher.class.getClassLoader(), getNativeFinalizer(), nativeSize());
 
     /**
-     * Holds the original CharSequence for use in {@link #reset}. {@link #input} is used during
+     * The index of the last position appended in a substitution.
+     */
+    int appendPos = 0;
+
+    /**
+     * Holds the original CharSequence for use in {@link #reset}. {@link #text} is used during
      * matching. Note that CharSequence is mutable while String is not, so reset can cause the input
      * to match to change.
      */
     private CharSequence originalInput;
 
     /**
-     * Holds the input text.
+     * If transparentBounds is true then the boundaries of this
+     * matcher's region are transparent to lookahead, lookbehind,
+     * and boundary matching constructs that try to see beyond them.
      */
-    private String input;
+    boolean transparentBounds = false;
 
     /**
-     * Holds the start of the region, or 0 if the matching should start at the
-     * beginning of the text.
+     * If anchoringBounds is true then the boundaries of this
+     * matcher's region match anchors such as ^ and $.
      */
-    private int regionStart;
-
-    /**
-     * Holds the end of the region, or input.length() if the matching should
-     * go until the end of the input.
-     */
-    private int regionEnd;
-
-    /**
-     * Holds the position where the next append operation will take place.
-     */
-    private int appendPos;
-
-    /**
-     * Reflects whether a match has been found during the most recent find
-     * operation.
-     */
-    private boolean matchFound;
-
-    /**
-     * Holds the offsets for the most recent match.
-     */
-    private int[] matchOffsets;
-
-    /**
-     * Reflects whether the bounds of the region are anchoring.
-     */
-    private boolean anchoringBounds = true;
-
-    /**
-     * Reflects whether the bounds of the region are transparent.
-     */
-    private boolean transparentBounds;
+    boolean anchoringBounds = true;
 
     /**
      * All matchers have the state used by Pattern during a match.
@@ -193,7 +191,7 @@
      * @return  The pattern for which this matcher was created
      */
     public Pattern pattern() {
-        return pattern;
+        return parentPattern;
     }
 
     /**
@@ -206,7 +204,7 @@
      */
     public MatchResult toMatchResult() {
         ensureMatch();
-        return new OffsetBasedMatchResult(input, matchOffsets);
+        return new OffsetBasedMatchResult(text, groups);
     }
 
     /**
@@ -226,11 +224,9 @@
       * @since 1.5
       */
     public Matcher usePattern(Pattern newPattern) {
-        if (newPattern == null) {
-            throw new IllegalArgumentException("newPattern == null");
-        }
-
-        this.pattern = newPattern;
+        if (newPattern == null)
+            throw new IllegalArgumentException("Pattern cannot be null");
+        parentPattern = newPattern;
 
         synchronized (this) {
             if (nativeFinalizer != null) {
@@ -238,21 +234,122 @@
                 address = 0; // In case openImpl throws.
                 nativeFinalizer = null;
             }
-            address = openImpl(pattern.address);
+            address = openImpl(parentPattern.address);
             nativeFinalizer = registry.registerNativeAllocation(this, address);
         }
 
-        if (input != null) {
+        if (text != null) {
             resetForInput();
         }
 
-        matchOffsets = new int[(groupCount() + 1) * 2];
+        groups = new int[(groupCount() + 1) * 2];
         matchFound = false;
         return this;
     }
 
     /**
-     * Returns the offset after the last character matched.  </p>
+     * Resets this matcher.
+     *
+     * <p> Resetting a matcher discards all of its explicit state information
+     * and sets its append position to zero. The matcher's region is set to the
+     * default region, which is its entire character sequence. The anchoring
+     * and transparency of this matcher's region boundaries are unaffected.
+     *
+     * @return  This matcher
+     */
+    public Matcher reset() {
+        return reset(originalInput, 0, originalInput.length());
+    }
+
+    /**
+     * Resets this matcher with a new input sequence.
+     *
+     * <p> Resetting a matcher discards all of its explicit state information
+     * and sets its append position to zero.  The matcher's region is set to
+     * the default region, which is its entire character sequence.  The
+     * anchoring and transparency of this matcher's region boundaries are
+     * unaffected.
+     *
+     * @param  input
+     *         The new input character sequence
+     *
+     * @return  This matcher
+     */
+    public Matcher reset(CharSequence input) {
+        return reset(input, 0, input.length());
+    }
+
+    /**
+     * Returns the start index of the previous match.
+     *
+     * @return  The index of the first character matched
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     */
+    public int start() {
+        return start(0);
+    }
+
+    /**
+     * Returns the start index of the subsequence captured by the given group
+     * during the previous match operation.
+     *
+     * <p> <a href="Pattern.html#cg">Capturing groups</a> are indexed from left
+     * to right, starting at one.  Group zero denotes the entire pattern, so
+     * the expression <i>m.</i><tt>start(0)</tt> is equivalent to
+     * <i>m.</i><tt>start()</tt>.  </p>
+     *
+     * @param  group
+     *         The index of a capturing group in this matcher's pattern
+     *
+     * @return  The index of the first character captured by the group,
+     *          or <tt>-1</tt> if the match was successful but the group
+     *          itself did not match anything
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If there is no capturing group in the pattern
+     *          with the given index
+     */
+    public int start(int group) {
+        ensureMatch();
+        if (group < 0 || group > groupCount())
+            throw new IndexOutOfBoundsException("No group " + group);
+        return groups[group * 2];
+    }
+
+    /**
+     * Returns the start index of the subsequence captured by the given
+     * <a href="Pattern.html#groupname">named-capturing group</a> during the
+     * previous match operation.
+     *
+     * @param  name
+     *         The name of a named-capturing group in this matcher's pattern
+     *
+     * @return  The index of the first character captured by the group,
+     *          or {@code -1} if the match was successful but the group
+     *          itself did not match anything
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     *
+     * @throws  IllegalArgumentException
+     *          If there is no capturing group in the pattern
+     *          with the given name
+     * @since 1.8
+     */
+    public int start(String name) {
+        return groups[getMatchedGroupIndex(name) * 2];
+    }
+
+    /**
+     * Returns the offset after the last character matched.
      *
      * @return  The offset after the last character matched
      *
@@ -290,7 +387,9 @@
      */
     public int end(int group) {
         ensureMatch();
-        return matchOffsets[(group * 2) + 1];
+        if (group < 0 || group > groupCount())
+            throw new IndexOutOfBoundsException("No group " + group);
+        return groups[group * 2 + 1];
     }
 
     /**
@@ -315,11 +414,9 @@
      * @since 1.8
      */
     public int end(String name) {
-        ensureMatch();
-        return matchOffsets[getMatchedGroupIndex(pattern.address, name) * 2 + 1];
+        return groups[getMatchedGroupIndex(name) * 2 + 1];
     }
 
-
     /**
      * Returns the input subsequence matched by the previous match.
      *
@@ -380,13 +477,11 @@
      */
     public String group(int group) {
         ensureMatch();
-        int from = matchOffsets[group * 2];
-        int to = matchOffsets[(group * 2) + 1];
-        if (from == -1 || to == -1) {
+        if (group < 0 || group > groupCount())
+            throw new IndexOutOfBoundsException("No group " + group);
+        if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
             return null;
-        } else {
-            return input.substring(from, to);
-        }
+        return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
     }
 
     /**
@@ -417,15 +512,10 @@
      * @since 1.7
      */
     public String group(String name) {
-        ensureMatch();
-        int group = getMatchedGroupIndex(pattern.address, name);
-        int from = matchOffsets[group * 2];
-        int to = matchOffsets[(group * 2) + 1];
-        if (from == -1 || to == -1) {
+        int group = getMatchedGroupIndex(name);
+        if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
             return null;
-        } else {
-            return input.substring(from, to);
-        }
+        return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
     }
 
     /**
@@ -457,7 +547,7 @@
      */
     public boolean matches() {
         synchronized (this) {
-            matchFound = matchesImpl(address, matchOffsets);
+            matchFound = matchesImpl(address, groups);
         }
         return matchFound;
     }
@@ -479,7 +569,7 @@
      */
     public boolean find() {
         synchronized (this) {
-            matchFound = findNextImpl(address, matchOffsets);
+            matchFound = findNextImpl(address, groups);
         }
         return matchFound;
     }
@@ -494,6 +584,7 @@
      * invocations of the {@link #find()} method will start at the first
      * character not matched by this match.  </p>
      *
+     * @param start the index to start searching for a match
      * @throws  IndexOutOfBoundsException
      *          If start is less than zero or if start is greater than the
      *          length of the input sequence.
@@ -503,13 +594,12 @@
      *          pattern
      */
     public boolean find(int start) {
+        int limit = getTextLength();
+        if ((start < 0) || (start > limit))
+            throw new IndexOutOfBoundsException("Illegal start index");
         reset();
-        if (start < 0 || start > input.length()) {
-            throw new IndexOutOfBoundsException("start=" + start + "; length=" + input.length());
-        }
-
         synchronized (this) {
-            matchFound = findImpl(address, start, matchOffsets);
+            matchFound = findImpl(address, start, groups);
         }
         return matchFound;
     }
@@ -530,7 +620,7 @@
      */
     public boolean lookingAt() {
         synchronized (this) {
-            matchFound = lookingAtImpl(address, matchOffsets);
+            matchFound = lookingAtImpl(address, groups);
         }
         return matchFound;
     }
@@ -588,8 +678,10 @@
      *
      * <p> The replacement string may contain references to subsequences
      * captured during the previous match: Each occurrence of
-     * <tt>$</tt><i>g</i> will be replaced by the result of evaluating the corresponding
-     * {@link #group(int) group(g)</tt>} respectively. For  <tt>$</tt><i>g</i><tt></tt>,
+     * <tt>${</tt><i>name</i><tt>}</tt> or <tt>$</tt><i>g</i>
+     * will be replaced by the result of evaluating the corresponding
+     * {@link #group(String) group(name)} or {@link #group(int) group(g)}
+     * respectively. For  <tt>$</tt><i>g</i>,
      * the first number after the <tt>$</tt> is always treated as part of
      * the group reference. Subsequent numbers are incorporated into g if
      * they would form a legal group reference. Only the numerals '0'
@@ -643,7 +735,8 @@
      *          that does not exist in the pattern
      */
     public Matcher appendReplacement(StringBuffer sb, String replacement) {
-        sb.append(input.substring(appendPos, start()));
+
+        sb.append(text.substring(appendPos, start()));
         appendEvaluated(sb, replacement);
         appendPos = end();
 
@@ -692,16 +785,19 @@
             }
         }
 
+        if (escape) {
+            throw new IllegalArgumentException("character to be escaped is missing");
+        }
+
+        if (dollar) {
+            throw new IllegalArgumentException("Illegal group reference: group index is missing");
+        }
+
         if (escapeNamedGroup) {
             throw new IllegalArgumentException("Missing ending brace '}' from replacement string");
         }
-
-        if (escape) {
-            throw new ArrayIndexOutOfBoundsException(s.length());
-        }
     }
 
-
     /**
      * Implements a terminal append-and-replace step.
      *
@@ -717,8 +813,8 @@
      * @return  The target string buffer
      */
     public StringBuffer appendTail(StringBuffer sb) {
-        if (appendPos < regionEnd) {
-            sb.append(input.substring(appendPos, regionEnd));
+        if (appendPos < to) {
+            sb.append(text.substring(appendPos, to));
         }
         return sb;
     }
@@ -759,11 +855,17 @@
      */
     public String replaceAll(String replacement) {
         reset();
-        StringBuffer buffer = new StringBuffer(input.length());
-        while (find()) {
-            appendReplacement(buffer, replacement);
+        boolean result = find();
+        if (result) {
+            StringBuffer sb = new StringBuffer();
+            do {
+                appendReplacement(sb, replacement);
+                result = find();
+            } while (result);
+            appendTail(sb);
+            return sb.toString();
         }
-        return appendTail(buffer).toString();
+        return text.toString();
     }
 
     /**
@@ -800,12 +902,15 @@
      *          subsequences as needed
      */
     public String replaceFirst(String replacement) {
+        if (replacement == null)
+            throw new NullPointerException("replacement");
         reset();
-        StringBuffer buffer = new StringBuffer(input.length());
-        if (find()) {
-            appendReplacement(buffer, replacement);
-        }
-        return appendTail(buffer).toString();
+        if (!find())
+            return text.toString();
+        StringBuffer sb = new StringBuffer();
+        appendReplacement(sb, replacement);
+        appendTail(sb);
+        return sb.toString();
     }
 
     /**
@@ -847,7 +952,7 @@
      * @since 1.5
      */
     public int regionStart() {
-        return regionStart;
+        return from;
     }
 
     /**
@@ -860,7 +965,7 @@
      * @since 1.5
      */
     public int regionEnd() {
-        return regionEnd;
+        return to;
     }
 
     /**
@@ -904,16 +1009,16 @@
      *
      * <p> By default, a matcher uses opaque bounds.
      *
-     * @param  value a boolean indicating whether to use opaque or transparent
+     * @param  b a boolean indicating whether to use opaque or transparent
      *         regions
      * @return this matcher
      * @see java.util.regex.Matcher#hasTransparentBounds
      * @since 1.5
      */
-    public Matcher useTransparentBounds(boolean value) {
+    public Matcher useTransparentBounds(boolean b) {
         synchronized (this) {
-            transparentBounds = value;
-            useTransparentBoundsImpl(address, value);
+            transparentBounds = b;
+            useTransparentBoundsImpl(address, b);
         }
         return this;
     }
@@ -954,15 +1059,15 @@
      *
      * <p> By default, a matcher uses anchoring region boundaries.
      *
-     * @param  value a boolean indicating whether or not to use anchoring bounds.
+     * @param  b a boolean indicating whether or not to use anchoring bounds.
      * @return this matcher
      * @see java.util.regex.Matcher#hasAnchoringBounds
      * @since 1.5
      */
-    public Matcher useAnchoringBounds(boolean value) {
+    public Matcher useAnchoringBounds(boolean b) {
         synchronized (this) {
-            anchoringBounds = value;
-            useAnchoringBoundsImpl(address, value);
+            anchoringBounds = b;
+            useAnchoringBoundsImpl(address, b);
         }
         return this;
     }
@@ -1006,7 +1111,6 @@
         }
     }
 
-
     /**
      * <p>Returns true if more input could change a positive match into a
      * negative one.
@@ -1028,35 +1132,23 @@
     }
 
     /**
-     * Resets this matcher.
+     * Returns the end index of the text.
      *
-     * <p> Resetting a matcher discards all of its explicit state information
-     * and sets its append position to zero. The matcher's region is set to the
-     * default region, which is its entire character sequence. The anchoring
-     * and transparency of this matcher's region boundaries are unaffected.
-     *
-     * @return  This matcher
+     * @return the index after the last character in the text
      */
-    public Matcher reset() {
-        return reset(originalInput, 0, originalInput.length());
+    int getTextLength() {
+        return text.length();
     }
 
     /**
-     * Resets this matcher with a new input sequence.
+     * Generates a String from this Matcher's input in the specified range.
      *
-     * <p> Resetting a matcher discards all of its explicit state information
-     * and sets its append position to zero.  The matcher's region is set to
-     * the default region, which is its entire character sequence.  The
-     * anchoring and transparency of this matcher's region boundaries are
-     * unaffected.
-     *
-     * @param  input
-     *         The new input character sequence
-     *
-     * @return  This matcher
+     * @param  beginIndex   the beginning index, inclusive
+     * @param  endIndex     the ending index, exclusive
+     * @return A String generated from this Matcher's input
      */
-    public Matcher reset(CharSequence input) {
-        return reset(input, 0, input.length());
+    CharSequence getSubSequence(int beginIndex, int endIndex) {
+        return text.subSequence(beginIndex, endIndex);
     }
 
     /**
@@ -1085,9 +1177,9 @@
         }
 
         this.originalInput = input;
-        this.input = input.toString();
-        this.regionStart = start;
-        this.regionEnd = end;
+        this.text = input.toString();
+        this.from = start;
+        this.to = end;
         resetForInput();
 
         matchFound = false;
@@ -1098,7 +1190,7 @@
 
     private void resetForInput() {
         synchronized (this) {
-            setInputImpl(address, input, regionStart, regionEnd);
+            setInputImpl(address, text, from, to);
             useAnchoringBoundsImpl(address, anchoringBounds);
             useTransparentBoundsImpl(address, transparentBounds);
         }
@@ -1117,77 +1209,9 @@
         }
     }
 
-    /**
-     * Returns the start index of the previous match.  </p>
-     *
-     * @return  The index of the first character matched
-     *
-     * @throws  IllegalStateException
-     *          If no match has yet been attempted,
-     *          or if the previous match operation failed
-     */
-    public int start() {
-        return start(0);
-    }
-
-    /**
-     * Returns the start index of the subsequence captured by the given group
-     * during the previous match operation.
-     *
-     * <p> <a href="Pattern.html#cg">Capturing groups</a> are indexed from left
-     * to right, starting at one.  Group zero denotes the entire pattern, so
-     * the expression <i>m.</i><tt>start(0)</tt> is equivalent to
-     * <i>m.</i><tt>start()</tt>.  </p>
-     *
-     * @param  group
-     *         The index of a capturing group in this matcher's pattern
-     *
-     * @return  The index of the first character captured by the group,
-     *          or <tt>-1</tt> if the match was successful but the group
-     *          itself did not match anything
-     *
-     * @throws  IllegalStateException
-     *          If no match has yet been attempted,
-     *          or if the previous match operation failed
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If there is no capturing group in the pattern
-     *          with the given index
-     */
-    public int start(int group) throws IllegalStateException {
+    private int getMatchedGroupIndex(String name) {
         ensureMatch();
-        return matchOffsets[group * 2];
-    }
-
-
-    /**
-     * Returns the start index of the subsequence captured by the given
-     * <a href="Pattern.html#groupname">named-capturing group</a> during the
-     * previous match operation.
-     *
-     * @param  name
-     *         The name of a named-capturing group in this matcher's pattern
-     *
-     * @return  The index of the first character captured by the group,
-     *          or {@code -1} if the match was successful but the group
-     *          itself did not match anything
-     *
-     * @throws  IllegalStateException
-     *          If no match has yet been attempted,
-     *          or if the previous match operation failed
-     *
-     * @throws  IllegalArgumentException
-     *          If there is no capturing group in the pattern
-     *          with the given name
-     * @since 1.8
-     */
-    public int start(String name) {
-        ensureMatch();
-        return matchOffsets[getMatchedGroupIndex(pattern.address, name) * 2];
-    }
-
-    private static int getMatchedGroupIndex(long patternAddr, String name) {
-        int result = getMatchedGroupIndex0(patternAddr, name);
+        int result = getMatchedGroupIndex0(parentPattern.address, name);
         if (result < 0) {
             throw new IllegalArgumentException("No capturing group in the pattern " +
                                                "with the name " + name);
diff --git a/ojluni/src/main/java/java/util/regex/Pattern.java b/ojluni/src/main/java/java/util/regex/Pattern.java
index 5938431..1464deb 100644
--- a/ojluni/src/main/java/java/util/regex/Pattern.java
+++ b/ojluni/src/main/java/java/util/regex/Pattern.java
@@ -27,6 +27,8 @@
 package java.util.regex;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
+import dalvik.system.VMRuntime;
+
 import libcore.util.NativeAllocationRegistry;
 
 import java.util.Iterator;
@@ -40,14 +42,16 @@
 
 import libcore.util.EmptyArray;
 
-// Android-changed: Add min API level of 26 for the named capaturing in javadoc
+// Android-changed: Document that named capturing is only available from API 26.
+// Android-changed: Android always uses unicode character classes.
+// UNICODE_CHARACTER_CLASS has no effect on Android.
 /**
  * A compiled representation of a regular expression.
  *
  * <p> A regular expression, specified as a string, must first be compiled into
  * an instance of this class.  The resulting pattern can then be used to create
- * a {@link Matcher} object that can match arbitrary {@link
- * java.lang.CharSequence </code>character sequences<code>} against the regular
+ * a {@link Matcher} object that can match arbitrary {@linkplain
+ * java.lang.CharSequence character sequences} against the regular
  * expression.  All of the state involved in performing a match resides in the
  * matcher, so many matchers can share the same pattern.
  *
@@ -74,15 +78,14 @@
  * such use.
  *
  *
- * <a name="sum">
- * <h4> Summary of regular-expression constructs </h4>
+ * <h3><a name="sum">Summary of regular-expression constructs</a></h3>
  *
  * <table border="0" cellpadding="1" cellspacing="0"
  *  summary="Regular expression constructs, and what they match">
  *
  * <tr align="left">
- * <th bgcolor="#CCCCFF" align="left" id="construct">Construct</th>
- * <th bgcolor="#CCCCFF" align="left" id="matches">Matches</th>
+ * <th align="left" id="construct">Construct</th>
+ * <th align="left" id="matches">Matches</th>
  * </tr>
  *
  * <tr><th>&nbsp;</th></tr>
@@ -109,7 +112,7 @@
  * <tr><td valign="top" headers="construct characters"><tt>&#92;x</tt><i>{h...h}</i></td>
  *     <td headers="matches">The character with hexadecimal&nbsp;value&nbsp;<tt>0x</tt><i>h...h</i>
  *         ({@link java.lang.Character#MIN_CODE_POINT Character.MIN_CODE_POINT}
- *         &nbsp;&lt;=&nbsp;<tt>0x</tt><i>h...h</i>&nbsp;&lt;=&nbsp
+ *         &nbsp;&lt;=&nbsp;<tt>0x</tt><i>h...h</i>&nbsp;&lt;=&nbsp;
  *          {@link java.lang.Character#MAX_CODE_POINT Character.MAX_CODE_POINT})</td></tr>
  * <tr><td valign="top" headers="matches"><tt>\t</tt></td>
  *     <td headers="matches">The tab character (<tt>'&#92;u0009'</tt>)</td></tr>
@@ -129,24 +132,24 @@
  * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2" id="classes">Character classes</th></tr>
  *
- * <tr><td valign="top" headers="construct classes"><tt>[abc]</tt></td>
- *     <td headers="matches"><tt>a</tt>, <tt>b</tt>, or <tt>c</tt> (simple class)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[^abc]</tt></td>
- *     <td headers="matches">Any character except <tt>a</tt>, <tt>b</tt>, or <tt>c</tt> (negation)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-zA-Z]</tt></td>
- *     <td headers="matches"><tt>a</tt> through <tt>z</tt>
- *         or <tt>A</tt> through <tt>Z</tt>, inclusive (range)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-d[m-p]]</tt></td>
- *     <td headers="matches"><tt>a</tt> through <tt>d</tt>,
- *      or <tt>m</tt> through <tt>p</tt>: <tt>[a-dm-p]</tt> (union)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[def]]</tt></td>
- *     <td headers="matches"><tt>d</tt>, <tt>e</tt>, or <tt>f</tt> (intersection)</tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[^bc]]</tt></td>
- *     <td headers="matches"><tt>a</tt> through <tt>z</tt>,
- *         except for <tt>b</tt> and <tt>c</tt>: <tt>[ad-z]</tt> (subtraction)</td></tr>
- * <tr><td valign="top" headers="construct classes"><tt>[a-z&&[^m-p]]</tt></td>
- *     <td headers="matches"><tt>a</tt> through <tt>z</tt>,
- *          and not <tt>m</tt> through <tt>p</tt>: <tt>[a-lq-z]</tt>(subtraction)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [abc]}</td>
+ *     <td headers="matches">{@code a}, {@code b}, or {@code c} (simple class)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [^abc]}</td>
+ *     <td headers="matches">Any character except {@code a}, {@code b}, or {@code c} (negation)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-zA-Z]}</td>
+ *     <td headers="matches">{@code a} through {@code z}
+ *         or {@code A} through {@code Z}, inclusive (range)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-d[m-p]]}</td>
+ *     <td headers="matches">{@code a} through {@code d},
+ *      or {@code m} through {@code p}: {@code [a-dm-p]} (union)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[def]]}</td>
+ *     <td headers="matches">{@code d}, {@code e}, or {@code f} (intersection)</tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[^bc]]}</td>
+ *     <td headers="matches">{@code a} through {@code z},
+ *         except for {@code b} and {@code c}: {@code [ad-z]} (subtraction)</td></tr>
+ * <tr><td valign="top" headers="construct classes">{@code [a-z&&[^m-p]]}</td>
+ *     <td headers="matches">{@code a} through {@code z},
+ *          and not {@code m} through {@code p}: {@code [a-lq-z]}(subtraction)</td></tr>
  * <tr><th>&nbsp;</th></tr>
  *
  * <tr align="left"><th colspan="2" id="predef">Predefined character classes</th></tr>
@@ -157,46 +160,55 @@
  *     <td headers="matches">A digit: <tt>[0-9]</tt></td></tr>
  * <tr><td valign="top" headers="construct predef"><tt>\D</tt></td>
  *     <td headers="matches">A non-digit: <tt>[^0-9]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\h</tt></td>
+ *     <td headers="matches">A horizontal whitespace character:
+ *     <tt>[ \t\xA0&#92;u1680&#92;u180e&#92;u2000-&#92;u200a&#92;u202f&#92;u205f&#92;u3000]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\H</tt></td>
+ *     <td headers="matches">A non-horizontal whitespace character: <tt>[^\h]</tt></td></tr>
  * <tr><td valign="top" headers="construct predef"><tt>\s</tt></td>
  *     <td headers="matches">A whitespace character: <tt>[ \t\n\x0B\f\r]</tt></td></tr>
  * <tr><td valign="top" headers="construct predef"><tt>\S</tt></td>
  *     <td headers="matches">A non-whitespace character: <tt>[^\s]</tt></td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\v</tt></td>
+ *     <td headers="matches">A vertical whitespace character: <tt>[\n\x0B\f\r\x85&#92;u2028&#92;u2029]</tt>
+ *     </td></tr>
+ * <tr><td valign="top" headers="construct predef"><tt>\V</tt></td>
+ *     <td headers="matches">A non-vertical whitespace character: <tt>[^\v]</tt></td></tr>
  * <tr><td valign="top" headers="construct predef"><tt>\w</tt></td>
  *     <td headers="matches">A word character: <tt>[a-zA-Z_0-9]</tt></td></tr>
  * <tr><td valign="top" headers="construct predef"><tt>\W</tt></td>
  *     <td headers="matches">A non-word character: <tt>[^\w]</tt></td></tr>
- *
  * <tr><th>&nbsp;</th></tr>
- * <tr align="left"><th colspan="2" id="posix">POSIX character classes</b> (US-ASCII only)<b></th></tr>
+ * <tr align="left"><th colspan="2" id="posix"><b>POSIX character classes (US-ASCII only)</b></th></tr>
  *
- * <tr><td valign="top" headers="construct posix"><tt>\p{Lower}</tt></td>
- *     <td headers="matches">A lower-case alphabetic character: <tt>[a-z]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Upper}</tt></td>
- *     <td headers="matches">An upper-case alphabetic character:<tt>[A-Z]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{ASCII}</tt></td>
- *     <td headers="matches">All ASCII:<tt>[\x00-\x7F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Alpha}</tt></td>
- *     <td headers="matches">An alphabetic character:<tt>[\p{Lower}\p{Upper}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Digit}</tt></td>
- *     <td headers="matches">A decimal digit: <tt>[0-9]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Alnum}</tt></td>
- *     <td headers="matches">An alphanumeric character:<tt>[\p{Alpha}\p{Digit}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Punct}</tt></td>
- *     <td headers="matches">Punctuation: One of <tt>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</tt></td></tr>
- *     <!-- <tt>[\!"#\$%&'\(\)\*\+,\-\./:;\<=\>\?@\[\\\]\^_`\{\|\}~]</tt>
- *          <tt>[\X21-\X2F\X31-\X40\X5B-\X60\X7B-\X7E]</tt> -->
- * <tr><td valign="top" headers="construct posix"><tt>\p{Graph}</tt></td>
- *     <td headers="matches">A visible character: <tt>[\p{Alnum}\p{Punct}]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Print}</tt></td>
- *     <td headers="matches">A printable character: <tt>[\p{Graph}\x20]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Blank}</tt></td>
- *     <td headers="matches">A space or a tab: <tt>[ \t]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Cntrl}</tt></td>
- *     <td headers="matches">A control character: <tt>[\x00-\x1F\x7F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{XDigit}</tt></td>
- *     <td headers="matches">A hexadecimal digit: <tt>[0-9a-fA-F]</tt></td></tr>
- * <tr><td valign="top" headers="construct posix"><tt>\p{Space}</tt></td>
- *     <td headers="matches">A whitespace character: <tt>[ \t\n\x0B\f\r]</tt></td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Lower}}</td>
+ *     <td headers="matches">A lower-case alphabetic character: {@code [a-z]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Upper}}</td>
+ *     <td headers="matches">An upper-case alphabetic character:{@code [A-Z]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{ASCII}}</td>
+ *     <td headers="matches">All ASCII:{@code [\x00-\x7F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Alpha}}</td>
+ *     <td headers="matches">An alphabetic character:{@code [\p{Lower}\p{Upper}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Digit}}</td>
+ *     <td headers="matches">A decimal digit: {@code [0-9]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Alnum}}</td>
+ *     <td headers="matches">An alphanumeric character:{@code [\p{Alpha}\p{Digit}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Punct}}</td>
+ *     <td headers="matches">Punctuation: One of {@code !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~}</td></tr>
+ *     <!-- {@code [\!"#\$%&'\(\)\*\+,\-\./:;\<=\>\?@\[\\\]\^_`\{\|\}~]}
+ *          {@code [\X21-\X2F\X31-\X40\X5B-\X60\X7B-\X7E]} -->
+ * <tr><td valign="top" headers="construct posix">{@code \p{Graph}}</td>
+ *     <td headers="matches">A visible character: {@code [\p{Alnum}\p{Punct}]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Print}}</td>
+ *     <td headers="matches">A printable character: {@code [\p{Graph}\x20]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Blank}}</td>
+ *     <td headers="matches">A space or a tab: {@code [ \t]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Cntrl}}</td>
+ *     <td headers="matches">A control character: {@code [\x00-\x1F\x7F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{XDigit}}</td>
+ *     <td headers="matches">A hexadecimal digit: {@code [0-9a-fA-F]}</td></tr>
+ * <tr><td valign="top" headers="construct posix">{@code \p{Space}}</td>
+ *     <td headers="matches">A whitespace character: {@code [ \t\n\x0B\f\r]}</td></tr>
  *
  * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2">java.lang.Character classes (simple <a href="#jcc">java character type</a>)</th></tr>
@@ -212,19 +224,19 @@
  *
  * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
- * * <tr><td valign="top" headers="construct unicode"><tt>\p{IsLatin}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
  *     <td headers="matches">A Latin&nbsp;script character (<a href="#usc">script</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{InGreek}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td>
  *     <td headers="matches">A character in the Greek&nbsp;block (<a href="#ubc">block</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{Lu}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{Lu}}</td>
  *     <td headers="matches">An uppercase letter (<a href="#ucc">category</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{IsAlphabetic}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsAlphabetic}}</td>
  *     <td headers="matches">An alphabetic character (<a href="#ubpc">binary property</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{Sc}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{Sc}}</td>
  *     <td headers="matches">A currency symbol</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\P{InGreek}</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code \P{InGreek}}</td>
  *     <td headers="matches">Any character except one in the Greek block (negation)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>[\p{L}&&[^\p{Lu}]]&nbsp;</tt></td>
+ * <tr><td valign="top" headers="construct unicode">{@code [\p{L}&&[^\p{Lu}]]}</td>
  *     <td headers="matches">Any letter except an uppercase letter (subtraction)</td></tr>
  *
  * <tr><th>&nbsp;</th></tr>
@@ -249,6 +261,13 @@
  *     <td headers="matches">The end of the input</td></tr>
  *
  * <tr><th>&nbsp;</th></tr>
+ * <tr align="left"><th colspan="2" id="lineending">Linebreak matcher</th></tr>
+ * <tr><td valign="top" headers="construct lineending"><tt>\R</tt></td>
+ *     <td headers="matches">Any Unicode linebreak sequence, is equivalent to
+ *     <tt>&#92;u000D&#92;u000A|[&#92;u000A&#92;u000B&#92;u000C&#92;u000D&#92;u0085&#92;u2028&#92;u2029]
+ *     </tt></td></tr>
+ *
+ * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2" id="greedy">Greedy quantifiers</th></tr>
  *
  * <tr><td valign="top" headers="construct greedy"><i>X</i><tt>?</tt></td>
@@ -361,8 +380,7 @@
  * <hr>
  *
  *
- * <a name="bs">
- * <h4> Backslashes, escapes, and quoting </h4>
+ * <h3><a name="bs">Backslashes, escapes, and quoting</a></h3>
  *
  * <p> The backslash character (<tt>'\'</tt>) serves to introduce escaped
  * constructs, as defined in the table above, as well as to quote characters
@@ -390,8 +408,7 @@
  * <tt>(hello)</tt> the string literal <tt>"&#92;&#92;(hello&#92;&#92;)"</tt>
  * must be used.
  *
- * <a name="cc">
- * <h4> Character Classes </h4>
+ * <h3><a name="cc">Character Classes</a></h3>
  *
  *    <p> Character classes may appear within other character classes, and
  *    may be composed by the union operator (implicit) and the intersection
@@ -420,7 +437,7 @@
  *        <td><tt>[a-e][i-u]</tt></td></tr>
  *      <tr><th>5&nbsp;&nbsp;&nbsp;&nbsp;</th>
  *        <td>Intersection</td>
- *        <td><tt>[a-z&&[aeiou]]</tt></td></tr>
+ *        <td>{@code [a-z&&[aeiou]]}</td></tr>
  *    </table></blockquote>
  *
  *    <p> Note that a different set of metacharacters are in effect inside
@@ -429,8 +446,7 @@
  *    character class, while the expression <tt>-</tt> becomes a range
  *    forming metacharacter.
  *
- * <a name="lt">
- * <h4> Line terminators </h4>
+ * <h3><a name="lt">Line terminators</a></h3>
  *
  * <p> A <i>line terminator</i> is a one- or two-character sequence that marks
  * the end of a line of the input character sequence.  The following are
@@ -465,11 +481,9 @@
  * except at the end of input. When in {@link #MULTILINE} mode <tt>$</tt>
  * matches just before a line terminator or the end of the input sequence.
  *
- * <a name="cg">
- * <h4> Groups and capturing </h4>
+ * <h3><a name="cg">Groups and capturing</a></h3>
  *
- * <a name="gnumber">
- * <h5> Group number </h5>
+ * <h4><a name="gnumber">Group number</a></h4>
  * <p> Capturing groups are numbered by counting their opening parentheses from
  * left to right.  In the expression <tt>((A)(B(C)))</tt>, for example, there
  * are four such groups: </p>
@@ -492,8 +506,7 @@
  * subsequence may be used later in the expression, via a back reference, and
  * may also be retrieved from the matcher once the match operation is complete.
  *
- * <a name="groupname">
- * <h5> Group name </h5>
+ * <h4><a name="groupname">Group name</a></h4>
  * <p>The constructs and APIs are available since API level 26. A capturing group
  * can also be assigned a "name", a <tt>named-capturing group</tt>,
  * and then be back-referenced later by the "name". Group names are composed of
@@ -523,7 +536,7 @@
  * that do not capture text and do not count towards the group total, or
  * <i>named-capturing</i> group.
  *
- * <h4> Unicode support </h4>
+ * <h3> Unicode support </h3>
  *
  * <p> This class is in conformance with Level 1 of <a
  * href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
@@ -554,18 +567,18 @@
  * <p>
  * Scripts, blocks, categories and binary properties can be used both inside
  * and outside of a character class.
- * <a name="usc">
+ *
  * <p>
- * <b>Scripts</b> are specified either with the prefix {@code Is}, as in
+ * <b><a name="usc">Scripts</a></b> are specified either with the prefix {@code Is}, as in
  * {@code IsHiragana}, or by using  the {@code script} keyword (or its short
  * form {@code sc})as in {@code script=Hiragana} or {@code sc=Hiragana}.
  * <p>
  * The script names supported by <code>Pattern</code> are the valid script names
  * accepted and defined by
  * {@link java.lang.Character.UnicodeScript#forName(String) UnicodeScript.forName}.
- * <a name="ubc">
+ *
  * <p>
- * <b>Blocks</b> are specified with the prefix {@code In}, as in
+ * <b><a name="ubc">Blocks</a></b> are specified with the prefix {@code In}, as in
  * {@code InMongolian}, or by using the keyword {@code block} (or its short
  * form {@code blk}) as in {@code block=Mongolian} or {@code blk=Mongolian}.
  * <p>
@@ -573,8 +586,8 @@
  * accepted and defined by
  * {@link java.lang.Character.UnicodeBlock#forName(String) UnicodeBlock.forName}.
  * <p>
- * <a name="ucc">
- * <b>Categories</b> may be specified with the optional prefix {@code Is}:
+ *
+ * <b><a name="ucc">Categories</a></b> may be specified with the optional prefix {@code Is}:
  * Both {@code \p{L}} and {@code \p{IsL}} denote the category of Unicode
  * letters. Same as scripts and blocks, categories can also be specified
  * by using the keyword {@code general_category} (or its short form
@@ -586,8 +599,8 @@
  * {@link java.lang.Character Character} class. The category names are those
  * defined in the Standard, both normative and informative.
  * <p>
- * <a name="ubpc">
- * <b>Binary properties</b> are specified with the prefix {@code Is}, as in
+ *
+ * <b><a name="ubpc">Binary properties</a></b> are specified with the prefix {@code Is}, as in
  * {@code IsAlphabetic}. The supported binary properties by <code>Pattern</code>
  * are
  * <ul>
@@ -602,22 +615,21 @@
  *   <li> White_Space
  *   <li> Digit
  *   <li> Hex_Digit
+ *   <li> Join_Control
  *   <li> Noncharacter_Code_Point
  *   <li> Assigned
  * </ul>
-
-
  * <p>
- * <b>Predefined Character classes</b> and <b>POSIX character classes</b> are in
- * conformance with the recommendation of <i>Annex C: Compatibility Properties</i>
+ * The following <b>Predefined Character classes</b> and <b>POSIX character classes</b>
+ * are in conformance with the recommendation of <i>Annex C: Compatibility Properties</i>
  * of <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Regular Expression
  * </i></a>.
- * <p>
+ *
  * <table border="0" cellpadding="1" cellspacing="0"
  *  summary="predefined and posix character classes in Unicode mode">
  * <tr align="left">
- * <th bgcolor="#CCCCFF" align="left" id="classes">Classes</th>
- * <th bgcolor="#CCCCFF" align="left" id="matches">Matches</th>
+ * <th align="left" id="predef_classes">Classes</th>
+ * <th align="left" id="predef_matches">Matches</th>
  *</tr>
  * <tr><td><tt>\p{Lower}</tt></td>
  *     <td>A lowercase character:<tt>\p{IsLowercase}</tt></td></tr>
@@ -636,9 +648,9 @@
  * <tr><td><tt>\p{Graph}</tt></td>
  *     <td>A visible character: <tt>[^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]</tt></td></tr>
  * <tr><td><tt>\p{Print}</tt></td>
- *     <td>A printable character: <tt>[\p{Graph}\p{Blank}&&[^\p{Cntrl}]]</tt></td></tr>
+ *     <td>A printable character: {@code [\p{Graph}\p{Blank}&&[^\p{Cntrl}]]}</td></tr>
  * <tr><td><tt>\p{Blank}</tt></td>
- *     <td>A space or a tab: <tt>[\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]</tt></td></tr>
+ *     <td>A space or a tab: {@code [\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]}</td></tr>
  * <tr><td><tt>\p{Cntrl}</tt></td>
  *     <td>A control character: <tt>\p{gc=Cc}</tt></td></tr>
  * <tr><td><tt>\p{XDigit}</tt></td>
@@ -654,7 +666,7 @@
  * <tr><td><tt>\S</tt></td>
  *     <td>A non-whitespace character: <tt>[^\s]</tt></td></tr>
  * <tr><td><tt>\w</tt></td>
- *     <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}]</tt></td></tr>
+ *     <td>A word character: <tt>[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]</tt></td></tr>
  * <tr><td><tt>\W</tt></td>
  *     <td>A non-word character: <tt>[^\w]</tt></td></tr>
  * </table>
@@ -663,9 +675,9 @@
  * Categories that behave like the java.lang.Character
  * boolean is<i>methodname</i> methods (except for the deprecated ones) are
  * available through the same <tt>\p{</tt><i>prop</i><tt>}</tt> syntax where
- * the specified property has the name <tt>java<i>methodname</i></tt>.
+ * the specified property has the name <tt>java<i>methodname</i></tt></a>.
  *
- * <h4> Comparison to Perl 5 </h4>
+ * <h3> Comparison to Perl 5 </h3>
  *
  * <p>The <code>Pattern</code> engine performs traditional NFA-based matching
  * with ordered alternation as occurs in Perl 5.
@@ -674,12 +686,6 @@
  *
  * <ul>
  *    <li><p> Predefined character classes (Unicode character)
- *    <p><tt>\h&nbsp;&nbsp;&nbsp;&nbsp;</tt>A horizontal whitespace
- *    <p><tt>\H&nbsp;&nbsp;&nbsp;&nbsp;</tt>A non horizontal whitespace
- *    <p><tt>\v&nbsp;&nbsp;&nbsp;&nbsp;</tt>A vertical whitespace
- *    <p><tt>\V&nbsp;&nbsp;&nbsp;&nbsp;</tt>A non vertical whitespace
- *    <p><tt>\R&nbsp;&nbsp;&nbsp;&nbsp;</tt>Any Unicode linebreak sequence
- *    <tt>\u005cu000D\u005cu000A|[\u005cu000A\u005cu000B\u005cu000C\u005cu000D\u005cu0085\u005cu2028\u005cu2029]</tt>
  *    <p><tt>\X&nbsp;&nbsp;&nbsp;&nbsp;</tt>Match Unicode
  *    <a href="http://www.unicode.org/reports/tr18/#Default_Grapheme_Clusters">
  *    <i>extended grapheme cluster</i></a>
@@ -766,7 +772,8 @@
  * @spec        JSR-51
  */
 
-public final class Pattern implements java.io.Serializable
+public final class Pattern
+    implements java.io.Serializable
 {
 
     /**
@@ -894,9 +901,10 @@
      */
     public static final int CANON_EQ = 0x80;
 
+    // Android-changed: Android always uses unicode character classes.
     /**
      * Enables the Unicode version of <i>Predefined character classes</i> and
-     * <i>POSIX character classes</i> as eefined by <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
+     * <i>POSIX character classes</i> as defined by <a href="http://www.unicode.org/reports/tr18/"><i>Unicode Technical
      * Standard #18: Unicode Regular Expression</i></a>
      * <i>Annex C: Compatibility Properties</i>.
      * <p>
@@ -921,6 +929,8 @@
      *
      * @serial
      */
+    // Android-changed: reimplement matching logic natively via ICU.
+    // private String pattern;
     private final String pattern;
 
     /**
@@ -928,21 +938,26 @@
      *
      * @serial
      */
+    // Android-changed: reimplement matching logic natively via ICU.
+    // private int flags;
     private final int flags;
 
+    // BEGIN Android-changed: reimplement matching logic natively via ICU.
+    // We only need some tie-ins to native memory, instead of a large number
+    // of fields on the .java side.
     @ReachabilitySensitive
     transient long address;
 
     private static final NativeAllocationRegistry registry = new NativeAllocationRegistry(
             Pattern.class.getClassLoader(), getNativeFinalizer(), nativeSize());
-
+    // END Android-changed: reimplement matching logic natively via ICU.
 
     /**
-     * Compiles the given regular expression into a pattern.  </p>
+     * Compiles the given regular expression into a pattern.
      *
      * @param  regex
      *         The expression to be compiled
-     *
+     * @return the given regular expression compiled into a pattern
      * @throws  PatternSyntaxException
      *          If the expression's syntax is invalid
      */
@@ -952,7 +967,7 @@
 
     /**
      * Compiles the given regular expression into a pattern with the given
-     * flags.  </p>
+     * flags.
      *
      * @param  regex
      *         The expression to be compiled
@@ -964,6 +979,7 @@
      *         {@link #LITERAL}, {@link #UNICODE_CHARACTER_CLASS}
      *         and {@link #COMMENTS}
      *
+     * @return the given regular expression compiled into a pattern with the given flags
      * @throws  IllegalArgumentException
      *          If bit values other than those corresponding to the defined
      *          match flags are set in <tt>flags</tt>
@@ -971,13 +987,12 @@
      * @throws  PatternSyntaxException
      *          If the expression's syntax is invalid
      */
-    public static Pattern compile(String regex, int flags) throws PatternSyntaxException {
+    public static Pattern compile(String regex, int flags) {
         return new Pattern(regex, flags);
     }
 
     /**
      * Returns the regular expression from which this pattern was compiled.
-     * </p>
      *
      * @return  The source of this pattern
      */
@@ -999,7 +1014,6 @@
 
     /**
      * Creates a matcher that will match the given input against this pattern.
-     * </p>
      *
      * @param  input
      *         The character sequence to be matched
@@ -1007,12 +1021,21 @@
      * @return  A new matcher for this pattern
      */
     public Matcher matcher(CharSequence input) {
+        // Android-removed: Pattern is eagerly compiled() upon construction.
+        /*
+        if (!compiled) {
+            synchronized(this) {
+                if (!compiled)
+                    compile();
+            }
+        }
+        */
         Matcher m = new Matcher(this, input);
         return m;
     }
 
     /**
-     * Returns this pattern's match flags.  </p>
+     * Returns this pattern's match flags.
      *
      * @return  The match flags specified when this pattern was compiled
      */
@@ -1042,7 +1065,7 @@
      *
      * @param  input
      *         The character sequence to be matched
-     *
+     * @return whether or not the regular expression matches on the input
      * @throws  PatternSyntaxException
      *          If the expression's syntax is invalid
      */
@@ -1052,6 +1075,8 @@
         return m.matches();
     }
 
+    // Android-changed: Adopt split() behavior change only for apps targeting API > 28.
+    // http://b/109659282#comment7
     /**
      * Splits the given input sequence around matches of this pattern.
      *
@@ -1059,10 +1084,16 @@
      * input sequence that is terminated by another subsequence that matches
      * this pattern or is terminated by the end of the input sequence.  The
      * substrings in the array are in the order in which they occur in the
-     * input.  If this pattern does not match any subsequence of the input then
+     * input. If this pattern does not match any subsequence of the input then
      * the resulting array has just one element, namely the input sequence in
      * string form.
      *
+     * <p> When there is a positive-width match at the beginning of the input
+     * sequence then an empty leading substring is included at the beginning
+     * of the resulting array. A zero-width match at the beginning however
+     * can only produce such an empty leading substring for apps running on or
+     * targeting API versions <= 28.
+     *
      * <p> The <tt>limit</tt> parameter controls the number of times the
      * pattern is applied and therefore affects the length of the resulting
      * array.  If the limit <i>n</i> is greater than zero then the pattern
@@ -1079,9 +1110,9 @@
      *
      * <blockquote><table cellpadding=1 cellspacing=0
      *              summary="Split examples showing regex, limit, and result">
-     * <tr><th><P align="left"><i>Regex&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
-     *     <th><P align="left"><i>Limit&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
-     *     <th><P align="left"><i>Result&nbsp;&nbsp;&nbsp;&nbsp;</i></th></tr>
+     * <tr><th align="left"><i>Regex&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
+     *     <th align="left"><i>Limit&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
+     *     <th align="left"><i>Result&nbsp;&nbsp;&nbsp;&nbsp;</i></th></tr>
      * <tr><td align=center>:</td>
      *     <td align=center>2</td>
      *     <td><tt>{ "boo", "and:foo" }</tt></td></tr>
@@ -1102,7 +1133,6 @@
      *     <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
      * </table></blockquote>
      *
-     *
      * @param  input
      *         The character sequence to be split
      *
@@ -1113,11 +1143,12 @@
      *          around matches of this pattern
      */
     public String[] split(CharSequence input, int limit) {
+        // BEGIN Android-added: fastSplit() to speed up simple cases.
         String[] fast = fastSplit(pattern, input.toString(), limit);
         if (fast != null) {
             return fast;
         }
-
+        // END Android-added: fastSplit() to speed up simple cases.
         int index = 0;
         boolean matchLimited = limit > 0;
         ArrayList<String> matchList = new ArrayList<>();
@@ -1126,6 +1157,17 @@
         // Add segments before each match found
         while(m.find()) {
             if (!matchLimited || matchList.size() < limit - 1) {
+                if (index == 0 && index == m.start() && m.start() == m.end()) {
+                    // no empty leading substring included for zero-width match
+                    // at the beginning of the input char sequence.
+                    // BEGIN Android-changed: split() compat behavior for apps targeting <= 28.
+                    // continue;
+                    int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+                    if (targetSdkVersion > 28) {
+                        continue;
+                    }
+                    // END Android-changed: split() compat behavior for apps targeting <= 28.
+                }
                 String match = input.subSequence(index, m.start()).toString();
                 matchList.add(match);
                 index = m.end();
@@ -1154,6 +1196,7 @@
         return matchList.subList(0, resultSize).toArray(result);
     }
 
+    // BEGIN Android-added: fastSplit() to speed up simple cases.
     private static final String FASTSPLIT_METACHARACTERS = "\\?*+[](){}^$.|";
 
     /**
@@ -1232,6 +1275,7 @@
         result[separatorCount] = input.substring(begin, lastPartEnd);
         return result;
     }
+    // END Android-added: fastSplit() to speed up simple cases.
 
     /**
      * Splits the given input sequence around matches of this pattern.
@@ -1246,8 +1290,8 @@
      *
      * <blockquote><table cellpadding=1 cellspacing=0
      *              summary="Split examples showing regex and result">
-     * <tr><th><P align="left"><i>Regex&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
-     *     <th><P align="left"><i>Result</i></th></tr>
+     * <tr><th align="left"><i>Regex&nbsp;&nbsp;&nbsp;&nbsp;</i></th>
+     *     <th align="left"><i>Result</i></th></tr>
      * <tr><td align=center>:</td>
      *     <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
      * <tr><td align=center>o</td>
@@ -1307,15 +1351,47 @@
 
         // Read in all fields
         s.defaultReadObject();
+
+        // Android-removed: reimplement matching logic natively via ICU.
+        // // Initialize counts
+        // capturingGroupCount = 1;
+        // localCount = 0;
+
+        // Android-changed: Pattern is eagerly compiled() upon construction.
+        /*
+        // if length > 0, the Pattern is lazily compiled
+        compiled = false;
+        if (pattern.length() == 0) {
+            root = new Start(lastAccept);
+            matchRoot = lastAccept;
+            compiled = true;
+        }
+        */
         compile();
     }
 
+    // Android-changed: reimplement matching logic natively via ICU.
+    // Dropped documentation reference to Start and LastNode implementation
+    // details which do not apply on Android.
     /**
      * This private constructor is used to create all Patterns. The pattern
      * string and match flags are all that is needed to completely describe
      * a Pattern.
      */
     private Pattern(String p, int f) {
+        pattern = p;
+        flags = f;
+
+        // BEGIN Android-changed: Only specific flags are supported.
+        /*
+        // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
+        if ((flags & UNICODE_CHARACTER_CLASS) != 0)
+            flags |= UNICODE_CASE;
+
+        // Reset group index count
+        capturingGroupCount = 1;
+        localCount = 0;
+        */
         if ((f & CANON_EQ) != 0) {
             throw new UnsupportedOperationException("CANON_EQ flag not supported");
         }
@@ -1323,11 +1399,23 @@
         if ((f & ~supportedFlags) != 0) {
             throw new IllegalArgumentException("Unsupported flags: " + (f & ~supportedFlags));
         }
-        this.pattern = p;
-        this.flags = f;
-        compile();
+        // END Android-changed: Only specific flags are supported supported.
+
+        // BEGIN Android-removed: Pattern is eagerly compiled() upon construction.
+        // if (pattern.length() > 0) {
+        // END Android-removed: Pattern is eagerly compiled() upon construction.
+            compile();
+        // Android-removed: reimplement matching logic natively via ICU.
+        /*
+        } else {
+            root = new Start(lastAccept);
+            matchRoot = lastAccept;
+        }
+        */
     }
 
+    // BEGIN Android-changed: reimplement matching logic natively via ICU.
+    // Use native implementation instead of > 3000 lines of helper methods.
     private void compile() throws PatternSyntaxException {
         if (pattern == null) {
             throw new NullPointerException("pattern == null");
@@ -1348,6 +1436,7 @@
     private static native long compileImpl(String regex, int flags);
     private static native long getNativeFinalizer();
     private static native int nativeSize();
+    // END Android-changed: reimplement matching logic natively via ICU.
 
     /**
      * Creates a predicate which can be used to match a string.
diff --git a/ojluni/src/main/java/java/util/stream/AbstractPipeline.java b/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
index 9bdea9c..627bb32 100644
--- a/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/AbstractPipeline.java
@@ -68,8 +68,9 @@
  * @param <E_OUT> type of output elements
  * @param <S> type of the subclass implementing {@code BaseStream}
  * @since 1.8
- * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+ * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
         extends PipelineHelper<E_OUT> implements BaseStream<E_OUT, S> {
     private static final String MSG_STREAM_LINKED = "stream has already been operated upon or closed";
@@ -242,6 +243,7 @@
      * @return a flat array-backed Node that holds the collected output elements
      */
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public final Node<E_OUT> evaluateToArrayNode(IntFunction<E_OUT[]> generator) {
         if (linkedOrConsumed)
             throw new IllegalStateException(MSG_STREAM_LINKED);
@@ -380,6 +382,7 @@
      *         intermediate operations
      * @see StreamOpFlag
      */
+    // Android-changed: Made public for CTS tests only.
     public final int getStreamFlags() {
         return StreamOpFlag.toStreamFlags(combinedFlags);
     }
@@ -501,6 +504,7 @@
     }
 
     @Override
+    // Android-changed: Made public for CTS tests only.
     public final int getStreamAndOpFlags() {
         return combinedFlags;
     }
@@ -511,6 +515,7 @@
 
     @Override
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public final <P_IN> Sink<P_IN> wrapSink(Sink<E_OUT> sink) {
         Objects.requireNonNull(sink);
 
@@ -533,6 +538,7 @@
 
     @Override
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public final <P_IN> Node<E_OUT> evaluate(Spliterator<P_IN> spliterator,
                                       boolean flatten,
                                       IntFunction<E_OUT[]> generator) {
@@ -558,6 +564,7 @@
      *
      * @return the output shape
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract StreamShape getOutputShape();
 
     /**
@@ -570,6 +577,7 @@
      * @param generator the array generator
      * @return a Node holding the output of the pipeline
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract <P_IN> Node<E_OUT> evaluateToNode(PipelineHelper<E_OUT> helper,
                                                       Spliterator<P_IN> spliterator,
                                                       boolean flattenTree,
@@ -584,6 +592,7 @@
      * @param supplier the supplier of a spliterator
      * @return a wrapping spliterator compatible with this shape
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract <P_IN> Spliterator<E_OUT> wrap(PipelineHelper<E_OUT> ph,
                                                    Supplier<Spliterator<P_IN>> supplier,
                                                    boolean isParallel);
@@ -593,6 +602,7 @@
      * spliterator when a method is invoked on the lazy spliterator.
      * @param supplier the supplier of a spliterator
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract Spliterator<E_OUT> lazySpliterator(Supplier<? extends Spliterator<E_OUT>> supplier);
 
     /**
@@ -603,6 +613,7 @@
      * @param spliterator the spliterator to pull elements from
      * @param sink the sink to push elements to
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract void forEachWithCancel(Spliterator<E_OUT> spliterator, Sink<E_OUT> sink);
 
     /**
@@ -621,6 +632,7 @@
      * @return a node builder
      */
     @Override
+    // Android-changed: Made public for CTS tests only.
     public abstract Node.Builder<E_OUT> makeNodeBuilder(long exactSizeIfKnown,
                                                         IntFunction<E_OUT[]> generator);
 
@@ -635,6 +647,7 @@
      *
      * @return {@code true} if this operation is stateful
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract boolean opIsStateful();
 
     /**
@@ -656,6 +669,7 @@
      *         each element, and passes the results (if any) to the provided
      *         {@code Sink}.
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink);
 
     /**
@@ -673,6 +687,7 @@
      * @param generator the array generator
      * @return a {@code Node} describing the result of the evaluation
      */
+    // Android-changed: Made public for CTS tests only.
     public <P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper,
                                           Spliterator<P_IN> spliterator,
                                           IntFunction<E_OUT[]> generator) {
@@ -700,6 +715,7 @@
      * @return a {@code Spliterator} describing the result of the evaluation
      */
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public <P_IN> Spliterator<E_OUT> opEvaluateParallelLazy(PipelineHelper<E_OUT> helper,
                                                      Spliterator<P_IN> spliterator) {
         return opEvaluateParallel(helper, spliterator, i -> (E_OUT[]) new Object[i]).spliterator();
diff --git a/ojluni/src/main/java/java/util/stream/BaseStream.java b/ojluni/src/main/java/java/util/stream/BaseStream.java
index b0be000..35d46e0 100644
--- a/ojluni/src/main/java/java/util/stream/BaseStream.java
+++ b/ojluni/src/main/java/java/util/stream/BaseStream.java
@@ -25,6 +25,8 @@
 package java.util.stream;
 
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Spliterator;
diff --git a/ojluni/src/main/java/java/util/stream/DistinctOps.java b/ojluni/src/main/java/java/util/stream/DistinctOps.java
index 0b7713e..22fbe05 100644
--- a/ojluni/src/main/java/java/util/stream/DistinctOps.java
+++ b/ojluni/src/main/java/java/util/stream/DistinctOps.java
@@ -65,6 +65,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
                                               Spliterator<P_IN> spliterator,
                                               IntFunction<T[]> generator) {
@@ -100,6 +101,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
                 if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {
                     // No-op
@@ -116,6 +118,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<T> opWrapSink(int flags, Sink<T> sink) {
                 Objects.requireNonNull(sink);
 
diff --git a/ojluni/src/main/java/java/util/stream/DoublePipeline.java b/ojluni/src/main/java/java/util/stream/DoublePipeline.java
index 25c19c6..e61e5de 100644
--- a/ojluni/src/main/java/java/util/stream/DoublePipeline.java
+++ b/ojluni/src/main/java/java/util/stream/DoublePipeline.java
@@ -52,6 +52,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class DoublePipeline<E_IN>
         extends AbstractPipeline<E_IN, Double, DoubleStream>
         implements DoubleStream {
@@ -128,11 +129,13 @@
     // Shape-specific methods
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final StreamShape getOutputShape() {
         return StreamShape.DOUBLE_VALUE;
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Node<Double> evaluateToNode(PipelineHelper<Double> helper,
                                              Spliterator<P_IN> spliterator,
                                              boolean flattenTree,
@@ -141,6 +144,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Spliterator<Double> wrap(PipelineHelper<Double> ph,
                                           Supplier<Spliterator<P_IN>> supplier,
                                           boolean isParallel) {
@@ -149,11 +153,13 @@
 
     @Override
     @SuppressWarnings("unchecked")
+    // Android-changed: Make public, to match the method it's overriding.
     public final Spliterator.OfDouble lazySpliterator(Supplier<? extends Spliterator<Double>> supplier) {
         return new StreamSpliterators.DelegatingSpliterator.OfDouble((Supplier<Spliterator.OfDouble>) supplier);
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final void forEachWithCancel(Spliterator<Double> spliterator, Sink<Double> sink) {
         Spliterator.OfDouble spl = adapt(spliterator);
         DoubleConsumer adaptedSink = adapt(sink);
@@ -161,6 +167,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final Node.Builder<Double> makeNodeBuilder(long exactSizeIfKnown, IntFunction<Double[]> generator) {
         return Nodes.doubleBuilder(exactSizeIfKnown);
     }
@@ -191,6 +198,7 @@
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedDouble<Double>(sink) {
                     @Override
@@ -208,6 +216,7 @@
         return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
                                                             StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<U> sink) {
                 return new Sink.ChainedDouble<U>(sink) {
                     @Override
@@ -225,6 +234,7 @@
         return new IntPipeline.StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedDouble<Integer>(sink) {
                     @Override
@@ -242,6 +252,7 @@
         return new LongPipeline.StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedDouble<Long>(sink) {
                     @Override
@@ -258,6 +269,7 @@
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedDouble<Double>(sink) {
                     @Override
@@ -284,6 +296,7 @@
             return this;
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE, StreamOpFlag.NOT_ORDERED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return sink;
             }
@@ -296,6 +309,7 @@
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                        StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedDouble<Double>(sink) {
                     @Override
@@ -319,6 +333,7 @@
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                        0) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedDouble<Double>(sink) {
                     @Override
@@ -514,8 +529,9 @@
      * Source stage of a DoubleStream
      *
      * @param <E_IN> type of elements in the upstream source
-     * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+     * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class Head<E_IN> extends DoublePipeline<E_IN> {
         /**
          * Constructor for the source stage of a DoubleStream.
@@ -526,6 +542,7 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Supplier<? extends Spliterator<Double>> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
@@ -539,17 +556,20 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Spliterator<Double> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
         }
 
         @Override
+        // Android-changed: Made public for CTS tests only.
         public final boolean opIsStateful() {
             throw new UnsupportedOperationException();
         }
 
         @Override
+        // Android-changed: Made public for CTS tests only.
         public final Sink<E_IN> opWrapSink(int flags, Sink<Double> sink) {
             throw new UnsupportedOperationException();
         }
@@ -585,6 +605,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatelessOp<E_IN> extends DoublePipeline<E_IN> {
         /**
          * Construct a new DoubleStream by appending a stateless intermediate
@@ -594,6 +615,7 @@
          * @param inputShape the stream shape for the upstream pipeline stage
          * @param opFlags operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                     StreamShape inputShape,
                     int opFlags) {
@@ -602,6 +624,7 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return false;
         }
@@ -614,6 +637,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatefulOp<E_IN> extends DoublePipeline<E_IN> {
         /**
          * Construct a new DoubleStream by appending a stateful intermediate
@@ -623,6 +647,7 @@
          * @param inputShape the stream shape for the upstream pipeline stage
          * @param opFlags operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape,
                    int opFlags) {
@@ -631,11 +656,13 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return true;
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public abstract <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
                                                         Spliterator<P_IN> spliterator,
                                                         IntFunction<Double[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/DoubleStream.java b/ojluni/src/main/java/java/util/stream/DoubleStream.java
index 347587e..4d5d23d 100644
--- a/ojluni/src/main/java/java/util/stream/DoubleStream.java
+++ b/ojluni/src/main/java/java/util/stream/DoubleStream.java
@@ -25,6 +25,8 @@
 package java.util.stream;
 
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.DoubleSummaryStatistics;
diff --git a/ojluni/src/main/java/java/util/stream/IntPipeline.java b/ojluni/src/main/java/java/util/stream/IntPipeline.java
index 60ab3b3..11f0bb7 100644
--- a/ojluni/src/main/java/java/util/stream/IntPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/IntPipeline.java
@@ -51,6 +51,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class IntPipeline<E_IN>
         extends AbstractPipeline<E_IN, Integer, IntStream>
         implements IntStream {
@@ -131,11 +132,13 @@
     // Shape-specific methods
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final StreamShape getOutputShape() {
         return StreamShape.INT_VALUE;
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Node<Integer> evaluateToNode(PipelineHelper<Integer> helper,
                                                      Spliterator<P_IN> spliterator,
                                                      boolean flattenTree,
@@ -144,6 +147,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Spliterator<Integer> wrap(PipelineHelper<Integer> ph,
                                                   Supplier<Spliterator<P_IN>> supplier,
                                                   boolean isParallel) {
@@ -152,11 +156,13 @@
 
     @Override
     @SuppressWarnings("unchecked")
+    // Android-changed: Make public, to match the method it's overriding.
     public final Spliterator.OfInt lazySpliterator(Supplier<? extends Spliterator<Integer>> supplier) {
         return new StreamSpliterators.DelegatingSpliterator.OfInt((Supplier<Spliterator.OfInt>) supplier);
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final void forEachWithCancel(Spliterator<Integer> spliterator, Sink<Integer> sink) {
         Spliterator.OfInt spl = adapt(spliterator);
         IntConsumer adaptedSink = adapt(sink);
@@ -164,6 +170,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final Node.Builder<Integer> makeNodeBuilder(long exactSizeIfKnown,
                                                        IntFunction<Integer[]> generator) {
         return Nodes.intBuilder(exactSizeIfKnown);
@@ -205,6 +212,7 @@
         return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedInt<Double>(sink) {
                     @Override
@@ -227,6 +235,7 @@
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedInt<Integer>(sink) {
                     @Override
@@ -244,6 +253,7 @@
         return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE,
                                                              StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
                 return new Sink.ChainedInt<U>(sink) {
                     @Override
@@ -261,6 +271,7 @@
         return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedInt<Long>(sink) {
                     @Override
@@ -278,6 +289,7 @@
         return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedInt<Double>(sink) {
                     @Override
@@ -294,6 +306,7 @@
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedInt<Integer>(sink) {
                     @Override
@@ -320,6 +333,7 @@
             return this;
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, StreamOpFlag.NOT_ORDERED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return sink;
             }
@@ -332,6 +346,7 @@
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                         StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedInt<Integer>(sink) {
                     @Override
@@ -355,6 +370,7 @@
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                         0) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedInt<Integer>(sink) {
                     @Override
@@ -513,6 +529,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class Head<E_IN> extends IntPipeline<E_IN> {
         /**
          * Constructor for the source stage of an IntStream.
@@ -523,6 +540,7 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Supplier<? extends Spliterator<Integer>> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
@@ -536,17 +554,20 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Spliterator<Integer> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             throw new UnsupportedOperationException();
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final Sink<E_IN> opWrapSink(int flags, Sink<Integer> sink) {
             throw new UnsupportedOperationException();
         }
@@ -581,6 +602,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatelessOp<E_IN> extends IntPipeline<E_IN> {
         /**
          * Construct a new IntStream by appending a stateless intermediate
@@ -589,6 +611,7 @@
          * @param inputShape The stream shape for the upstream pipeline stage
          * @param opFlags Operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                     StreamShape inputShape,
                     int opFlags) {
@@ -597,6 +620,7 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return false;
         }
@@ -609,6 +633,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatefulOp<E_IN> extends IntPipeline<E_IN> {
         /**
          * Construct a new IntStream by appending a stateful intermediate
@@ -617,6 +642,7 @@
          * @param inputShape The stream shape for the upstream pipeline stage
          * @param opFlags Operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape,
                    int opFlags) {
@@ -625,11 +651,13 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return true;
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public abstract <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
                                                          Spliterator<P_IN> spliterator,
                                                          IntFunction<Integer[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/LongPipeline.java b/ojluni/src/main/java/java/util/stream/LongPipeline.java
index e7f6a5ad..768a378 100644
--- a/ojluni/src/main/java/java/util/stream/LongPipeline.java
+++ b/ojluni/src/main/java/java/util/stream/LongPipeline.java
@@ -52,6 +52,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class LongPipeline<E_IN>
         extends AbstractPipeline<E_IN, Long, LongStream>
         implements LongStream {
@@ -129,11 +130,13 @@
     // Shape-specific methods
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final StreamShape getOutputShape() {
         return StreamShape.LONG_VALUE;
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Node<Long> evaluateToNode(PipelineHelper<Long> helper,
                                            Spliterator<P_IN> spliterator,
                                            boolean flattenTree,
@@ -142,6 +145,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Spliterator<Long> wrap(PipelineHelper<Long> ph,
                                         Supplier<Spliterator<P_IN>> supplier,
                                         boolean isParallel) {
@@ -150,11 +154,13 @@
 
     @Override
     @SuppressWarnings("unchecked")
+    // Android-changed: Make public, to match the method it's overriding.
     public final Spliterator.OfLong lazySpliterator(Supplier<? extends Spliterator<Long>> supplier) {
         return new StreamSpliterators.DelegatingSpliterator.OfLong((Supplier<Spliterator.OfLong>) supplier);
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final void forEachWithCancel(Spliterator<Long> spliterator, Sink<Long> sink) {
         Spliterator.OfLong spl = adapt(spliterator);
         LongConsumer adaptedSink =  adapt(sink);
@@ -162,6 +168,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final Node.Builder<Long> makeNodeBuilder(long exactSizeIfKnown, IntFunction<Long[]> generator) {
         return Nodes.longBuilder(exactSizeIfKnown);
     }
@@ -186,6 +193,7 @@
         return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedLong<Double>(sink) {
                     @Override
@@ -208,6 +216,7 @@
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedLong<Long>(sink) {
                     @Override
@@ -225,6 +234,7 @@
         return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE,
                                                           StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<U> sink) {
                 return new Sink.ChainedLong<U>(sink) {
                     @Override
@@ -242,6 +252,7 @@
         return new IntPipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                                  StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedLong<Integer>(sink) {
                     @Override
@@ -259,6 +270,7 @@
         return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedLong<Double>(sink) {
                     @Override
@@ -275,6 +287,7 @@
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedLong<Long>(sink) {
                     @Override
@@ -301,6 +314,7 @@
             return this;
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_ORDERED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return sink;
             }
@@ -313,6 +327,7 @@
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                      StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedLong<Long>(sink) {
                     @Override
@@ -336,6 +351,7 @@
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                      0) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedLong<Long>(sink) {
                     @Override
@@ -494,8 +510,9 @@
      *
      * @param <E_IN> type of elements in the upstream source
      * @since 1.8
-     * @hide Visibility for CTS only (OpenJDK 8 streams tests).
+     * @hide Made public for CTS tests only (OpenJDK 8 streams tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class Head<E_IN> extends LongPipeline<E_IN> {
         /**
          * Constructor for the source stage of a LongStream.
@@ -506,6 +523,7 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Supplier<? extends Spliterator<Long>> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
@@ -519,17 +537,20 @@
          *                    in {@link StreamOpFlag}
          * @param parallel {@code true} if the pipeline is parallel
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Spliterator<Long> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             throw new UnsupportedOperationException();
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final Sink<E_IN> opWrapSink(int flags, Sink<Long> sink) {
             throw new UnsupportedOperationException();
         }
@@ -561,6 +582,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatelessOp<E_IN> extends LongPipeline<E_IN> {
         /**
          * Construct a new LongStream by appending a stateless intermediate
@@ -569,6 +591,7 @@
          * @param inputShape The stream shape for the upstream pipeline stage
          * @param opFlags Operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                     StreamShape inputShape,
                     int opFlags) {
@@ -577,6 +600,7 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return false;
         }
@@ -589,6 +613,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatefulOp<E_IN> extends LongPipeline<E_IN> {
         /**
          * Construct a new LongStream by appending a stateful intermediate
@@ -598,6 +623,7 @@
          * @param opFlags Operation flags for the new stage
          * @hide Visible for CTS testing only (OpenJDK8 tests).
          */
+        // Android-changed: Made public for CTS tests only.
         public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape,
                    int opFlags) {
@@ -606,11 +632,13 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return true;
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public abstract <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
                                                       Spliterator<P_IN> spliterator,
                                                       IntFunction<Long[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/LongStream.java b/ojluni/src/main/java/java/util/stream/LongStream.java
index 84189ef..a2d429e 100644
--- a/ojluni/src/main/java/java/util/stream/LongStream.java
+++ b/ojluni/src/main/java/java/util/stream/LongStream.java
@@ -24,8 +24,9 @@
  */
 package java.util.stream;
 
-import java.math.BigInteger;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.LongSummaryStatistics;
@@ -791,11 +792,7 @@
             // Split the range in two and concatenate
             // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE) then
             // the lower range, [Long.MIN_VALUE, 0) will be further split in two
-            // Android-changed: no divideUnsigned support yet, use BigInteger instead.
-            long m = startInclusive +
-                BigInteger.valueOf(endExclusive).subtract(BigInteger.valueOf(startInclusive))
-                     .divide(BigInteger.valueOf(2)).longValue() + 1;
-
+            long m = startInclusive + Long.divideUnsigned(endExclusive - startInclusive, 2) + 1;
             return concat(range(startInclusive, m), range(m, endExclusive));
         } else {
             return StreamSupport.longStream(
@@ -829,11 +826,7 @@
             // Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then
             // the lower range, [Long.MIN_VALUE, 0), and upper range,
             // [0, Long.MAX_VALUE], will both be further split in two
-            // Android-changed: no divideUnsigned support yet, use BigInteger instead.
-            long m = startInclusive +
-                BigInteger.valueOf(endInclusive).subtract(BigInteger.valueOf(startInclusive))
-                     .divide(BigInteger.valueOf(2)).longValue() + 1;
-
+            long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
             return concat(range(startInclusive, m), rangeClosed(m, endInclusive));
         } else {
             return StreamSupport.longStream(
diff --git a/ojluni/src/main/java/java/util/stream/Node.java b/ojluni/src/main/java/java/util/stream/Node.java
index 4a72ca4..e20de78 100644
--- a/ojluni/src/main/java/java/util/stream/Node.java
+++ b/ojluni/src/main/java/java/util/stream/Node.java
@@ -58,6 +58,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public interface Node<T> {
 
     /**
diff --git a/ojluni/src/main/java/java/util/stream/PipelineHelper.java b/ojluni/src/main/java/java/util/stream/PipelineHelper.java
index 06a4f92..832d68a 100644
--- a/ojluni/src/main/java/java/util/stream/PipelineHelper.java
+++ b/ojluni/src/main/java/java/util/stream/PipelineHelper.java
@@ -53,6 +53,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class PipelineHelper<P_OUT> {
 
     /**
@@ -70,6 +71,7 @@
      * @return the combined stream and operation flags
      * @see StreamOpFlag
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract int getStreamAndOpFlags();
 
     /**
@@ -151,6 +153,7 @@
      * @return a {@code Sink} that implements the pipeline stages and sends
      *         results to the provided {@code Sink}
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract<P_IN> Sink<P_IN> wrapSink(Sink<P_OUT> sink);
 
     /**
@@ -198,6 +201,7 @@
      * @param generator a factory function for array instances
      * @return the {@code Node} containing all output elements
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract<P_IN> Node<P_OUT> evaluate(Spliterator<P_IN> spliterator,
                                         boolean flatten,
                                         IntFunction<P_OUT[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/ReferencePipeline.java b/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
index ddec43e..84ec8c5 100644
--- a/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
+++ b/ojluni/src/main/java/java/util/stream/ReferencePipeline.java
@@ -55,6 +55,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public abstract class ReferencePipeline<P_IN, P_OUT>
         extends AbstractPipeline<P_IN, P_OUT, Stream<P_OUT>>
         implements Stream<P_OUT>  {
@@ -98,11 +99,13 @@
     // Shape-specific methods
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final StreamShape getOutputShape() {
         return StreamShape.REFERENCE;
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Node<P_OUT> evaluateToNode(PipelineHelper<P_OUT> helper,
                                         Spliterator<P_IN> spliterator,
                                         boolean flattenTree,
@@ -111,6 +114,7 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final <P_IN> Spliterator<P_OUT> wrap(PipelineHelper<P_OUT> ph,
                                      Supplier<Spliterator<P_IN>> supplier,
                                      boolean isParallel) {
@@ -118,16 +122,19 @@
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final Spliterator<P_OUT> lazySpliterator(Supplier<? extends Spliterator<P_OUT>> supplier) {
         return new StreamSpliterators.DelegatingSpliterator<>(supplier);
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final void forEachWithCancel(Spliterator<P_OUT> spliterator, Sink<P_OUT> sink) {
         do { } while (!sink.cancellationRequested() && spliterator.tryAdvance(sink));
     }
 
     @Override
+    // Android-changed: Make public, to match the method it's overriding.
     public final Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown, IntFunction<P_OUT[]> generator) {
         return Nodes.builder(exactSizeIfKnown, generator);
     }
@@ -151,6 +158,7 @@
             return this;
         return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_ORDERED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                 return sink;
             }
@@ -163,6 +171,7 @@
         return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                      StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                 return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                     @Override
@@ -204,6 +213,7 @@
         return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                               StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedReference<P_OUT, Integer>(sink) {
                     @Override
@@ -221,6 +231,7 @@
         return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                       StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedReference<P_OUT, Long>(sink) {
                     @Override
@@ -238,6 +249,7 @@
         return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedReference<P_OUT, Double>(sink) {
                     @Override
@@ -283,6 +295,7 @@
         return new IntPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                               StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedReference<P_OUT, Integer>(sink) {
                     IntConsumer downstreamAsInt = downstream::accept;
@@ -311,6 +324,7 @@
         return new DoublePipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedReference<P_OUT, Double>(sink) {
                     DoubleConsumer downstreamAsDouble = downstream::accept;
@@ -339,6 +353,7 @@
         return new LongPipeline.StatelessOp<P_OUT>(this, StreamShape.REFERENCE,
                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedReference<P_OUT, Long>(sink) {
                     LongConsumer downstreamAsLong = downstream::accept;
@@ -366,6 +381,7 @@
         return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                      0) {
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                 return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                     @Override
@@ -436,7 +452,7 @@
         // super type of U an ArrayStoreException will be thrown.
         @SuppressWarnings("rawtypes")
         IntFunction rawGenerator = (IntFunction) generator;
-        // TODO(b/29399275): Eclipse compiler requires explicit (Node<A[]>) cast below.
+        // Android-changed: Eclipse compiler requires explicit (Node<A[]>) cast (b/29399275).
         return (A[]) Nodes.flatten((Node<A[]>) evaluateToArrayNode(rawGenerator), rawGenerator)
                 .asArray(rawGenerator);
     }
@@ -539,6 +555,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> {
         /**
          * Constructor for the source stage of a Stream.
@@ -548,6 +565,7 @@
          * @param sourceFlags the source flags for the stream source, described
          *                    in {@link StreamOpFlag}
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Supplier<? extends Spliterator<?>> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
@@ -560,17 +578,20 @@
          * @param sourceFlags the source flags for the stream source, described
          *                    in {@link StreamOpFlag}
          */
+        // Android-changed: Made public for CTS tests only.
         public Head(Spliterator<?> source,
              int sourceFlags, boolean parallel) {
             super(source, sourceFlags, parallel);
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             throw new UnsupportedOperationException();
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink) {
             throw new UnsupportedOperationException();
         }
@@ -606,6 +627,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatelessOp<E_IN, E_OUT>
             extends ReferencePipeline<E_IN, E_OUT> {
         /**
@@ -616,6 +638,7 @@
          * @param inputShape The stream shape for the upstream pipeline stage
          * @param opFlags Operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                     StreamShape inputShape,
                     int opFlags) {
@@ -624,6 +647,7 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return false;
         }
@@ -637,6 +661,7 @@
      * @since 1.8
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public abstract static class StatefulOp<E_IN, E_OUT>
             extends ReferencePipeline<E_IN, E_OUT> {
         /**
@@ -646,6 +671,7 @@
          * @param inputShape The stream shape for the upstream pipeline stage
          * @param opFlags Operation flags for the new stage
          */
+        // Android-changed: Made public for CTS tests only.
         public StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape,
                    int opFlags) {
@@ -654,11 +680,13 @@
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public final boolean opIsStateful() {
             return true;
         }
 
         @Override
+        // Android-changed: Make public, to match the method it's overriding.
         public abstract <P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper,
                                                        Spliterator<P_IN> spliterator,
                                                        IntFunction<E_OUT[]> generator);
diff --git a/ojluni/src/main/java/java/util/stream/Sink.java b/ojluni/src/main/java/java/util/stream/Sink.java
index 032fd45..2c5609c 100644
--- a/ojluni/src/main/java/java/util/stream/Sink.java
+++ b/ojluni/src/main/java/java/util/stream/Sink.java
@@ -115,6 +115,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public interface Sink<T> extends Consumer<T> {
     /**
      * Resets the sink state to receive a fresh data set.  This must be called
diff --git a/ojluni/src/main/java/java/util/stream/SliceOps.java b/ojluni/src/main/java/java/util/stream/SliceOps.java
index 3042197..6a6f85e 100644
--- a/ojluni/src/main/java/java/util/stream/SliceOps.java
+++ b/ojluni/src/main/java/java/util/stream/SliceOps.java
@@ -130,6 +130,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
                 long size = helper.exactOutputSizeIfKnown(spliterator);
                 if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
@@ -157,6 +158,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
                                               Spliterator<P_IN> spliterator,
                                               IntFunction<T[]> generator) {
@@ -186,6 +188,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<T> opWrapSink(int flags, Sink<T> sink) {
                 return new Sink.ChainedReference<T, T>(sink) {
                     long n = skip;
@@ -246,6 +249,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
                                                                Spliterator<P_IN> spliterator) {
                 long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -266,6 +270,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
                                                     Spliterator<P_IN> spliterator,
                                                     IntFunction<Integer[]> generator) {
@@ -295,6 +300,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
                 return new Sink.ChainedInt<Integer>(sink) {
                     long n = skip;
@@ -355,6 +361,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
                                                             Spliterator<P_IN> spliterator) {
                 long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -375,6 +382,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
                                                  Spliterator<P_IN> spliterator,
                                                  IntFunction<Long[]> generator) {
@@ -404,6 +412,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedLong<Long>(sink) {
                     long n = skip;
@@ -464,6 +473,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
                                                               Spliterator<P_IN> spliterator) {
                 long size = helper.exactOutputSizeIfKnown(spliterator);
@@ -484,6 +494,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
                                                    Spliterator<P_IN> spliterator,
                                                    IntFunction<Double[]> generator) {
@@ -513,6 +524,7 @@
             }
 
             @Override
+            // Android-changed: Make public, to match the method it's overriding.
             public Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedDouble<Double>(sink) {
                     long n = skip;
diff --git a/ojluni/src/main/java/java/util/stream/SpinedBuffer.java b/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
index c91c4ff..d21518a 100644
--- a/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
+++ b/ojluni/src/main/java/java/util/stream/SpinedBuffer.java
@@ -54,6 +54,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public class SpinedBuffer<E>
         extends AbstractSpinedBuffer
         implements Consumer<E>, Iterable<E> {
@@ -94,6 +95,7 @@
      *         is negative
      */
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public SpinedBuffer(int initialCapacity) {
         super(initialCapacity);
         curChunk = (E[]) new Object[1 << initialChunkPower];
@@ -103,6 +105,7 @@
      * Constructs an empty list with an initial capacity of sixteen.
      */
     @SuppressWarnings("unchecked")
+    // Android-changed: Made public for CTS tests only.
     public SpinedBuffer() {
         super();
         curChunk = (E[]) new Object[1 << initialChunkPower];
@@ -415,9 +418,8 @@
      * @param <E> the wrapper type for this primitive type
      * @param <T_ARR> the array type for this primitive type
      * @param <T_CONS> the Consumer type for this primitive type
-     * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
-    public abstract static class OfPrimitive<E, T_ARR, T_CONS>
+    abstract static class OfPrimitive<E, T_ARR, T_CONS>
             extends AbstractSpinedBuffer implements Iterable<E> {
 
         /*
@@ -723,10 +725,13 @@
      * An ordered collection of {@code int} values.
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class OfInt extends SpinedBuffer.OfPrimitive<Integer, int[], IntConsumer>
             implements IntConsumer {
+        // Android-changed: Made public for CTS tests only.
         public OfInt() { }
 
+        // Android-changed: Made public for CTS tests only.
         public OfInt(int initialCapacity) {
             super(initialCapacity);
         }
@@ -837,10 +842,13 @@
      * An ordered collection of {@code long} values.
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class OfLong extends SpinedBuffer.OfPrimitive<Long, long[], LongConsumer>
             implements LongConsumer {
+        // Android-changed: Made public for CTS tests only.
         public OfLong() { }
 
+        // Android-changed: Made public for CTS tests only.
         public OfLong(int initialCapacity) {
             super(initialCapacity);
         }
@@ -952,11 +960,14 @@
      * An ordered collection of {@code double} values.
      * @hide Visible for CTS testing only (OpenJDK8 tests).
      */
+    // Android-changed: Made public for CTS tests only.
     public static class OfDouble
             extends SpinedBuffer.OfPrimitive<Double, double[], DoubleConsumer>
             implements DoubleConsumer {
+        // Android-changed: Made public for CTS tests only.
         public OfDouble() { }
 
+        // Android-changed: Made public for CTS tests only.
         public OfDouble(int initialCapacity) {
             super(initialCapacity);
         }
diff --git a/ojluni/src/main/java/java/util/stream/Stream.java b/ojluni/src/main/java/java/util/stream/Stream.java
index d4cb9ff..c35fc05 100644
--- a/ojluni/src/main/java/java/util/stream/Stream.java
+++ b/ojluni/src/main/java/java/util/stream/Stream.java
@@ -25,6 +25,8 @@
 package java.util.stream;
 
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
@@ -126,7 +128,8 @@
  *
  * <p>Streams have a {@link #close()} method and implement {@link AutoCloseable},
  * but nearly all stream instances do not actually need to be closed after use.
- * Generally, only streams whose source is an IO channel will require closing.  Most streams
+ * Generally, only streams whose source is an IO channel (such as those returned
+ * by {@link Files#lines(Path, Charset)}) will require closing.  Most streams
  * are backed by collections, arrays, or generating functions, which require no
  * special resource management.  (If a stream does require closing, it can be
  * declared as a resource in a {@code try}-with-resources statement.)
diff --git a/ojluni/src/main/java/java/util/stream/StreamOpFlag.java b/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
index 3477a33..83a3660 100644
--- a/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
+++ b/ojluni/src/main/java/java/util/stream/StreamOpFlag.java
@@ -202,6 +202,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public enum StreamOpFlag {
 
     /*
@@ -458,6 +459,7 @@
      *
      * @return the bitmap for setting this characteristic
      */
+    // Android-changed: Made public for CTS tests only.
     public int set() {
         return set;
     }
@@ -467,6 +469,7 @@
      *
      * @return the bitmap for clearing this characteristic
      */
+    // Android-changed: Made public for CTS tests only.
     public int clear() {
         return clear;
     }
@@ -476,6 +479,7 @@
      *
      * @return true if a stream-based flag, otherwise false.
      */
+    // Android-changed: Made public for CTS tests only.
     public boolean isStreamFlag() {
         return maskTable.get(Type.STREAM) > 0;
     }
@@ -488,6 +492,7 @@
      *        operation flags
      * @return true if this flag is known, otherwise false.
      */
+    // Android-changed: Made public for CTS tests only.
     public boolean isKnown(int flags) {
         return (flags & preserve) == set;
     }
@@ -499,6 +504,7 @@
      * @param flags the operation flags or combined stream and operations flags.
      * @return true if this flag is preserved, otherwise false.
      */
+    // Android-changed: Made public for CTS tests only.
     public boolean isCleared(int flags) {
         return (flags & preserve) == clear;
     }
@@ -509,6 +515,7 @@
      * @param flags the combined stream and operations flags.
      * @return true if this flag is preserved, otherwise false.
      */
+    // Android-changed: Made public for CTS tests only.
     public boolean isPreserved(int flags) {
         return (flags & preserve) == preserve;
     }
@@ -519,6 +526,7 @@
      * @param t the flag type.
      * @return true if this flag can be set for the flag type, otherwise false.
      */
+    // Android-changed: Made public for CTS tests only.
     public boolean canSet(Type t) {
         return (maskTable.get(t) & SET_BITS) > 0;
     }
@@ -526,26 +534,31 @@
     /**
      * The bit mask for spliterator characteristics
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int SPLITERATOR_CHARACTERISTICS_MASK = createMask(Type.SPLITERATOR);
 
     /**
      * The bit mask for source stream flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int STREAM_MASK = createMask(Type.STREAM);
 
     /**
      * The bit mask for intermediate operation flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int OP_MASK = createMask(Type.OP);
 
     /**
      * The bit mask for terminal operation flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int TERMINAL_OP_MASK = createMask(Type.TERMINAL_OP);
 
     /**
      * The bit mask for upstream terminal operation flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int UPSTREAM_TERMINAL_OP_MASK = createMask(Type.UPSTREAM_TERMINAL_OP);
 
     private static int createMask(Type t) {
@@ -583,51 +596,61 @@
      * The initial value to be combined with the stream flags of the first
      * stream in the pipeline.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int INITIAL_OPS_VALUE = FLAG_MASK_IS | FLAG_MASK_NOT;
 
     /**
      * The bit value to set or inject {@link #DISTINCT}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int IS_DISTINCT = DISTINCT.set;
 
     /**
      * The bit value to clear {@link #DISTINCT}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int NOT_DISTINCT = DISTINCT.clear;
 
     /**
      * The bit value to set or inject {@link #SORTED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int IS_SORTED = SORTED.set;
 
     /**
      * The bit value to clear {@link #SORTED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int NOT_SORTED = SORTED.clear;
 
     /**
      * The bit value to set or inject {@link #ORDERED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int IS_ORDERED = ORDERED.set;
 
     /**
      * The bit value to clear {@link #ORDERED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int NOT_ORDERED = ORDERED.clear;
 
     /**
      * The bit value to set {@link #SIZED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int IS_SIZED = SIZED.set;
 
     /**
      * The bit value to clear {@link #SIZED}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int NOT_SIZED = SIZED.clear;
 
     /**
      * The bit value to inject {@link #SHORT_CIRCUIT}.
      */
+    // Android-changed: Made public for CTS tests only.
     public static final int IS_SHORT_CIRCUIT = SHORT_CIRCUIT.set;
 
     private static int getMask(int flags) {
@@ -684,6 +707,7 @@
      *        The value {#link INITIAL_OPS_VALUE} must be used as the seed value.
      * @return the updated combined stream and operation flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static int combineOpFlags(int newStreamOrOpFlags, int prevCombOpFlags) {
         // 0x01 or 0x10 nibbles are transformed to 0x11
         // 0x00 nibbles remain unchanged
@@ -701,6 +725,7 @@
      * @param combOpFlags the combined stream and operation flags.
      * @return the stream flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static int toStreamFlags(int combOpFlags) {
         // By flipping the nibbles 0x11 become 0x00 and 0x01 become 0x10
         // Shift left 1 to restore set flags and mask off anything other than the set flags
@@ -713,6 +738,7 @@
      * @param streamFlags the stream flags.
      * @return the spliterator characteristic bit set.
      */
+    // Android-changed: Made public for CTS tests only.
     public static int toCharacteristics(int streamFlags) {
         return streamFlags & SPLITERATOR_CHARACTERISTICS_MASK;
     }
@@ -730,6 +756,7 @@
      *        bit set.
      * @return the stream flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static int fromCharacteristics(Spliterator<?> spliterator) {
         int characteristics = spliterator.characteristics();
         if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) {
@@ -748,6 +775,7 @@
      * @param characteristics the spliterator characteristic bit set.
      * @return the stream flags.
      */
+    // Android-changed: Made public for CTS tests only.
     public static int fromCharacteristics(int characteristics) {
         return characteristics & SPLITERATOR_CHARACTERISTICS_MASK;
     }
diff --git a/ojluni/src/main/java/java/util/stream/StreamShape.java b/ojluni/src/main/java/java/util/stream/StreamShape.java
index 2c5f83b..5bcae4a 100644
--- a/ojluni/src/main/java/java/util/stream/StreamShape.java
+++ b/ojluni/src/main/java/java/util/stream/StreamShape.java
@@ -47,6 +47,7 @@
  * @since 1.8
  * @hide Visible for CTS testing only (OpenJDK8 tests).
  */
+// Android-changed: Made public for CTS tests only.
 public enum StreamShape {
     /**
      * The shape specialization corresponding to {@code Stream} and elements
diff --git a/ojluni/src/main/java/java/util/stream/package-info.java b/ojluni/src/main/java/java/util/stream/package-info.java
index 17b070a..016c86d 100644
--- a/ojluni/src/main/java/java/util/stream/package-info.java
+++ b/ojluni/src/main/java/java/util/stream/package-info.java
@@ -82,7 +82,13 @@
  *     {@link java.util.stream.Stream#of(Object[])},
  *     {@link java.util.stream.IntStream#range(int, int)}
  *     or {@link java.util.stream.Stream#iterate(Object, UnaryOperator)};</li>
- *     </li>
+ *     <li>The lines of a file can be obtained from {@link java.io.BufferedReader#lines()};</li>
+ *     <li>Streams of file paths can be obtained from methods in {@link java.nio.file.Files};</li>
+ *     <li>Streams of random numbers can be obtained from {@link java.util.Random#ints()};</li>
+ *     <li>Numerous other stream-bearing methods in the JDK, including
+ *     {@link java.util.BitSet#stream()},
+ *     {@link java.util.regex.Pattern#splitAsStream(java.lang.CharSequence)},
+ *     and {@link java.util.jar.JarFile#stream()}.</li>
  * </ul>
  *
  * <p>Additional stream sources can be provided by third-party libraries using
diff --git a/ojluni/src/main/java/java/util/zip/Deflater.java b/ojluni/src/main/java/java/util/zip/Deflater.java
index 578bd56..5c7dffd 100644
--- a/ojluni/src/main/java/java/util/zip/Deflater.java
+++ b/ojluni/src/main/java/java/util/zip/Deflater.java
@@ -79,7 +79,7 @@
     // Android-added: @ReachabilitySensitive
     // Finalization clears zsRef, and thus can't be allowed to occur early.
     // Unlike some other CloseGuard uses, the spec allows clients to rely on finalization
-    // here.  Thus dropping a deflater without calling close() should work correctly.
+    // here.  Thus dropping a deflater without calling end() should work correctly.
     // It thus does not suffice to just rely on the CloseGuard annotation.
     @ReachabilitySensitive
     private final ZStreamRef zsRef;
@@ -91,7 +91,7 @@
     private long bytesRead;
     private long bytesWritten;
 
-    // Android-changed: added close guard
+    // Android-added: CloseGuard support.
     @ReachabilitySensitive
     private final CloseGuard guard = CloseGuard.get();
 
@@ -165,6 +165,14 @@
      */
     public static final int FULL_FLUSH = 3;
 
+    // Android-removed: initIDs handled in register method.
+    /*
+    static {
+        /* Zip library is loaded from System.initializeSystemClass *
+        initIDs();
+    }
+    */
+
     /**
      * Creates a new compressor using the specified compression level.
      * If 'nowrap' is true then the ZLIB header and checksum fields will
@@ -177,7 +185,7 @@
         this.level = level;
         this.strategy = DEFAULT_STRATEGY;
         this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
-        // Android-changed: added close guard
+        // Android-added: CloseGuard support.
         guard.open("end");
     }
 
@@ -547,7 +555,7 @@
      */
     public void end() {
         synchronized (zsRef) {
-            // Android-changed: added close guard
+            // Android-added: CloseGuard support.
             guard.close();
             long addr = zsRef.address();
             zsRef.clear();
@@ -562,7 +570,7 @@
      * Closes the compressor when garbage is collected.
      */
     protected void finalize() {
-        // Android-changed: added close guard
+        // Android-added: CloseGuard support.
         if (guard != null) {
             guard.warnIfOpen();
         }
diff --git a/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java b/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
index 26c5b19..c3f7802 100644
--- a/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/DeflaterInputStream.java
@@ -201,14 +201,23 @@
             off += n;
             len -= n;
         }
-        // Android-changed: set reachEOF eagerly (not just when the number of bytes is zero).
-        // so that available is more accurate.
+        // BEGIN Android-changed: Return more accurate value from available().
+        // Set reachEOF eagerly when the Deflater has finished, and not just when the number of
+        // bytes is zero so that available is more accurate.
+        // See http://b/111589691
+        /*
+        if (cnt == 0 && def.finished()) {
+            reachEOF = true;
+            cnt = -1;
+        }
+        */
         if (def.finished()) {
-            reachEOF =true;
+            reachEOF = true;
             if (cnt == 0) {
                 cnt = -1;
             }
         }
+        // END Android-changed: Return more accurate value from available().
 
         return cnt;
     }
diff --git a/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java b/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
index 7b7d113..7821737 100644
--- a/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
+++ b/ojluni/src/main/java/java/util/zip/DeflaterOutputStream.java
@@ -249,7 +249,12 @@
      * @throws IOException if an I/O error has occurred
      */
     protected void deflate() throws IOException {
-        // Android-changed: output all available compressed data (b/4005091)
+        // Android-changed: Output all available compressed data (b/4005091).
+        // See http://b/111496419 for more details.
+        // int len = def.deflate(buf, 0, buf.length);
+        // if (len > 0) {
+        //     out.write(buf, 0, len);
+        // }
         int len = 0;
         while ((len = def.deflate(buf, 0, buf.length)) > 0) {
           out.write(buf, 0, len);
diff --git a/ojluni/src/main/java/java/util/zip/GZIPInputStream.java b/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
index 915d446..109454c 100644
--- a/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/GZIPInputStream.java
@@ -75,9 +75,17 @@
      */
     public GZIPInputStream(InputStream in, int size) throws IOException {
         super(in, new Inflater(true), size);
-        // Android-changed: Unconditionally close external inflaters (b/26462400)
+        // Android-removed: Unconditionally close external inflaters (b/26462400)
         // usesDefaultInflater = true;
-        readHeader(in);
+        // BEGIN Android-changed: Do not rely on finalization to inf.end().
+        // readHeader(in);
+        try {
+            readHeader(in);
+        } catch (Exception e) {
+            inf.end();
+            throw e;
+        }
+        // END Android-changed: Do not rely on finalization to inf.end().
     }
 
     /**
diff --git a/ojluni/src/main/java/java/util/zip/Inflater.java b/ojluni/src/main/java/java/util/zip/Inflater.java
index 8a1ba6f..eb8754e 100644
--- a/ojluni/src/main/java/java/util/zip/Inflater.java
+++ b/ojluni/src/main/java/java/util/zip/Inflater.java
@@ -80,7 +80,7 @@
     // Android-added: @ReachabilitySensitive
     // Finalization clears zsRef, and thus can't be allowed to occur early.
     // Unlike some other CloseGuard uses, the spec allows clients to rely on finalization
-    // here.  Thus dropping a deflater without calling close() should work correctly.
+    // here.  Thus dropping a deflater without calling end() should work correctly.
     // It thus does not suffice to just rely on the CloseGuard annotation.
     @ReachabilitySensitive
     private final ZStreamRef zsRef;
@@ -91,12 +91,20 @@
     private long bytesRead;
     private long bytesWritten;
 
-    // Android-changed: added CloseGuard instance
+    // Android-added: CloseGuard support.
     @ReachabilitySensitive
     private final CloseGuard guard = CloseGuard.get();
 
     private static final byte[] defaultBuf = new byte[0];
 
+    // Android-removed: initIDs handled in register method.
+    /*
+    static {
+        /* Zip library is loaded from System.initializeSystemClass *
+        initIDs();
+    }
+    */
+
     /**
      * Creates a new decompressor. If the parameter 'nowrap' is true then
      * the ZLIB header and checksum fields will not be used. This provides
@@ -110,7 +118,7 @@
      */
     public Inflater(boolean nowrap) {
         zsRef = new ZStreamRef(init(nowrap));
-        // Android-changed: added close guard
+        // Android-added: CloseGuard support.
         guard.open("end");
     }
 
@@ -378,6 +386,7 @@
      */
     public void end() {
         synchronized (zsRef) {
+            // Android-added: CloseGuard support.
             guard.close();
 
             long addr = zsRef.address();
@@ -393,7 +402,7 @@
      * Closes the decompressor when garbage is collected.
      */
     protected void finalize() {
-        // Android-changed: added close guard
+        // Android-added: CloseGuard support.
         if (guard != null) {
             guard.warnIfOpen();
         }
@@ -403,9 +412,8 @@
 
     private void ensureOpen () {
         assert Thread.holdsLock(zsRef);
-        // Android-changed: Throw IllegalStateException instead of a NullPointerException.
         if (zsRef.address() == 0)
-            throw new IllegalStateException("Inflater has been closed");
+            throw new NullPointerException("Inflater has been closed");
     }
 
     boolean ended() {
diff --git a/ojluni/src/main/java/java/util/zip/InflaterInputStream.java b/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
index 0ae662e..b65adbe 100644
--- a/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/InflaterInputStream.java
@@ -56,7 +56,20 @@
      */
     protected int len;
 
-    // Android-changed: closed is now protected.
+    // Android-changed: Make closed accessible to subclasses.
+    // This was made protected because it needed to be accessed by
+    // StrictJarFile.ZipInflaterInputStream. Unfortunately, it was not marked as @hide and so it
+    // inadvertently became part of the public API. It will be marked as @removed to remove it from
+    // the public API in a future release of Android. See http://b/111592689 for more information.
+    // private boolean closed = false;
+    /**
+     * Indicates whether the {@link #close()} method has been called, internal use only.
+     *
+     * @deprecated This field will be removed from a future version of Android and should not be
+     * used. Subclasses that access this field need to be modified to keep track of their own
+     * closed state by overriding close().
+     */
+    @Deprecated
     protected boolean closed = false;
 
     // this flag is set to true after EOF has reached
@@ -102,6 +115,7 @@
     }
 
     // Android-changed: Unconditionally close external inflaters (b/26462400)
+    // See http://b/111630946 for more details.
     // boolean usesDefaultInflater = false;
 
     /**
@@ -163,12 +177,6 @@
                     fill();
                 }
             }
-
-            // Android-changed: Eagerly set reachEOF.
-            if (inf.finished()) {
-                reachEOF = true;
-            }
-
             return n;
         } catch (DataFormatException e) {
             String s = e.getMessage();
@@ -190,6 +198,14 @@
         ensureOpen();
         if (reachEOF) {
             return 0;
+        // BEGIN Android-added: Return more accurate value from available().
+        // Integrates change http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/dbcf47bfb044 made as part
+        // of https://bugs.openjdk.java.net/browse/JDK-7031075.
+        } else if (inf.finished()) {
+            // the end of the compressed data stream has been reached
+            reachEOF = true;
+            return 0;
+        // END Android-added: Return more accurate value from available().
         } else {
             return 1;
         }
diff --git a/ojluni/src/main/java/java/util/zip/ZipEntry.java b/ojluni/src/main/java/java/util/zip/ZipEntry.java
index 57433e0..0de6756 100644
--- a/ojluni/src/main/java/java/util/zip/ZipEntry.java
+++ b/ojluni/src/main/java/java/util/zip/ZipEntry.java
@@ -32,7 +32,6 @@
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
-
 import static java.util.zip.ZipConstants64.*;
 
 /**
@@ -42,7 +41,6 @@
  */
 public
 class ZipEntry implements ZipConstants, Cloneable {
-
     String name;        // entry name
     long xdostime = -1; // last modification time (in extended DOS time,
                         // where milliseconds lost in conversion might
@@ -57,7 +55,8 @@
     int flag = 0;       // general purpose flag
     byte[] extra;       // optional extra field data for entry
     String comment;     // optional comment string for entry
-    // Android-changed: Add dataOffset for internal use.
+    // Android-added: Add dataOffset for internal use.
+    // Used by android.util.jar.StrictJarFile from frameworks.
     long dataOffset;
 
     /**
@@ -75,21 +74,6 @@
      */
     static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16);
 
-    /** @hide - Called from StrictJarFile native code. */
-    public ZipEntry(String name, String comment, long crc, long compressedSize,
-            long size, int compressionMethod, int xdostime, byte[] extra,
-            long dataOffset) {
-        this.name = name;
-        this.comment = comment;
-        this.crc = crc;
-        this.csize = compressedSize;
-        this.size = size;
-        this.method = compressionMethod;
-        this.xdostime = xdostime;
-        this.dataOffset = dataOffset;
-        this.setExtra0(extra, false);
-    }
-
     /**
      * Approximately 128 years, in milliseconds (ignoring leap years etc).
      *
@@ -105,10 +89,26 @@
      * should be sufficient.
      * @hide
      */
-    // Android-changed: public for testing purposes
+    // Android-changed: Make UPPER_DOSTIME_BOUND public hidden for testing purposes.
     public static final long UPPER_DOSTIME_BOUND =
             128L * 365 * 24 * 60 * 60 * 1000;
 
+    // Android-added: New constructor for use by StrictJarFile native code.
+    /** @hide */
+    public ZipEntry(String name, String comment, long crc, long compressedSize,
+            long size, int compressionMethod, int xdostime, byte[] extra,
+            long dataOffset) {
+        this.name = name;
+        this.comment = comment;
+        this.crc = crc;
+        this.csize = compressedSize;
+        this.size = size;
+        this.method = compressionMethod;
+        this.xdostime = xdostime;
+        this.dataOffset = dataOffset;
+        this.setExtra0(extra, false);
+    }
+
     /**
      * Creates a new zip entry with the specified name.
      *
@@ -122,6 +122,9 @@
     public ZipEntry(String name) {
         Objects.requireNonNull(name, "name");
         // Android-changed: Explicitly use UTF_8 instead of the default charset.
+        // if (name.length() > 0xFFFF) {
+        //     throw new IllegalArgumentException("entry name too long");
+        // }
         if (name.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
             throw new IllegalArgumentException(name + " too long: " +
                     name.getBytes(StandardCharsets.UTF_8).length);
@@ -152,6 +155,7 @@
         flag = e.flag;
         extra = e.extra;
         comment = e.comment;
+        // Android-added: Add dataOffset for internal use.
         dataOffset = e.dataOffset;
     }
 
@@ -160,6 +164,7 @@
      */
     ZipEntry() {}
 
+    // Android-added: Add dataOffset for internal use.
     /** @hide */
     public long getDataOffset() {
         return dataOffset;
@@ -218,8 +223,6 @@
      * @see #setLastModifiedTime(FileTime)
      */
     public long getTime() {
-        // Android-changed: Use xdostime, returning mtime would be a
-        // functional difference
         if (mtime != null) {
             return mtime.toMillis();
         }
@@ -573,18 +576,12 @@
      * @see #getComment()
      */
     public void setComment(String comment) {
-        // Android-changed: Explicitly allow null comments (or allow comments to be
-        // cleared).
-        if (comment == null) {
-            this.comment = null;
-            return;
-        }
-
-        // Android-changed: Explicitly use UTF-8.
-        if (comment.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
+        // BEGIN Android-added: Explicitly use UTF_8 instead of the default charset.
+        if (comment != null && comment.getBytes(StandardCharsets.UTF_8).length > 0xffff) {
             throw new IllegalArgumentException(comment + " too long: " +
                     comment.getBytes(StandardCharsets.UTF_8).length);
         }
+        // END Android-added: Explicitly use UTF_8 instead of the default charset.
 
         this.comment = comment;
     }
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index bc2e6cf..851aab1 100644
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -62,19 +62,37 @@
  */
 public
 class ZipFile implements ZipConstants, Closeable {
-    private long jzfile;           // address of jzfile data
+    // Android-note: jzfile does not require @ReachabilitySensitive annotation.
+    // The @ReachabilitySensitive annotation is usually added to instance fields that references
+    // native data that is cleaned up when the instance becomes unreachable. Its presence ensures
+    // that the instance object is not finalized until the field is no longer used. Without it an
+    // instance could be finalized during execution of an instance method iff that method's this
+    // variable holds the last reference to the instance and the method had copied all the fields
+    // it needs out of the instance. That would release the native data, invalidating its reference
+    // and would cause serious problems if the method had taken a copy of that field and
+    // then called a native method that would try to use it.
+    //
+    // This field does not require the annotation because all usages of this field are enclosed
+    // within a synchronized(this) block and finalizing of the object referenced in a synchronized
+    // block is not allowed as that would release its monitor that is currently in use.
+    private long jzfile;  // address of jzfile data
     private final String name;     // zip file name
     private final int total;       // total number of entries
     private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
 
     // Android-added: CloseGuard support
-    // Not declared @ReachabilitySensitive, since all relevant methods, including finalize()
-    // synchronize on this, preventing premature finalization.
     private final CloseGuard guard = CloseGuard.get();
 
-    // Android-changed, needed for alternative OPEN_DELETE implementation
-    // that doesn't use unlink before closing the file.
+    // Android-added: Do not use unlink() to implement OPEN_DELETE.
+    // Upstream uses unlink() to cause the file name to be removed from the filesystem after it is
+    // opened but that does not work on fuse fs as it causes problems with lseek. Android simply
+    // keeps a reference to the File so that it can explicitly delete it during close.
+    //
+    // OpenJDK 9+181 has a pure Java implementation of ZipFile that does not use unlink() and
+    // instead does something very similar to what Android does. If Android adopts it then this
+    // patch can be dropped.
+    // See http://b/28950284 and http://b/28901232 for more details.
     private final File fileToRemoveOnClose;
 
     private static final int STORED = ZipEntry.STORED;
@@ -94,10 +112,27 @@
      */
     public static final int OPEN_DELETE = 0x4;
 
+    // Android-removed: initIDs() not used on Android.
+    /*
+    static {
+        /* Zip library is loaded from System.initializeSystemClass *
+        initIDs();
+    }
+
+    private static native void initIDs();
+    */
+
     private static final boolean usemmap;
 
     static {
-        // Android-changed: always use mmap.
+        // Android-changed: Always use mmap.
+        /*
+        // A system prpperty to disable mmap use to avoid vm crash when
+        // in-use zip file is accidently overwritten by others.
+        String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping");
+        usemmap = (prop == null ||
+                   !(prop.length() == 0 || prop.equalsIgnoreCase("true")));
+        */
         usemmap = true;
     }
 
@@ -207,51 +242,35 @@
             throw new IllegalArgumentException("Illegal mode: 0x"+
                                                Integer.toHexString(mode));
         }
-
-        // Android-changed: Error out early if the file is too short or non-existent.
-        long length = file.length();
-        if (length < ZipConstants.ENDHDR) {
-            if (length == 0 && !file.exists()) {
-                throw new FileNotFoundException("File doesn't exist: " + file);
-            } else {
-                throw new ZipException("File too short to be a zip file: " + file.length());
+        String name = file.getPath();
+        // Android-removed: SecurityManager is always null
+        /*
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkRead(name);
+            if ((mode & OPEN_DELETE) != 0) {
+                sm.checkDelete(name);
             }
         }
+        */
 
-        // Android-changed, handle OPEN_DELETE case in #close().
+        // Android-added: Do not use unlink() to implement OPEN_DELETE.
         fileToRemoveOnClose = ((mode & OPEN_DELETE) != 0) ? file : null;
 
-        String name = file.getPath();
-        // Android-changed: SecurityManager is always null
-        // SecurityManager sm = System.getSecurityManager();
-        // if (sm != null) {
-        //     sm.checkRead(name);
-        //     if ((mode & OPEN_DELETE) != 0) {
-        //         sm.checkDelete(name);
-        //     }
-        // }
         if (charset == null)
             throw new NullPointerException("charset is null");
         this.zc = ZipCoder.get(charset);
-        // Android-changed: Skip perf counters
+        // Android-removed: Skip perf counters
         // long t0 = System.nanoTime();
         jzfile = open(name, mode, file.lastModified(), usemmap);
-        // Android-changed: Skip perf counters
+        // Android-removed: Skip perf counters
         // sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
         // sun.misc.PerfCounter.getZipFileCount().increment();
         this.name = name;
         this.total = getTotal(jzfile);
         this.locsig = startsWithLOC(jzfile);
-        Enumeration<? extends ZipEntry> entries = entries();
-
+        // Android-added: CloseGuard support
         guard.open("close");
-
-        // Android-changed: Error out early if the zipfile has no entries.
-        if (size() == 0 || !entries.hasMoreElements()) {
-            close();
-            throw new ZipException("No entries");
-        }
-
     }
 
     /**
@@ -380,10 +399,16 @@
         synchronized (this) {
             ensureOpen();
             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
-                // Android-changed: addSlash set to true, android is fine with "/" at the end
+                // Android-changed: Find entry by name, falling back to name/ if cannot be found.
+                // Needed for ClassPathURLStreamHandler handling of URLs without trailing slashes.
+                // This was added as part of the work to move StrictJarFile from libcore to
+                // framework, see http://b/111293098 for more details.
+                // It should be possible to revert this after upgrading to OpenJDK 8u144 or above.
+                // jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
                 jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), true);
             } else {
-                // Android-changed: addSlash set to true, android is fine with "/" at the end
+                // Android-changed: Find entry by name, falling back to name/ if cannot be found.
+                // jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
                 jzentry = getEntry(jzfile, zc.getBytes(entry.name), true);
             }
             if (jzentry == 0) {
@@ -401,6 +426,7 @@
                 // MORE: Compute good size for inflater stream:
                 long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
                 // Android-changed: Use 64k buffer size, performs better than 8k.
+                // See http://b/65491407.
                 // if (size > 65536) size = 8192;
                 if (size > 65536) size = 65536;
                 if (size <= 0) size = 4096;
@@ -642,32 +668,47 @@
     public void close() throws IOException {
         if (closeRequested)
             return;
-        guard.close();
+        // Android-added: CloseGuard support
+        if (guard != null) {
+            guard.close();
+        }
         closeRequested = true;
 
         synchronized (this) {
             // Close streams, release their inflaters
-            synchronized (streams) {
-                if (false == 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();
+            // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
+            // If the constructor threw an exception then the streams / inflaterCache fields can
+            // be null and close() can be called by the finalizer.
+            if (streams != null) {
+            // END Android-added: null field check to avoid NullPointerException during finalize.
+                synchronized (streams) {
+                    if (false == 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();
+                            }
                         }
                     }
                 }
+            // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
             }
 
-            // Release cached inflaters
-            Inflater inf;
-            synchronized (inflaterCache) {
-                while (null != (inf = inflaterCache.poll())) {
-                    inf.end();
+            if (inflaterCache != null) {
+            // END Android-added: null field check to avoid NullPointerException during finalize.
+                // Release cached inflaters
+                Inflater inf;
+                synchronized (inflaterCache) {
+                    while (null != (inf = inflaterCache.poll())) {
+                        inf.end();
+                    }
                 }
+            // BEGIN Android-added: null field check to avoid NullPointerException during finalize.
             }
+            // END Android-added: null field check to avoid NullPointerException during finalize.
 
             if (jzfile != 0) {
                 // Close the zip file
@@ -676,7 +717,7 @@
 
                 close(zf);
             }
-            // Android-changed, explicit delete for OPEN_DELETE ZipFile.
+            // Android-added: Do not use unlink() to implement OPEN_DELETE.
             if (fileToRemoveOnClose != null) {
                 fileToRemoveOnClose.delete();
             }
@@ -698,14 +739,11 @@
      * @see    java.util.zip.ZipFile#close()
      */
     protected void finalize() throws IOException {
-        // Android-note: finalize() won't be invoked while important instance methods are running.
-        // Both those methods and this method synchronize on "this", ensuring reachability
-        // until the monitor is released.
+        // Android-added: CloseGuard support
         if (guard != null) {
             guard.warnIfOpen();
         }
-
-        close();  // Synchronizes on "this".
+        close();
     }
 
     private static native void close(long jzfile);
@@ -745,8 +783,12 @@
         }
 
         public int read(byte b[], int off, int len) throws IOException {
-            // Android-changed: Always throw an exception on read if the zipfile
-            // has already been closed.
+            // Android-added: Always throw an exception when reading from closed zipfile.
+            // Required by the JavaDoc for InputStream.read(byte[], int, int). Upstream version
+            // 8u121-b13 is not compliant but that bug has been fixed in upstream version 9+181
+            // as part of a major change to switch to a pure Java implementation.
+            // See https://bugs.openjdk.java.net/browse/JDK-8145260 and
+            // https://bugs.openjdk.java.net/browse/JDK-8142508.
             ensureOpenOrZipException();
 
             synchronized (ZipFile.this) {
@@ -762,7 +804,8 @@
                     len = (int) rem;
                 }
 
-                // Android-changed: Moved
+                // Android-removed: Always throw an exception when reading from closed zipfile.
+                // Moved to the start of the method.
                 //ensureOpenOrZipException();
                 len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
                                    off, len);
@@ -827,15 +870,33 @@
         }
     }
 
+    // Android-removed: Access startsWithLocHeader() directly.
+    /*
+    static {
+        sun.misc.SharedSecrets.setJavaUtilZipFileAccess(
+            new sun.misc.JavaUtilZipFileAccess() {
+                public boolean startsWithLocHeader(ZipFile zip) {
+                    return zip.startsWithLocHeader();
+                }
+             }
+        );
+    }
+    */
+
     /**
      * Returns {@code true} if, and only if, the zip file begins with {@code
      * LOCSIG}.
      * @hide
      */
+    // Android-changed: Access startsWithLocHeader() directly.
+    // Make hidden public for use by sun.misc.URLClassPath
+    // private boolean startsWithLocHeader() {
     public boolean startsWithLocHeader() {
         return locsig;
     }
 
+    // BEGIN Android-added: Provide access to underlying file descriptor for testing.
+    // See http://b/111148957 for background information.
     /** @hide */
     // @VisibleForTesting
     public int getFileDescriptor() {
@@ -843,6 +904,7 @@
     }
 
     private static native int getFileDescriptor(long jzfile);
+    // END Android-added: Provide access to underlying file descriptor for testing.
 
     private static native long open(String name, int mode, long lastModified,
                                     boolean usemmap) throws IOException;
diff --git a/ojluni/src/main/java/java/util/zip/ZipInputStream.java b/ojluni/src/main/java/java/util/zip/ZipInputStream.java
index cda8b81..0413f47 100644
--- a/ojluni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/ojluni/src/main/java/java/util/zip/ZipInputStream.java
@@ -124,10 +124,12 @@
         if ((entry = readLOC()) == null) {
             return null;
         }
-        // BEGIN Android-changed
+        // Android-changed: Return more accurate value from available().
+        // Initialize the remaining field with the number of bytes that can be read from the entry
+        // for both uncompressed and compressed entries so that it can be used to provide a more
+        // accurate return value for available().
         // if (entry.method == STORED) {
         if (entry.method == STORED || entry.method == DEFLATED) {
-        // END Android-changed
             remaining = entry.size;
         }
         entryEOF = false;
@@ -159,10 +161,14 @@
      */
     public int available() throws IOException {
         ensureOpen();
-        // BEGIN Android-changed
+        // Android-changed: Return more accurate value from available().
+        // Tracks the remaining bytes in order to return a more accurate value for the available
+        // bytes. Given an entry of size N both Android and upstream will return 1 until N bytes
+        // have been read at which point Android will return 0 and upstream will return 1.
+        // Upstream will only return 0 after an attempt to read a byte fails because the EOF has
+        // been reached. See http://b/111439440 for more details.
         // if (entryEOF) {
         if (entryEOF || (entry != null && remaining == 0)) {
-        // END Android-changed
             return 0;
         } else {
             return 1;
@@ -206,9 +212,10 @@
                 entry = null;
             } else {
                 crc.update(b, off, len);
-                // BEGIN Android-changed
+                // Android-added: Return more accurate value from available().
+                // Update the remaining field so it is an accurate count of the number of bytes
+                // remaining in this stream, after deflation.
                 remaining -= len;
-                // END Android-changed
             }
             return len;
         case STORED:
diff --git a/ojluni/src/main/java/java/util/zip/ZipOutputStream.java b/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
index b4ac81d..dd005ec 100644
--- a/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/ojluni/src/main/java/java/util/zip/ZipOutputStream.java
@@ -53,7 +53,7 @@
      * total entry count fields, such as the ones in jdk6, and even
      * some in jdk7.
      */
-    // Android-changed: Force to false.
+    // Android-changed: Always allow use of Zip64.
     private static final boolean inhibitZip64 = false;
     //  Boolean.parseBoolean(
     //      java.security.AccessController.doPrivileged(
@@ -358,10 +358,6 @@
         if (finished) {
             return;
         }
-        // Android-changed: Fix for ZipOutputStreamTest#testCreateEmpty
-        if (xentries.isEmpty()) {
-            throw new ZipException("No entries");
-        }
         if (current != null) {
             closeEntry();
         }
diff --git a/ojluni/src/main/java/javax/crypto/JceSecurity.java b/ojluni/src/main/java/javax/crypto/JceSecurity.java
index 4572627..b0ae07e 100644
--- a/ojluni/src/main/java/javax/crypto/JceSecurity.java
+++ b/ojluni/src/main/java/javax/crypto/JceSecurity.java
@@ -218,7 +218,7 @@
 
     static {
         try {
-            NULL_URL = new URL("http://null.oracle.com/");
+            NULL_URL = new URL("http://null.sun.com/");
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -255,69 +255,14 @@
 
     // BEGIN Android-removed: JCE crypto strength restrictions are never in place on Android.
     /*
-     * This is called from within an doPrivileged block.
-     *
-     * Following logic is used to decide what policy files are selected.
-     *
-     * If the new Security property (crypto.policy) is set in the
-     * java.security file, or has been set dynamically using the
-     * Security.setProperty() call before the JCE framework has
-     * been initialized, that setting will be used.
-     * Remember - this property is not defined by default. A conscious
-     * user edit or an application call is required.
-     *
-     * Otherwise, if user has policy jar files installed in the legacy
-     * jre/lib/security/ directory, the JDK will honor whatever
-     * setting is set by those policy files. (legacy/current behavior)
-     *
-     * If none of the above 2 conditions are met, the JDK will default
-     * to using the limited crypto policy files found in the
-     * jre/lib/security/policy/limited/ directory
-     *
     private static void setupJurisdictionPolicies() throws Exception {
-        // Sanity check the crypto.policy Security property.  Single
-        // directory entry, no pseudo-directories (".", "..", leading/trailing
-        // path separators). normalize()/getParent() will help later.
-        String javaHomeProperty = System.getProperty("java.home");
-        String cryptoPolicyProperty = Security.getProperty("crypto.policy");
-        Path cpPath = (cryptoPolicyProperty == null) ? null :
-                Paths.get(cryptoPolicyProperty);
+        String javaHomeDir = System.getProperty("java.home");
+        String sep = File.separator;
+        String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
+            "security" + sep;
 
-        if ((cpPath != null) && ((cpPath.getNameCount() != 1) ||
-                (cpPath.compareTo(cpPath.getFileName())) != 0)) {
-            throw new SecurityException(
-                    "Invalid policy directory name format: " +
-                            cryptoPolicyProperty);
-        }
-
-        if (cpPath == null) {
-            // Security property is not set, use default path
-            cpPath = Paths.get(javaHomeProperty, "lib", "security");
-        } else {
-            // populate with java.home
-            cpPath = Paths.get(javaHomeProperty, "lib", "security",
-                    "policy", cryptoPolicyProperty);
-        }
-
-        if (debug != null) {
-            debug.println("crypto policy directory: " + cpPath);
-        }
-
-        File exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
-        File importJar = new File(cpPath.toFile(),"local_policy.jar");
-
-        if (cryptoPolicyProperty == null && (!exportJar.exists() ||
-                !importJar.exists())) {
-            // Compatibility set up. If crypto.policy is not defined.
-            // check to see if legacy jars exist in lib directory. If
-            // they don't exist, we default to limited policy mode.
-            cpPath = Paths.get(
-                    javaHomeProperty, "lib", "security", "policy", "limited");
-            // point to the new jar files in limited directory
-            exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
-            importJar = new File(cpPath.toFile(),"local_policy.jar");
-        }
-
+        File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
+        File importJar = new File(pathToPolicyJar, "local_policy.jar");
         URL jceCipherURL = ClassLoader.getSystemResource
                 ("javax/crypto/Cipher.class");
 
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index ec4254a..58e3591 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -178,7 +178,7 @@
         }
     }
 
-    // BEGIN Android-changed: Use lazily-created OkHttp hostname verifier
+    // BEGIN Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
     // The RI default hostname verifier is a static member of the class, which means
     // it's created when the class is initialized.  As well, its default verifier
     // just fails all verification attempts, whereas we use OkHttp's verifier.
@@ -211,7 +211,7 @@
      * The <code>hostnameVerifier</code> for this object.
      */
     protected HostnameVerifier hostnameVerifier;
-    // END Android-changed: Use lazily-created OkHttp hostname verifier
+    // END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
 
     /**
      * Sets the default <code>HostnameVerifier</code> inherited by a
@@ -239,6 +239,8 @@
         if (sm != null) {
             sm.checkPermission(new SSLPermission("setHostnameVerifier"));
         }
+        // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
+        // defaultHostnameVerifier = v;
         NoPreloadHolder.defaultHostnameVerifier = v;
     }
 
@@ -250,6 +252,8 @@
      * @see #setDefaultHostnameVerifier(HostnameVerifier)
      */
     public static HostnameVerifier getDefaultHostnameVerifier() {
+        // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
+        // return defaultHostnameVerifier;
         return NoPreloadHolder.defaultHostnameVerifier;
     }
 
@@ -284,7 +288,12 @@
      * @see #setDefaultHostnameVerifier(HostnameVerifier)
      */
     public HostnameVerifier getHostnameVerifier() {
-        // Android-added: Use the default verifier if none is set
+        // Android-added: Use the default verifier if none is set.
+        // Note that this also has the side effect of *setting* (if unset)
+        // hostnameVerifier to be the default one. It's not clear why this
+        // was done (commit abd00f0eaa46f71f98e75a631c268c812d1ec7c1) but
+        // we're keeping this behavior for lack of a strong reason to do
+        // otherwise.
         if (hostnameVerifier == null) {
             hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
         }
@@ -358,6 +367,9 @@
      * @param sf the SSL socket factory
      * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
      *          parameter is null.
+     * @throws SecurityException if a security manager exists and its
+     *         <code>checkSetFactory</code> method does not allow
+     *         a socket factory to be specified.
      * @see #getSSLSocketFactory()
      */
     public void setSSLSocketFactory(SSLSocketFactory sf) {
diff --git a/ojluni/src/main/java/javax/security/auth/callback/Callback.java b/ojluni/src/main/java/javax/security/auth/callback/Callback.java
index 83855ca..d95c87f1 100644
--- a/ojluni/src/main/java/javax/security/auth/callback/Callback.java
+++ b/ojluni/src/main/java/javax/security/auth/callback/Callback.java
@@ -26,6 +26,13 @@
 
 package javax.security.auth.callback;
 
+// Android-changed: Removed @see tags (targets do not exist on Android):
+// @see javax.security.auth.callback.ChoiceCallback
+// @see javax.security.auth.callback.ConfirmationCallback
+// @see javax.security.auth.callback.LanguageCallback
+// @see javax.security.auth.callback.NameCallback
+// @see javax.security.auth.callback.TextInputCallback
+// @see javax.security.auth.callback.TextOutputCallback
 /**
  * <p> Implementations of this interface are passed to a
  * {@code CallbackHandler}, allowing underlying security services
@@ -41,12 +48,6 @@
  * underlying security services.
  *
  * @see javax.security.auth.callback.CallbackHandler
- * @see javax.security.auth.callback.ChoiceCallback
- * @see javax.security.auth.callback.ConfirmationCallback
- * @see javax.security.auth.callback.LanguageCallback
- * @see javax.security.auth.callback.NameCallback
  * @see javax.security.auth.callback.PasswordCallback
- * @see javax.security.auth.callback.TextInputCallback
- * @see javax.security.auth.callback.TextOutputCallback
  */
 public interface Callback { }
diff --git a/ojluni/src/main/java/javax/security/auth/login/LoginException.java b/ojluni/src/main/java/javax/security/auth/login/LoginException.java
index 75eedec..c8fa8cb 100644
--- a/ojluni/src/main/java/javax/security/auth/login/LoginException.java
+++ b/ojluni/src/main/java/javax/security/auth/login/LoginException.java
@@ -25,10 +25,10 @@
 
 package javax.security.auth.login;
 
+// Android-changed: Removed @see tag (target does not exist on Android):
+// @see javax.security.auth.login.LoginContext
 /**
  * This is the basic login exception.
- *
- * @see javax.security.auth.login.LoginContext
  */
 
 public class LoginException extends java.security.GeneralSecurityException {
diff --git a/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java b/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
index 73c67d8..644fc4d 100644
--- a/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
+++ b/ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java
@@ -32,7 +32,8 @@
  * {@link java.net.StandardSocketOptions}. These options may be platform
  * specific.
  */
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
 public final class ExtendedSocketOptions {
 
     private static class ExtSocketOption<T> implements SocketOption<T> {
diff --git a/ojluni/src/main/java/jdk/net/NetworkPermission.java b/ojluni/src/main/java/jdk/net/NetworkPermission.java
index 96d7a8e..b102571 100644
--- a/ojluni/src/main/java/jdk/net/NetworkPermission.java
+++ b/ojluni/src/main/java/jdk/net/NetworkPermission.java
@@ -32,8 +32,8 @@
 /**
  * Legacy security code; do not use.
  */
-
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
 public final class NetworkPermission extends BasicPermission {
 
     public NetworkPermission(String name) {
diff --git a/ojluni/src/main/java/jdk/net/SocketFlow.java b/ojluni/src/main/java/jdk/net/SocketFlow.java
index a8ca749..59875a8 100644
--- a/ojluni/src/main/java/jdk/net/SocketFlow.java
+++ b/ojluni/src/main/java/jdk/net/SocketFlow.java
@@ -43,7 +43,8 @@
  * When a security manager is installed, a {@link NetworkPermission}
  * is required to set or get this option.
  */
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
 public class SocketFlow {
 
     private static final int UNSET = -1;
@@ -64,7 +65,8 @@
      * one of these statuses, which reflect the state of socket's
      * flow.
      */
-//    @jdk.Exported
+    // Android-removed: @jdk.Exported, not present on Android.
+    // @jdk.Exported
     public enum Status {
         /**
          * Set or get socket option has not been called yet. Status
diff --git a/ojluni/src/main/java/jdk/net/Sockets.java b/ojluni/src/main/java/jdk/net/Sockets.java
index 1187eb3..197a905 100644
--- a/ojluni/src/main/java/jdk/net/Sockets.java
+++ b/ojluni/src/main/java/jdk/net/Sockets.java
@@ -55,7 +55,8 @@
  *
  * @see java.nio.channels.NetworkChannel
  */
-//@jdk.Exported
+// Android-removed: @jdk.Exported, not present on Android.
+// @jdk.Exported
 public class Sockets {
 
     private final static HashMap<Class<?>,Set<SocketOption<?>>>
diff --git a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
index 94c401f..6ce6fcf 100644
--- a/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
+++ b/ojluni/src/main/java/sun/invoke/util/VerifyAccess.java
@@ -185,29 +185,75 @@
         return false;
     }
 
+    // Android-removed: Unused method.
+    /*
     /**
      * Decide if the given method type, attributed to a member or symbolic
      * reference of a given reference class, is really visible to that class.
      * @param type the supposed type of a member or symbolic reference of refc
      * @param refc the class attempting to make the reference
-     */
+     *
     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
-        if (type == refc)  return true;  // easy check
+        if (type == refc) {
+            return true;  // easy check
+        }
         while (type.isArray())  type = type.getComponentType();
-        if (type.isPrimitive() || type == Object.class)  return true;
-        ClassLoader parent = type.getClassLoader();
-        if (parent == null)  return true;
-        ClassLoader child  = refc.getClassLoader();
-        if (child == null)  return false;
-        if (parent == child || loadersAreRelated(parent, child, true))
+        if (type.isPrimitive() || type == Object.class) {
             return true;
-        // Do it the hard way:  Look up the type name from the refc loader.
-        try {
-            Class<?> res = child.loadClass(type.getName());
-            return (type == res);
-        } catch (ClassNotFoundException ex) {
+        }
+        ClassLoader typeLoader = type.getClassLoader();
+        ClassLoader refcLoader = refc.getClassLoader();
+        if (typeLoader == refcLoader) {
+            return true;
+        }
+        if (refcLoader == null && typeLoader != null) {
             return false;
         }
+        if (typeLoader == null && type.getName().startsWith("java.")) {
+            // Note:  The API for actually loading classes, ClassLoader.defineClass,
+            // guarantees that classes with names beginning "java." cannot be aliased,
+            // because class loaders cannot load them directly.
+            return true;
+        }
+
+        // Do it the hard way:  Look up the type name from the refc loader.
+        //
+        // Force the refc loader to report and commit to a particular binding for this type name (type.getName()).
+        //
+        // In principle, this query might force the loader to load some unrelated class,
+        // which would cause this query to fail (and the original caller to give up).
+        // This would be wasted effort, but it is expected to be very rare, occurring
+        // only when an attacker is attempting to create a type alias.
+        // In the normal case, one class loader will simply delegate to the other,
+        // and the same type will be visible through both, with no extra loading.
+        //
+        // It is important to go through Class.forName instead of ClassLoader.loadClass
+        // because Class.forName goes through the JVM system dictionary, which records
+        // the class lookup once for all. This means that even if a not-well-behaved class loader
+        // would "change its mind" about the meaning of the name, the Class.forName request
+        // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
+        // will record the first successful result. Unsuccessful results are not stored.
+        //
+        // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
+        // class loader about the binding of the proposed name (type.getName()).
+        // The looked up type ("res") is compared for equality against the proposed
+        // type ("type") and then is discarded.  Thus, the worst that can happen to
+        // the "child" class loader is that it is bothered to load and report a class
+        // that differs from "type"; this happens once due to JVM system dictionary
+        // memoization.  And the caller never gets to look at the alternate type binding
+        // ("res"), whether it exists or not.
+        final String name = type.getName();
+        Class<?> res = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Class>() {
+                    public Class<?> run() {
+                        try {
+                            return Class.forName(name, false, refcLoader);
+                        } catch (ClassNotFoundException | LinkageError e) {
+                            return null; // Assume the class is not found
+                        }
+                    }
+            });
+        return (type == res);
     }
 
     /**
@@ -215,7 +261,7 @@
      * reference of a given reference class, is really visible to that class.
      * @param type the supposed type of a member or symbolic reference of refc
      * @param refc the class attempting to make the reference
-     */
+     *
     public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
         for (int n = -1, max = type.parameterCount(); n < max; n++) {
             Class<?> ptype = (n < 0 ? type.returnType() : type.parameterType(n));
@@ -224,6 +270,7 @@
         }
         return true;
     }
+    */
 
     /**
      * Test if two classes have the same class loader and package qualifier.
@@ -253,8 +300,10 @@
         return true;
     }
 
+    // Android-removed: Unused method.
+    /*
     /** Return the package name for this class.
-     */
+     *
     public static String getPackageName(Class<?> cls) {
         assert(!cls.isArray());
         String name = cls.getName();
@@ -262,6 +311,7 @@
         if (dot < 0)  return "";
         return name.substring(0, dot);
     }
+    */
 
     /**
      * Test if two classes are defined as part of the same package member (top-level class).
@@ -287,6 +337,8 @@
         return pkgmem;
     }
 
+    // Android-removed: Unused method.
+    /*
     private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,
                                              boolean loader1MustBeParent) {
         if (loader1 == loader2 || loader1 == null
@@ -305,15 +357,19 @@
         }
         return false;
     }
+    */
 
+    // Android-removed: Unused method.
+    /*
     /**
      * Is the class loader of parentClass identical to, or an ancestor of,
      * the class loader of childClass?
      * @param parentClass a class
      * @param childClass another class, which may be a descendent of the first class
      * @return whether parentClass precedes or equals childClass in class loader order
-     */
+     *
     public static boolean classLoaderIsAncestor(Class<?> parentClass, Class<?> childClass) {
         return loadersAreRelated(parentClass.getClassLoader(), childClass.getClassLoader(), true);
     }
+    */
 }
diff --git a/ojluni/src/main/java/sun/misc/SharedSecrets.java b/ojluni/src/main/java/sun/misc/SharedSecrets.java
index d21aa4d..45cd489 100644
--- a/ojluni/src/main/java/sun/misc/SharedSecrets.java
+++ b/ojluni/src/main/java/sun/misc/SharedSecrets.java
@@ -35,15 +35,191 @@
     for this purpose, namely the loss of compile-time checking. */
 
 public class SharedSecrets {
-    // BEGIN Android-changed: Pruned unused access interfaces
+    // BEGIN Android-removed: Pruned unused access interfaces
+    /*
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static JavaUtilJarAccess javaUtilJarAccess;
+    private static JavaLangAccess javaLangAccess;
+    private static JavaLangRefAccess javaLangRefAccess;
+    private static JavaIOAccess javaIOAccess;
+    private static JavaNetAccess javaNetAccess;
+    private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
+    private static JavaNioAccess javaNioAccess;
+    */
+    // END Android-removed: Pruned unused access interfaces
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
+    // BEGIN Android-removed: Pruned unused access interfaces
+    /*
+    private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
+    private static JavaSecurityAccess javaSecurityAccess;
+    private static JavaUtilZipFileAccess javaUtilZipFileAccess;
+    private static JavaAWTAccess javaAWTAccess;
+    private static JavaOISAccess javaOISAccess;
+    private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
+
+    public static JavaUtilJarAccess javaUtilJarAccess() {
+        if (javaUtilJarAccess == null) {
+            // Ensure JarFile is initialized; we know that that class
+            // provides the shared secret
+            unsafe.ensureClassInitialized(JarFile.class);
+        }
+        return javaUtilJarAccess;
+    }
+
+    public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
+        javaUtilJarAccess = access;
+    }
+
+    public static void setJavaLangAccess(JavaLangAccess jla) {
+        javaLangAccess = jla;
+    }
+
+    public static JavaLangAccess getJavaLangAccess() {
+        return javaLangAccess;
+    }
+
+    public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
+        javaLangRefAccess = jlra;
+    }
+
+    public static JavaLangRefAccess getJavaLangRefAccess() {
+        return javaLangRefAccess;
+    }
+
+    public static void setJavaNetAccess(JavaNetAccess jna) {
+        javaNetAccess = jna;
+    }
+
+    public static JavaNetAccess getJavaNetAccess() {
+        return javaNetAccess;
+    }
+
+    public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
+        javaNetHttpCookieAccess = a;
+    }
+
+    public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
+        if (javaNetHttpCookieAccess == null)
+            unsafe.ensureClassInitialized(java.net.HttpCookie.class);
+        return javaNetHttpCookieAccess;
+    }
+
+    public static void setJavaNioAccess(JavaNioAccess jna) {
+        javaNioAccess = jna;
+    }
+
+    public static JavaNioAccess getJavaNioAccess() {
+        if (javaNioAccess == null) {
+            // Ensure java.nio.ByteOrder is initialized; we know that
+            // this class initializes java.nio.Bits that provides the
+            // shared secret.
+            unsafe.ensureClassInitialized(java.nio.ByteOrder.class);
+        }
+        return javaNioAccess;
+    }
+
+    public static void setJavaIOAccess(JavaIOAccess jia) {
+        javaIOAccess = jia;
+    }
+
+    public static JavaIOAccess getJavaIOAccess() {
+        if (javaIOAccess == null) {
+            unsafe.ensureClassInitialized(Console.class);
+        }
+        return javaIOAccess;
+    }
+    */
+    // END Android-removed: Pruned unused access interfaces
 
     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
         javaIOFileDescriptorAccess = jiofda;
     }
 
     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
+        // Android-changed: ensureClassInitialized isn't supported in Android. Use Class.forName.
+        // if (javaIOFileDescriptorAccess == null)
+        //     unsafe.ensureClassInitialized(FileDescriptor.class);
+        if (javaIOFileDescriptorAccess == null) {
+            try {
+                Class.forName("java.io.FileDescriptor");
+            } catch (ClassNotFoundException e) {
+                // Throw if FileDescriptor class is not found. Something wrong in runtime / libcore.
+                throw new RuntimeException(e);
+            }
+        }
         return javaIOFileDescriptorAccess;
     }
-    // END Android-changed: Pruned unused access interfaces
+
+    // BEGIN Android-removed: Pruned unused access interfaces
+    /*
+    public static void setJavaOISAccess(JavaOISAccess access) {
+        javaOISAccess = access;
+    }
+
+    public static JavaOISAccess getJavaOISAccess() {
+        if (javaOISAccess == null)
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+
+        return javaOISAccess;
+    }
+
+
+    public static void setJavaSecurityProtectionDomainAccess
+        (JavaSecurityProtectionDomainAccess jspda) {
+            javaSecurityProtectionDomainAccess = jspda;
+    }
+
+    public static JavaSecurityProtectionDomainAccess
+        getJavaSecurityProtectionDomainAccess() {
+            if (javaSecurityProtectionDomainAccess == null)
+                unsafe.ensureClassInitialized(ProtectionDomain.class);
+            return javaSecurityProtectionDomainAccess;
+    }
+
+    public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
+        javaSecurityAccess = jsa;
+    }
+
+    public static JavaSecurityAccess getJavaSecurityAccess() {
+        if (javaSecurityAccess == null) {
+            unsafe.ensureClassInitialized(AccessController.class);
+        }
+        return javaSecurityAccess;
+    }
+
+    public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
+        if (javaUtilZipFileAccess == null)
+            unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
+        return javaUtilZipFileAccess;
+    }
+
+    public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
+        javaUtilZipFileAccess = access;
+    }
+
+    public static void setJavaAWTAccess(JavaAWTAccess jaa) {
+        javaAWTAccess = jaa;
+    }
+
+    public static JavaAWTAccess getJavaAWTAccess() {
+        // this may return null in which case calling code needs to
+        // provision for.
+        if (javaAWTAccess == null) {
+            return null;
+        }
+        return javaAWTAccess;
+    }
+
+    public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+        if (javaObjectInputStreamAccess == null) {
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+        }
+        return javaObjectInputStreamAccess;
+    }
+
+    public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
+        javaObjectInputStreamAccess = access;
+    }
+    */
+    // END Android-removed: Pruned unused access interfaces
 }
diff --git a/ojluni/src/main/java/sun/misc/Unsafe.java b/ojluni/src/main/java/sun/misc/Unsafe.java
index c9ba16e..aaa9e70 100644
--- a/ojluni/src/main/java/sun/misc/Unsafe.java
+++ b/ojluni/src/main/java/sun/misc/Unsafe.java
@@ -26,7 +26,8 @@
 package sun.misc;
 
 import dalvik.annotation.optimization.FastNative;
-import dalvik.system.VMStack;
+import sun.reflect.Reflection;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
@@ -55,11 +56,12 @@
      * very limited situations.
      */
     public static Unsafe getUnsafe() {
+        Class<?> caller = Reflection.getCallerClass();
         /*
          * Only code on the bootclasspath is allowed to get at the
          * Unsafe instance.
          */
-        ClassLoader calling = VMStack.getCallingClassLoader();
+        ClassLoader calling = (caller == null) ? null : caller.getClassLoader();
         if ((calling != null) && (calling != Unsafe.class.getClassLoader())) {
             throw new SecurityException("Unsafe access denied");
         }
diff --git a/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java b/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
index 0c117d4..da2a739 100644
--- a/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
+++ b/ojluni/src/main/java/sun/net/ftp/impl/FtpClient.java
@@ -517,6 +517,10 @@
      * @return <code>true</code> if the command was successful
      * @throws IOException
      */
+    // Android-changed: Integrate upstream fix to guard against '\n'.
+    // Integrates OpenJDK's "8170222: Better transfers of files".
+    // See http://b/35784677 .
+    // private boolean issueCommand(String cmd) throws IOException {
     private boolean issueCommand(String cmd) throws IOException,
             sun.net.ftp.FtpProtocolException {
         if (!isConnected()) {
@@ -529,12 +533,14 @@
                 // ignore...
             }
         }
+        // BEGIN Android-added: Integrate upstream fix to guard against '\n'.
         if (cmd.indexOf('\n') != -1) {
             sun.net.ftp.FtpProtocolException ex
                     = new sun.net.ftp.FtpProtocolException("Illegal FTP command");
             ex.initCause(new IllegalArgumentException("Illegal carriage return"));
             throw ex;
         }
+        // END Android-added: Integrate upstream fix to guard against '\n'.
         sendServer(cmd + "\r\n");
         return readReply();
     }
diff --git a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
index fac57e2..2fc7fd1 100644
--- a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
+++ b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
@@ -117,7 +117,9 @@
      * basis, and change it only when the "source", i.e. the system property,
      * did change.
      */
-
+    // Android-note: Integrated some upstream changes from beyond OpenJDK8u121-b13.
+    // This includes NonProxyInfo.pattern -> hostsPool and associated changes.
+    // See http://b/62368386
     static class NonProxyInfo {
         // Default value for nonProxyHosts, this provides backward compatibility
         // by excluding localhost and its litteral notations.
diff --git a/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java b/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
index 6fbd4ff..4191ef4 100644
--- a/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
+++ b/ojluni/src/main/java/sun/net/spi/nameservice/NameService.java
@@ -28,6 +28,9 @@
 import java.net.UnknownHostException;
 
 public interface NameService {
+    // Android-changed: Support for network (netId)-specific DNS resolution.
+    // For use by frameworks/base's android.net.Network.
+    // public java.net.InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException;
     public java.net.InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException;
     public String getHostByAddr(byte[] addr) throws UnknownHostException;
 }
diff --git a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
index d7c4424..b0aa959 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
@@ -125,8 +125,12 @@
              * to get the jarFile, and set it as our permission.
              */
             if (getUseCaches()) {
+                // Android-added: Upstream fix to avoid affecting useCaches setting.
+                // This line and the one further down were integrated from an
+                // upstream commit beyond OpenJDK 8u121-b13. See http://b/62368386
                 boolean oldUseCaches = jarFileURLConnection.getUseCaches();
                 jarFileURLConnection = factory.getConnection(jarFile);
+                // Android-added: Upstream fix to avoid affecting useCaches setting.
                 jarFileURLConnection.setUseCaches(oldUseCaches);
             }
 
diff --git a/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java b/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
index b629517..e2f8092 100644
--- a/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
+++ b/ojluni/src/main/java/sun/nio/ch/ChannelInputStream.java
@@ -29,6 +29,7 @@
 import java.io.*;
 import java.nio.*;
 import java.nio.channels.*;
+import java.nio.channels.spi.*;
 
 
 /**
@@ -44,13 +45,8 @@
     extends InputStream
 {
 
-    // Android-changed: This code didn't make sense. In particular, the block channel is
-    // useless because we throw if the channel is non-blocking!. It would only make sense
-    // if it's called on a blocking channel (but we're asked to make it non-blocking before
-    // the read) we never do that, though.
-    //
-    // read(ReadableByteChannel,ByteBuffer, boolean block)
-    public static int read(ReadableByteChannel ch, ByteBuffer bb)
+    public static int read(ReadableByteChannel ch, ByteBuffer bb,
+                           boolean block)
         throws IOException
     {
         if (ch instanceof SelectableChannel) {
@@ -59,13 +55,11 @@
                 boolean bm = sc.isBlocking();
                 if (!bm)
                     throw new IllegalBlockingModeException();
-                // Android-removed.
-                // if (bm != block)
-                //    sc.configureBlocking(block);
+                if (bm != block)
+                    sc.configureBlocking(block);
                 int n = ch.read(bb);
-                // Android-removed.
-                // if (bm != block)
-                //     sc.configureBlocking(bm);
+                if (bm != block)
+                    sc.configureBlocking(bm);
                 return n;
             }
         } else {
@@ -113,7 +107,7 @@
     protected int read(ByteBuffer bb)
         throws IOException
     {
-        return ChannelInputStream.read(ch, bb);
+        return ChannelInputStream.read(ch, bb, true);
     }
 
     public int available() throws IOException {
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
index 0338f01..49ad55c 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramChannelImpl.java
@@ -28,36 +28,17 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.PortUnreachableException;
-import java.net.ProtocolFamily;
-import java.net.SocketAddress;
-import java.net.SocketOption;
-import java.net.StandardProtocolFamily;
-import java.net.StandardSocketOptions;
+import java.net.*;
 import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyBoundException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.MembershipKey;
-import java.nio.channels.NotYetConnectedException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.util.*;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
-import sun.net.ExtendedOptionsImpl;
 import sun.net.ResourceManager;
+import sun.net.ExtendedOptionsImpl;
 
 /**
  * An implementation of DatagramChannels.
@@ -72,9 +53,10 @@
     private static NativeDispatcher nd = new DatagramDispatcher();
 
     // Our file descriptor
-    // Android-changed: Make the fd package visible so that we can expose it through DatagramSocketAdaptor.
     // Android-added: @ReachabilitySensitive.
     @ReachabilitySensitive
+    // Android-changed: Make the fd visible for DatagramSocketAdaptor.
+    // private final FileDescriptor fd;
     final FileDescriptor fd;
 
     // fd value needed for dev/poll. This value will remain valid
@@ -146,7 +128,6 @@
             this.fdVal = IOUtil.fdVal(fd);
             this.state = ST_UNCONNECTED;
             // Android-added: CloseGuard support.
-            // Net#socket will set |fd| if it succeeds.
             if (fd != null && fd.valid()) {
                 guard.open("close");
             }
@@ -178,7 +159,6 @@
         this.fdVal = IOUtil.fdVal(fd);
         this.state = ST_UNCONNECTED;
         // Android-added: CloseGuard support.
-        // Net#socket will set |fd| if it succeeds.
         if (fd != null && fd.valid()) {
             guard.open("close");
         }
@@ -371,15 +351,13 @@
             throw new IllegalArgumentException("Read-only buffer");
         if (dst == null)
             throw new NullPointerException();
-        // Android-changed: Do not attempt to bind to 0 (or 0.0.0.0) if there hasn't been
-        // an explicit call to bind() yet. Fail fast and return null.
-        if (localAddress == null)
-            return null;
         synchronized (readLock) {
             ensureOpen();
             // Socket was not bound before attempting receive
-            // if (localAddress() == null)
+            // Android-changed: Do not implicitly to bind to 0 (or 0.0.0.0), return null instead.
+            if (localAddress() == null)
             //     bind(null);
+                return null;
             int n = 0;
             ByteBuffer bb = null;
             try {
@@ -445,6 +423,7 @@
         int newSize = Math.max(rem, 1);
         ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
         try {
+            // Android-added: BlockGuard support.
             BlockGuard.getThreadPolicy().onNetwork();
 
             int n = receiveIntoNativeBuffer(fd, bb, newSize, 0);
@@ -508,6 +487,7 @@
                 if (!isOpen())
                     return 0;
                 writerThread = NativeThread.current();
+                // Android-added: BlockGuard support.
                 BlockGuard.getThreadPolicy().onNetwork();
 
                 do {
@@ -1090,9 +1070,15 @@
         }
     }
 
+    // BEGIN Android-changed: Add CloseGuard support and call superclass finalizer.
+    /*
+    protected void finalize() throws IOException {
+        // fd is null if constructor threw exception
+        if (fd != null)
+            close();
+    */
     protected void finalize() throws Throwable {
         try {
-            // Android-added: CloseGuard support.
             if (guard != null) {
                 guard.warnIfOpen();
             }
@@ -1102,6 +1088,7 @@
         } finally {
             super.finalize();
         }
+        // END Android-changed: Add CloseGuard support and call superclass finalizer.
     }
 
     /**
@@ -1208,6 +1195,8 @@
         throws IOException;
 
     static {
+        // Android removed: Native code initialization not required.
+        // IOUtil.load();
         initIDs();
     }
 
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java b/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
index 328e4ee..d012534 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramDispatcher.java
@@ -37,22 +37,31 @@
 
 class DatagramDispatcher extends NativeDispatcher
 {
+    // Android-removed: Native code initialization not required.
+    // static {
+    //     IOUtil.load();
+    // }
+
     int read(FileDescriptor fd, long address, int len) throws IOException {
+        // Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onNetwork();
         return read0(fd, address, len);
     }
 
     long readv(FileDescriptor fd, long address, int len) throws IOException {
+        // Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onNetwork();
         return readv0(fd, address, len);
     }
 
     int write(FileDescriptor fd, long address, int len) throws IOException {
+        // Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onNetwork();
         return write0(fd, address, len);
     }
 
     long writev(FileDescriptor fd, long address, int len) throws IOException {
+        // Android-added: BlockGuard support.
         BlockGuard.getThreadPolicy().onNetwork();
         return writev0(fd, address, len);
     }
diff --git a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
index d752d1a..a32356f 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
@@ -105,10 +105,11 @@
         this.parent = parent;
         this.path = path;
         this.nd = new FileDispatcherImpl(append);
-        // Android-added: CloseGuard support.
+        // BEGIN Android-added: CloseGuard support.
         if (fd != null && fd.valid()) {
             guard.open("close");
         }
+        // END Android-added: CloseGuard support.
     }
 
     // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel()
@@ -167,6 +168,7 @@
 
     }
 
+    // BEGIN Android-added: CloseGuard support.
     protected void finalize() throws Throwable {
         try {
             if (guard != null) {
@@ -177,6 +179,7 @@
             super.finalize();
         }
     }
+    // END Android-added: CloseGuard support.
 
     public int read(ByteBuffer dst) throws IOException {
         ensureOpen();
@@ -294,9 +297,13 @@
                 ti = threads.add();
                 if (!isOpen())
                     return 0;
+                // BEGIN Android-added: BlockGuard support.
+                // Note: position() itself doesn't seem to block, so this may be overzealous
+                // when position() is not followed by a read/write operation. http://b/77263638
                 if (append) {
                     BlockGuard.getThreadPolicy().onWriteToDisk();
                 }
+                // END Android-added: BlockGuard support.
                 do {
                     // in append-mode then position is advanced to end before writing
                     p = (append) ? nd.size(fd) : position0(fd, -1);
@@ -322,6 +329,9 @@
                 ti = threads.add();
                 if (!isOpen())
                     return null;
+                // Android-added: BlockGuard support.
+                // Note: position() itself doesn't seem to block, so this may be overzealous
+                // when position() is not followed by a read/write operation. http://b/77263638
                 BlockGuard.getThreadPolicy().onReadFromDisk();
                 do {
                     p  = position0(fd, newPosition);
@@ -367,6 +377,7 @@
             int rv = -1;
             long p = -1;
             int ti = -1;
+            long rp = -1;
             try {
                 begin();
                 ti = threads.add();
@@ -402,8 +413,8 @@
                 if (p > newSize)
                     p = newSize;
                 do {
-                    rv = (int)position0(fd, p);
-                } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+                    rp = position0(fd, p);
+                } while ((rp == IOStatus.INTERRUPTED) && isOpen());
                 return this;
             } finally {
                 threads.remove(ti);
@@ -462,6 +473,7 @@
             ti = threads.add();
             if (!isOpen())
                 return -1;
+            // Android-added: BlockGuard support.
             BlockGuard.getThreadPolicy().onWriteToDisk();
             do {
                 n = transferTo0(fd, position, icount, targetFD);
@@ -936,35 +948,13 @@
                 return null;
 
             if (filesize < position + size) { // Extend file size
-                // BEGIN Android-changed
-                /*
                 if (!writable) {
                     throw new IOException("Channel not open for writing " +
                         "- cannot extend file to required size");
                 }
-                */
-                // END Android-changed
-                int rv = 0;
+                int rv;
                 do {
-                    // BEGIN Android-changed
-                    //int rv = nd.truncate(fd, position + size);
-                    try {
-                        rv = nd.truncate(fd, position + size);
-                    } catch (IOException r) {
-                        try {
-                            // If we're dealing with non-regular files, for example,
-                            // character devices such as /dev/zero. In those
-                            // cases, we ignore the failed truncation and continue
-                            // on.
-                            if (android.system.OsConstants.S_ISREG(Libcore.os.fstat(fd).st_mode)) {
-                                throw r;
-                            }
-                        } catch (ErrnoException e) {
-                            e.rethrowAsIOException();
-                        }
-                        break;
-                    }
-                    // END Android-changed
+                    rv = nd.truncate(fd, position + size);
                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
                 if (!isOpen())
                     return null;
@@ -973,6 +963,13 @@
                 addr = 0;
                 // a valid file descriptor is not required
                 FileDescriptor dummy = new FileDescriptor();
+                // Android-changed: Allocate a DirectByteBuffer directly.
+                /*
+                if ((!writable) || (imode == MAP_RO))
+                    return Util.newMappedByteBufferR(0, 0, dummy, null);
+                else
+                    return Util.newMappedByteBuffer(0, 0, dummy, null);
+                */
                 return new DirectByteBuffer(0, 0, dummy, null,
                         (!writable) || (imode == MAP_RO) /* readOnly */);
             }
@@ -981,8 +978,9 @@
             long mapPosition = position - pagePosition;
             long mapSize = size + pagePosition;
             try {
-                // If no exception was thrown from map0, the address is valid
+                // Android-added: BlockGuard support.
                 BlockGuard.getThreadPolicy().onReadFromDisk();
+                // If no exception was thrown from map0, the address is valid
                 addr = map0(imode, mapPosition, mapSize);
             } catch (OutOfMemoryError x) {
                 // An OutOfMemoryError may indicate that we've exhausted memory
@@ -1015,6 +1013,20 @@
             assert (addr % allocationGranularity == 0);
             int isize = (int)size;
             Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
+            // Android-changed: Allocate a DirectByteBuffer directly.
+            /*
+            if ((!writable) || (imode == MAP_RO)) {
+                return Util.newMappedByteBufferR(isize,
+                                                 addr + pagePosition,
+                                                 mfd,
+                                                 um);
+            } else {
+                return Util.newMappedByteBuffer(isize,
+                                                addr + pagePosition,
+                                                mfd,
+                                                um);
+            }
+            */
             return new DirectByteBuffer(isize, addr + pagePosition, mfd, um,
                     (!writable) || (imode == MAP_RO));
         } finally {
@@ -1023,8 +1035,38 @@
         }
     }
 
+    // Android-removed: Unused method getMappedBufferPool().
+    /*
+    /**
+     * Invoked by sun.management.ManagementFactoryHelper to create the management
+     * interface for mapped buffers.
+     *
+    public static sun.misc.JavaNioAccess.BufferPool getMappedBufferPool() {
+        return new sun.misc.JavaNioAccess.BufferPool() {
+            @Override
+            public String getName() {
+                return "mapped";
+            }
+            @Override
+            public long getCount() {
+                return Unmapper.count;
+            }
+            @Override
+            public long getTotalCapacity() {
+                return Unmapper.totalCapacity;
+            }
+            @Override
+            public long getMemoryUsed() {
+                return Unmapper.totalSize;
+            }
+        };
+    }
+    */
+
     // -- Locks --
 
+
+
     // keeps track of locks on this file
     private volatile FileLockTable fileLockTable;
 
@@ -1245,6 +1287,8 @@
     private static native long initIDs();
 
     static {
+        // Android-removed: Move clinit code to JNI registration functions.
+        // IOUtil.load();
         allocationGranularity = initIDs();
     }
 
diff --git a/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
index d7a9fc6..852b738 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * 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
diff --git a/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java b/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
index 17c9f03..1911c35 100644
--- a/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/PollSelectorImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -57,9 +57,23 @@
         long pipeFds = IOUtil.makePipe(false);
         fd0 = (int) (pipeFds >>> 32);
         fd1 = (int) pipeFds;
-        pollWrapper = new PollArrayWrapper(INIT_CAP);
-        pollWrapper.initInterrupt(fd0, fd1);
-        channelArray = new SelectionKeyImpl[INIT_CAP];
+        try {
+            pollWrapper = new PollArrayWrapper(INIT_CAP);
+            pollWrapper.initInterrupt(fd0, fd1);
+            channelArray = new SelectionKeyImpl[INIT_CAP];
+        } catch (Throwable t) {
+            try {
+                FileDispatcherImpl.closeIntFD(fd0);
+            } catch (IOException ioe0) {
+                t.addSuppressed(ioe0);
+            }
+            try {
+                FileDispatcherImpl.closeIntFD(fd1);
+            } catch (IOException ioe1) {
+                t.addSuppressed(ioe1);
+            }
+            throw t;
+        }
     }
 
     protected int doSelect(long timeout)
diff --git a/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java b/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
index 9ea18c9..d4ce6a1 100644
--- a/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
+++ b/ojluni/src/main/java/sun/nio/ch/PollSelectorProvider.java
@@ -36,8 +36,9 @@
         return new PollSelectorImpl(this);
     }
 
-    // Android-changed: Android never has stdin/stdout connected to a socket.
-    // public Channel inheritedChannel() throws IOException {
-    //     return InheritedChannel.getChannel();
-    // }
+    public Channel inheritedChannel() throws IOException {
+        // Android-changed: Android never has stdin/stdout connected to a socket.
+        // return InheritedChannel.getChannel();
+        return null;
+    }
 }
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
index a2aba2d..d07134f 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
@@ -27,11 +27,13 @@
 package sun.nio.ch;
 
 import java.io.*;
+import java.lang.ref.*;
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
+import java.util.*;
 
 
 // Make a socket channel look like a socket.
@@ -57,6 +59,7 @@
     private volatile int timeout = 0;
 
     private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
+        // Android-changed: Conscrypt compatibility, ensure fd is not null. http://b/25857624
         super(new FileDescriptorHolderSocketImpl(sc.getFD()));
         this.sc = sc;
     }
@@ -92,7 +95,8 @@
             try {
 
                 if (timeout == 0) {
-                    // Android-changed: Be consistent
+                    // Android-changed: Translate exceptions consistently.
+                    // sc.connect(remote);
                     try {
                         sc.connect(remote);
                     } catch (Exception ex) {
@@ -144,8 +148,7 @@
     }
 
     public InetAddress getInetAddress() {
-        // Use #remoteAddress and do manual isConnected check. #getRemoteAddress() returns
-        // non-null result before connection.
+        // Android-changed: remoteAddress() returns non-null before connection. http://b/26140820
         if (!isConnected()) {
             return null;
         }
@@ -168,8 +171,7 @@
     }
 
     public int getPort() {
-        // Use #remoteAddress and do manual isConnected check. #getRemoteAddress() returns
-        // non-null result before connection.
+        // Android-changed: remoteAddress() returns non-null before connection. http://b/26140820
         if (!isConnected()) {
           return 0;
         }
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java b/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
index f660f9d..6c53b09 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketOptionRegistry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009,  Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -57,7 +57,7 @@
         static final Map<RegistryKey,OptionKey> options = options();           
         private static Map<RegistryKey,OptionKey> options() {                  
             Map<RegistryKey,OptionKey> map =                                   
-                new HashMap<RegistryKey,OptionKey>();
+                new HashMap<RegistryKey,OptionKey>();                          
             map.put(new RegistryKey(StandardSocketOptions.SO_BROADCAST, Net.UNSPEC), new OptionKey(1, 6));
             map.put(new RegistryKey(StandardSocketOptions.SO_KEEPALIVE, Net.UNSPEC), new OptionKey(1, 9));
             map.put(new RegistryKey(StandardSocketOptions.SO_LINGER, Net.UNSPEC), new OptionKey(1, 13));
@@ -74,7 +74,7 @@
             map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET6), new OptionKey(41, 18));
             map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET6), new OptionKey(41, 19));
             map.put(new RegistryKey(ExtendedSocketOption.SO_OOBINLINE, Net.UNSPEC), new OptionKey(1, 10));
-            return map;
+            return map;                                                        
         }                                                                      
     }                                                                          
     public static OptionKey findOption(SocketOption<?> name, ProtocolFamily family) { 
diff --git a/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
index a80b540..759a60b 100644
--- a/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/SourceChannelImpl.java
@@ -156,6 +156,7 @@
     }
 
     public int read(ByteBuffer dst) throws IOException {
+        // Android-added: Throw NPE if null ByteBuffer passed to read().
         if (dst == null) {
             throw new NullPointerException();
         }
diff --git a/ojluni/src/main/java/sun/nio/ch/Util.java b/ojluni/src/main/java/sun/nio/ch/Util.java
index 6b82112..fa0b631 100644
--- a/ojluni/src/main/java/sun/nio/ch/Util.java
+++ b/ojluni/src/main/java/sun/nio/ch/Util.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 
 import java.nio.ByteBuffer;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.*;
 import sun.misc.Unsafe;
 import sun.misc.Cleaner;
@@ -41,6 +42,9 @@
     // The number of temp buffers in our pool
     private static final int TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX;
 
+    // The max size allowed for a cached temp buffer, in bytes
+    private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
+
     // Per-thread cache of temporary direct buffers
     private static ThreadLocal<BufferCache> bufferCache =
         new ThreadLocal<BufferCache>()
@@ -52,6 +56,52 @@
     };
 
     /**
+     * Returns the max size allowed for a cached temp buffers, in
+     * bytes. It defaults to Long.MAX_VALUE. It can be set with the
+     * jdk.nio.maxCachedBufferSize property. Even though
+     * ByteBuffer.capacity() returns an int, we're using a long here
+     * for potential future-proofing.
+     */
+    private static long getMaxCachedBufferSize() {
+        String s = java.security.AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                    return System.getProperty("jdk.nio.maxCachedBufferSize");
+                }
+            });
+        if (s != null) {
+            try {
+                long m = Long.parseLong(s);
+                if (m >= 0) {
+                    return m;
+                } else {
+                    // if it's negative, ignore the system property
+                }
+            } catch (NumberFormatException e) {
+                // if the string is not well formed, ignore the system property
+            }
+        }
+        return Long.MAX_VALUE;
+    }
+
+    /**
+     * Returns true if a buffer of this size is too large to be
+     * added to the buffer cache, false otherwise.
+     */
+    private static boolean isBufferTooLarge(int size) {
+        return size > MAX_CACHED_BUFFER_SIZE;
+    }
+
+    /**
+     * Returns true if the buffer is too large to be added to the
+     * buffer cache, false otherwise.
+     */
+    private static boolean isBufferTooLarge(ByteBuffer buf) {
+        return isBufferTooLarge(buf.capacity());
+    }
+
+    /**
      * A simple cache of direct buffers.
      */
     private static class BufferCache {
@@ -77,6 +127,9 @@
          * size (or null if no suitable buffer is found).
          */
         ByteBuffer get(int size) {
+            // Don't call this if the buffer would be too large.
+            assert !isBufferTooLarge(size);
+
             if (count == 0)
                 return null;  // cache is empty
 
@@ -114,6 +167,9 @@
         }
 
         boolean offerFirst(ByteBuffer buf) {
+            // Don't call this if the buffer is too large.
+            assert !isBufferTooLarge(buf);
+
             if (count >= TEMP_BUF_POOL_SIZE) {
                 return false;
             } else {
@@ -125,6 +181,9 @@
         }
 
         boolean offerLast(ByteBuffer buf) {
+            // Don't call this if the buffer is too large.
+            assert !isBufferTooLarge(buf);
+
             if (count >= TEMP_BUF_POOL_SIZE) {
                 return false;
             } else {
@@ -153,6 +212,15 @@
      * Returns a temporary buffer of at least the given size
      */
     public static ByteBuffer getTemporaryDirectBuffer(int size) {
+        // If a buffer of this size is too large for the cache, there
+        // should not be a buffer in the cache that is at least as
+        // large. So we'll just create a new one. Also, we don't have
+        // to remove the buffer from the cache (as this method does
+        // below) given that we won't put the new buffer in the cache.
+        if (isBufferTooLarge(size)) {
+            return ByteBuffer.allocateDirect(size);
+        }
+
         BufferCache cache = bufferCache.get();
         ByteBuffer buf = cache.get(size);
         if (buf != null) {
@@ -182,6 +250,13 @@
      * likely to be returned by a subsequent call to getTemporaryDirectBuffer.
      */
     static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
+        // If the buffer is too large for the cache we don't have to
+        // check the cache. We'll just free it.
+        if (isBufferTooLarge(buf)) {
+            free(buf);
+            return;
+        }
+
         assert buf != null;
         BufferCache cache = bufferCache.get();
         if (!cache.offerFirst(buf)) {
@@ -197,6 +272,13 @@
      * cache in same order that they were obtained.
      */
     static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
+        // If the buffer is too large for the cache we don't have to
+        // check the cache. We'll just free it.
+        if (isBufferTooLarge(buf)) {
+            free(buf);
+            return;
+        }
+
         assert buf != null;
         BufferCache cache = bufferCache.get();
         if (!cache.offerLast(buf)) {
@@ -209,6 +291,8 @@
      * Frees the memory for the given direct buffer
      */
     private static void free(ByteBuffer buf) {
+        // Android-changed: Add null check for cleaner. http://b/26040655
+        // ((DirectBuffer)buf).cleaner().clean();
         Cleaner cleaner = ((DirectBuffer)buf).cleaner();
         if (cleaner != null) {
             cleaner.clean();
@@ -284,6 +368,8 @@
         return unsafe;
     }
 
+    // BEGIN Android-removed: DirectByteBuffer is @hide public on Android so reflection unneeded.
+    /*
     private static int pageSize = -1;
 
     static int pageSize() {
@@ -292,7 +378,100 @@
         return pageSize;
     }
 
+    private static volatile Constructor<?> directByteBufferConstructor = null;
+
+    private static void initDBBConstructor() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
+                        Constructor<?> ctor = cl.getDeclaredConstructor(
+                            new Class<?>[] { int.class,
+                                             long.class,
+                                             FileDescriptor.class,
+                                             Runnable.class });
+                        ctor.setAccessible(true);
+                        directByteBufferConstructor = ctor;
+                    } catch (ClassNotFoundException   |
+                             NoSuchMethodException    |
+                             IllegalArgumentException |
+                             ClassCastException x) {
+                        throw new InternalError(x);
+                    }
+                    return null;
+                }});
+    }
+
+    static MappedByteBuffer newMappedByteBuffer(int size, long addr,
+                                                FileDescriptor fd,
+                                                Runnable unmapper)
+    {
+        MappedByteBuffer dbb;
+        if (directByteBufferConstructor == null)
+            initDBBConstructor();
+        try {
+            dbb = (MappedByteBuffer)directByteBufferConstructor.newInstance(
+              new Object[] { new Integer(size),
+                             new Long(addr),
+                             fd,
+                             unmapper });
+        } catch (InstantiationException |
+                 IllegalAccessException |
+                 InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+        return dbb;
+    }
+
+    private static volatile Constructor<?> directByteBufferRConstructor = null;
+
+    private static void initDBBRConstructor() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
+                        Constructor<?> ctor = cl.getDeclaredConstructor(
+                            new Class<?>[] { int.class,
+                                             long.class,
+                                             FileDescriptor.class,
+                                             Runnable.class });
+                        ctor.setAccessible(true);
+                        directByteBufferRConstructor = ctor;
+                    } catch (ClassNotFoundException |
+                             NoSuchMethodException |
+                             IllegalArgumentException |
+                             ClassCastException x) {
+                        throw new InternalError(x);
+                    }
+                    return null;
+                }});
+    }
+
+    static MappedByteBuffer newMappedByteBufferR(int size, long addr,
+                                                 FileDescriptor fd,
+                                                 Runnable unmapper)
+    {
+        MappedByteBuffer dbb;
+        if (directByteBufferRConstructor == null)
+            initDBBRConstructor();
+        try {
+            dbb = (MappedByteBuffer)directByteBufferRConstructor.newInstance(
+              new Object[] { new Integer(size),
+                             new Long(addr),
+                             fd,
+                             unmapper });
+        } catch (InstantiationException |
+                 IllegalAccessException |
+                 InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+        return dbb;
+    }
+    */
+    // END Android-removed: DirectByteBuffer is @hide public on Android so reflection unneeded.
+
     // -- Bug compatibility --
+
     private static volatile String bugLevel = null;
 
     static boolean atBugLevel(String bl) {              // package-private
diff --git a/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java b/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
index 3cdf45b..8a2335e 100644
--- a/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
+++ b/ojluni/src/main/java/sun/nio/cs/StreamDecoder.java
@@ -54,6 +54,7 @@
     private boolean haveLeftoverChar = false;
     private char leftoverChar;
 
+    // Android-added: Flush the CharsetDecoder correctly.
     private boolean needsFlush = false;
 
     // Factories for java.io.InputStreamReader
@@ -273,9 +274,11 @@
         try {
         if (ch != null) {
             // Read from the channel
-            // Android-changed: Use ChannelInputStream.read to make sure we throw
-            // the right exception for non-blocking channels.
-            int n = sun.nio.ch.ChannelInputStream.read(ch, bb);
+            // Android-changed: Use ChannelInputStream.read which throws on non-blocking channels.
+            // Other implementations of ReadableByteChannel.read do not, and Channels.newReader
+            // is documented to throw on non-blocking.
+            // int n = ch.read(bb);
+            int n = sun.nio.ch.ChannelInputStream.read(ch, bb, true);
             if (n < 0)
                 return n;
         } else {
@@ -317,7 +320,7 @@
         // Ensure that cb[0] == cbuf[off]
         cb = cb.slice();
 
-        // Android-changed: Support flushing the buffer properly.
+        // BEGIN Android-added: Flush the CharsetDecoder correctly.
         if (needsFlush) {
             CoderResult cr = decoder.flush(cb);
             if (cr.isOverflow()) {
@@ -337,6 +340,7 @@
             cr.throwException();
             // Unreachable.
         }
+        // END Android-added: Flush the CharsetDecoder properly.
 
         boolean eof = false;
         for (;;) {
@@ -351,10 +355,10 @@
             int n = readBytes();
             if (n < 0) {
                 eof = true;
-                // Android-changed: We want to go 'round the loop one more time
-                // with "eof = true". We also don't want to reset the decoder here
-                // because we might potentially need to flush it later.
-                //
+                // Android-removed: Flush the CharsetDecoder correctly.
+                // We want to go 'round the loop one more time with "eof = true".
+                // We also don't want to reset the decoder here because we might potentially need
+                // to flush it later.
                 // if ((cb.position() == 0) && (!bb.hasRemaining()))
                 //     break;
                 //  decoder.reset();
@@ -369,6 +373,9 @@
         }
 
         if (eof) {
+            // BEGIN Android-changed: Flush the CharsetDecoder correctly.
+            // // ## Need to flush decoder
+            // decoder.reset();
             CoderResult cr = decoder.flush(cb);
             if (cr.isOverflow()) {
                 needsFlush = true;
@@ -379,6 +386,7 @@
             if (!cr.isUnderflow()) {
                 cr.throwException();
             }
+            // END Android-changed: Flush the CharsetDecoder correctly.
         }
 
         if (cb.position() == 0) {
diff --git a/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java b/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
index 44f7d16..a395370 100644
--- a/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
+++ b/ojluni/src/main/java/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
@@ -70,10 +70,9 @@
             if (unsafe.getByte(address + pos) == 0) {
                 int len = pos - start;
                 byte[] value = new byte[len];
+                // Android-changed: We don't have Unsafe.copyMemory yet, so we use getByte.
                 // unsafe.copyMemory(null, address+start, value,
                 //     Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
-
-                // Android-changed: We don't have Unsafe.copyMemory yet, so we use getByte.
                 for (int i = 0; i < len; i++) {
                     value[i] = unsafe.getByte(address + start + i);
                 }
diff --git a/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java b/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
index 5044045..db61c8d 100644
--- a/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
+++ b/ojluni/src/main/java/sun/nio/fs/LinuxWatchService.java
@@ -25,25 +25,18 @@
 
 package sun.nio.fs;
 
+import java.nio.file.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
 import java.io.IOException;
-import java.nio.file.NotDirectoryException;
-import java.nio.file.Path;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchEvent;
-import java.nio.file.WatchKey;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
 import dalvik.system.CloseGuard;
 import sun.misc.Unsafe;
 
-import static sun.nio.fs.UnixConstants.EAGAIN;
-import static sun.nio.fs.UnixConstants.EMFILE;
-import static sun.nio.fs.UnixConstants.ENOSPC;
-import static sun.nio.fs.UnixNativeDispatcher.read;
-import static sun.nio.fs.UnixNativeDispatcher.write;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
 
 /**
  * Linux implementation of WatchService based on inotify.
@@ -388,14 +381,13 @@
                             }
                             if (actual > 0) {
                                 byte[] buf = new byte[actual];
+                                // BEGIN Android-changed: Use Unsafe.getByte not Unsafe.copyMemory.
                                 // unsafe.copyMemory(null, event + OFFSETOF_NAME,
                                 //    buf, Unsafe.ARRAY_BYTE_BASE_OFFSET, actual);
-
-                                // Android-changed: We don't have Unsafe.copyMemory yet, so we use
-                                // getByte.
                                 for(int i = 0; i < actual; i++) {
                                     buf[i] = unsafe.getByte(event + OFFSETOF_NAME + i);
                                 }
+                                // END Android-changed: Use Unsafe.getByte not Unsafe.copyMemory.
                                 name = new UnixPath(fs, buf);
                             }
                         }
diff --git a/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java b/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
index 1815239..1c8f708 100644
--- a/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
+++ b/ojluni/src/main/java/sun/nio/fs/MimeTypesFileTypeDetector.java
@@ -25,7 +25,18 @@
 
 package sun.nio.fs;
 
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.nio.file.Path;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import libcore.net.MimeUtils;
 
 /**
@@ -35,6 +46,24 @@
 
 class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
 
+    // BEGIN Android-removed: Delegate to libcore.net.MimeUtils.
+    /*
+    // path to mime.types file
+    private final Path mimeTypesFile;
+
+    // map of extension to MIME type
+    private Map<String,String> mimeTypeMap;
+
+    // set to true when file loaded
+    private volatile boolean loaded = false;
+
+    public MimeTypesFileTypeDetector(Path filePath) {
+        mimeTypesFile = filePath;
+    }
+    */
+    // END Android-removed: Delegate to libcore.net.MimeUtils.
+
+
     @Override
     protected String implProbeContentType(Path path) {
         Path fn = path.getFileName();
@@ -45,10 +74,18 @@
         if (ext.isEmpty())
             return null;  // no extension
 
+        // Android-removed: Delegate to libcore.net.MimeUtils.
+        // loadMimeTypes();
+        // if (mimeTypeMap == null || mimeTypeMap.isEmpty())
+        //    return null;
+
         // Case-sensitive search
         String mimeType;
         do {
+            // BEGIN Android-changed: Delegate to libcore.net.MimeUtils.
+            // mimeType = mimeTypeMap.get(ext);
             mimeType = MimeUtils.guessMimeTypeFromExtension(ext);
+            // END Android-changed: Delegate to libcore.net.MimeUtils.
             if (mimeType == null)
                 ext = getExtension(ext);
         } while (mimeType == null && !ext.isEmpty());
@@ -67,4 +104,119 @@
         }
         return ext;
     }
+
+    // BEGIN Android-removed: Delegate to libcore.net.MimeUtils.
+    /*
+    /**
+     * Parse the mime types file, and store the type-extension mappings into
+     * mimeTypeMap. The mime types file is not loaded until the first probe
+     * to achieve the lazy initialization. It adopts double-checked locking
+     * optimization to reduce the locking overhead.
+     *
+    private void loadMimeTypes() {
+        if (!loaded) {
+            synchronized (this) {
+                if (!loaded) {
+                    List<String> lines = AccessController.doPrivileged(
+                        new PrivilegedAction<List<String>>() {
+                            @Override
+                            public List<String> run() {
+                                try {
+                                    return Files.readAllLines(mimeTypesFile,
+                                                              Charset.defaultCharset());
+                                } catch (IOException ignore) {
+                                    return Collections.emptyList();
+                                }
+                            }
+                        });
+
+                    mimeTypeMap = new HashMap<>(lines.size());
+                    String entry = "";
+                    for (String line : lines) {
+                        entry += line;
+                        if (entry.endsWith("\\")) {
+                            entry = entry.substring(0, entry.length() - 1);
+                            continue;
+                        }
+                        parseMimeEntry(entry);
+                        entry = "";
+                    }
+                    if (!entry.isEmpty()) {
+                        parseMimeEntry(entry);
+                    }
+                    loaded = true;
+                }
+            }
+        }
+    }
+
+    /**
+     * Parse a mime-types entry, which can have the following formats.
+     * 1) Simple space-delimited format
+     * image/jpeg   jpeg jpg jpe JPG
+     *
+     * 2) Netscape key-value pair format
+     * type=application/x-java-jnlp-file desc="Java Web Start" exts="jnlp"
+     * or
+     * type=text/html exts=htm,html
+     *
+    private void parseMimeEntry(String entry) {
+        entry = entry.trim();
+        if (entry.isEmpty() || entry.charAt(0) == '#')
+            return;
+
+        entry = entry.replaceAll("\\s*#.*", "");
+        int equalIdx = entry.indexOf('=');
+        if (equalIdx > 0) {
+            // Parse a mime-types command having the key-value pair format
+            final String TYPEEQUAL = "type=";
+            String typeRegex = "\\b" + TYPEEQUAL +
+                    "(\"\\p{Graph}+?/\\p{Graph}+?\"|\\p{Graph}+/\\p{Graph}+\\b)";
+            Pattern typePattern = Pattern.compile(typeRegex);
+            Matcher typeMatcher = typePattern.matcher(entry);
+
+            if (typeMatcher.find()) {
+                String type = typeMatcher.group().substring(TYPEEQUAL.length());
+                if (type.charAt(0) == '"') {
+                    type = type.substring(1, type.length() - 1);
+                }
+
+                final String EXTEQUAL = "exts=";
+                String extRegex = "\\b" + EXTEQUAL +
+                        "(\"[\\p{Graph}\\p{Blank}]+?\"|\\p{Graph}+\\b)";
+                Pattern extPattern = Pattern.compile(extRegex);
+                Matcher extMatcher = extPattern.matcher(entry);
+
+                if (extMatcher.find()) {
+                    String exts =
+                            extMatcher.group().substring(EXTEQUAL.length());
+                    if (exts.charAt(0) == '"') {
+                        exts = exts.substring(1, exts.length() - 1);
+                    }
+                    String[] extList = exts.split("[\\p{Blank}\\p{Punct}]+");
+                    for (String ext : extList) {
+                        putIfAbsent(ext, type);
+                    }
+                }
+            }
+        } else {
+            // Parse a mime-types command having the space-delimited format
+            String[] elements = entry.split("\\s+");
+            int i = 1;
+            while (i < elements.length) {
+                putIfAbsent(elements[i++], elements[0]);
+            }
+        }
+    }
+
+    private void putIfAbsent(String key, String value) {
+        if (key != null && !key.isEmpty() &&
+            value != null && !value.isEmpty() &&
+            !mimeTypeMap.containsKey(key))
+        {
+            mimeTypeMap.put(key, value);
+        }
+    }
+    */
+    // END Android-removed: Delegate to libcore.net.MimeUtils.
 }
diff --git a/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java b/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
index ee6969c..dcdfdf2 100644
--- a/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
+++ b/ojluni/src/main/java/sun/nio/fs/NativeBuffers.java
@@ -121,18 +121,17 @@
      * Copies a byte array and zero terminator into a given native buffer.
      */
     static void copyCStringToNativeBuffer(byte[] cstr, NativeBuffer buffer) {
+        // Android-removed: We don't have Unsafe.copyMemory yet, so use putByte.
         // long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET;
-        // long len = cstr.length;
-        // assert buffer.size() >= (len + 1);
-        // unsafe.copyMemory(cstr, offset, null, buffer.address(), len);
-        // unsafe.putByte(buffer.address() + len, (byte)0);
 
-        // Android-changed: We don't have Unsafe.copyMemory yet, so we use putByte.
         long len = cstr.length;
         assert buffer.size() >= (len + 1);
+        // BEGIN Android-changed: We don't have Unsafe.copyMemory yet, so use putByte.
+        // unsafe.copyMemory(cstr, offset, null, buffer.address(), len);
         for (int i = 0; i < len; ++i) {
             unsafe.putByte(buffer.address() + i, cstr[i]);
         }
+        // END Android-changed: We don't have Unsafe.copyMemory yet, so use putByte.
         unsafe.putByte(buffer.address() + len, (byte)0);
     }
 
diff --git a/ojluni/src/main/java/sun/nio/fs/UnixConstants.java b/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
index a6d3bbd..d197ee2 100644
--- a/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
+++ b/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
@@ -27,22 +27,15 @@
 // AUTOMATICALLY GENERATED FILE - DO NOT EDIT
 package sun.nio.fs;
 
+// BEGIN Android-changed: Use constants from android.system.OsConstants. http://b/32203242
+// Those constants are initialized by native code to ensure correctness on different architectures.
+// AT_SYMLINK_NOFOLLOW (used by fstatat) and AT_REMOVEDIR (used by unlinkat) as of July 2018 do not
+// have equivalents in android.system.OsConstants so left unchanged.
 import android.system.OsConstants;
 
-import java.io.ObjectStreamClass;
-
 class UnixConstants {
+    private UnixConstants() { }
 
-    private UnixConstants() {
-    }
-
-    // Android-changed (http://b/32203242): Instead of maintaining a separate set of UnixConstants,
-    // use the values from android.system.OsConstants.  AT_SYMLINK_NOFOLLOW is used by fstatat when
-    // a symbolic link is passed. With AT_SYMLINK_NOLLOW, it doesn't dereference and instead return
-    // information about the link, and with it, returns the information about the target. There is
-    // no suitable alternative for the flag in android.system.OsConstant, therefore, left untouched.
-    // With AT_REMOVEDIR, unlinkat works equivalent to rmdir. Again there is no suitable alternative
-    // for the flag in android.system.OsConstant, therefore, left unchanged.
     static final int O_RDONLY = OsConstants.O_RDONLY;
 
     static final int O_WRONLY = OsConstants.O_WRONLY;
@@ -137,10 +130,6 @@
 
     static final int EMFILE = OsConstants.EMFILE;
 
-    static final int AT_SYMLINK_NOFOLLOW = 0x100;
-
-    static final int AT_REMOVEDIR = 0x200;
-
     // S_IAMB are access mode bits, therefore, calculated by taking OR of all the read, write and
     // execute permissions bits for owner, group and other.
     private static int get_S_IAMB() {
@@ -148,4 +137,9 @@
                 OsConstants.S_IRGRP | OsConstants.S_IWGRP | OsConstants.S_IXGRP |
                 OsConstants.S_IROTH | OsConstants.S_IWOTH | OsConstants.S_IXOTH);
     }
-}
+    // END Android-changed: Use constants from android.system.OsConstants. http://b/32203242
+
+
+    static final int AT_SYMLINK_NOFOLLOW = 0x100;
+    static final int AT_REMOVEDIR = 0x200;
+}                                                                              
diff --git a/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java b/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
index 98fc9ab..0532e4d 100644
--- a/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
+++ b/ojluni/src/main/java/sun/nio/fs/UnixFileStore.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -186,7 +186,8 @@
             return false;
         UnixFileStore other = (UnixFileStore)ob;
         return (this.dev == other.dev) &&
-               Arrays.equals(this.entry.dir(), other.entry.dir());
+               Arrays.equals(this.entry.dir(), other.entry.dir()) &&
+               this.entry.name().equals(other.entry.name());
     }
 
     @Override
diff --git a/ojluni/src/main/java/sun/nio/fs/Util.java b/ojluni/src/main/java/sun/nio/fs/Util.java
index fdd6ccc..08a3025 100644
--- a/ojluni/src/main/java/sun/nio/fs/Util.java
+++ b/ojluni/src/main/java/sun/nio/fs/Util.java
@@ -38,6 +38,8 @@
 class Util {
     private Util() { }
 
+    // Android-changed: Hard-code UTF-8 for jnuEncoding rather than requiring a system property.
+    // The system property sun.jnu.encoding is not set on Android; we just hard-code "UTF-8" here.
     // private static final Charset jnuEncoding = Charset.forName(
     //    AccessController.doPrivileged(new GetPropertyAction("sun.jnu.encoding")));
     private static final Charset jnuEncoding = Charset.forName("UTF-8");
diff --git a/ojluni/src/main/java/sun/reflect/Reflection.java b/ojluni/src/main/java/sun/reflect/Reflection.java
index bb82b43..9c6c0cc 100644
--- a/ojluni/src/main/java/sun/reflect/Reflection.java
+++ b/ojluni/src/main/java/sun/reflect/Reflection.java
@@ -30,12 +30,82 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import dalvik.system.VMStack;
+
 /** Common utility routines used by both java.lang and
     java.lang.reflect */
 
 public class Reflection {
 
-    // Android-removed: Dead code: Misc unused fields and methods.
+    // Android-removed: Dead code.
+    /*
+    /** Used to filter out fields and methods from certain classes from public
+        view, where they are sensitive or they may contain VM-internal objects.
+        These Maps are updated very rarely. Rather than synchronize on
+        each access, we use copy-on-write *
+    private static volatile Map<Class<?>,String[]> fieldFilterMap;
+    private static volatile Map<Class<?>,String[]> methodFilterMap;
+
+    static {
+        Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
+        map.put(Reflection.class,
+            new String[] {"fieldFilterMap", "methodFilterMap"});
+        map.put(System.class, new String[] {"security"});
+        map.put(Class.class, new String[] {"classLoader"});
+        fieldFilterMap = map;
+
+        methodFilterMap = new HashMap<>();
+    }
+   */
+
+    // BEGIN Android-changed: getCallerClass() reimplementation.
+    // As of 2018-07 this implementation does not ignore frames
+    // associated with java.lang.reflect.Method.invoke() but this
+    // may change in future, see http://b/111800372 .
+    // Only code that expects or can handle the RI behavior (eg.
+    // code inherited from the RI) should call this method.
+    /*
+    /** Returns the class of the caller of the method calling this method,
+        ignoring frames associated with java.lang.reflect.Method.invoke()
+        and its implementation. *
+    @CallerSensitive
+    public static native Class<?> getCallerClass();
+    */
+    public static Class<?> getCallerClass() {
+        // This method (getCallerClass()) constitutes another stack frame,
+        // so we need to call getStackClass2() rather than getStackClass1().
+        return VMStack.getStackClass2();
+    }
+    // END Android-changed: getCallerClass() reimplementation.
+
+    // Android-removed: Dead code.
+    /*
+    /**
+     * @deprecated This method will be removed in JDK 9.
+     * This method is a private JDK API and retained temporarily for
+     * existing code to run until a replacement API is defined.
+     *
+    @Deprecated
+    public static native Class<?> getCallerClass(int depth);
+
+    /** Retrieves the access flags written to the class file. For
+        inner classes these flags may differ from those returned by
+        Class.getModifiers(), which searches the InnerClasses
+        attribute to find the source-level access flags. This is used
+        instead of Class.getModifiers() for run-time access checks due
+        to compatibility reasons; see 4471811. Only the values of the
+        low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
+        valid. *
+    public static native int getClassAccessFlags(Class<?> c);
+
+    /** A quick "fast-path" check to try to avoid getCallerClass()
+        calls. *
+    public static boolean quickCheckMemberAccess(Class<?> memberClass,
+                                                 int modifiers)
+    {
+        return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
+    }
+    */
 
     public static void ensureMemberAccess(Class<?> currentClass,
                                           Class<?> memberClass,
@@ -77,7 +147,10 @@
             return true;
         }
 
-        // Android-changed
+        // Android-changed: verifyMemberAccess() consistent with class.getAccessFlags(T).
+        // The RI carries a separate getClassAccessFlags(Class) utility method
+        // with slightly different behavior for backwards compatibility. This
+        // does not apply on Android since the RI code was never adopted.
         // if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
         if (!Modifier.isPublic(memberClass.getAccessFlags())) {
             isSameClassPackage = isSameClassPackage(currentClass, memberClass);
@@ -204,6 +277,6 @@
         return false;
     }
 
-    // Android-removed: Dead code: Misc unused methods.
+    // Android-removed: Dead code.
 
 }
diff --git a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
index 5896f15..b4fdf70 100644
--- a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
+++ b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
@@ -26,7 +26,10 @@
 
 
 package sun.reflect.misc;
+
+import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
+import sun.reflect.Reflection;
 
 public final class ReflectUtil {
 
@@ -45,7 +48,61 @@
         return cls.newInstance();
     }
 
-    // Android-removed: Dead code: Unused method ensureMemberAccess()
+    /*
+     * Reflection.ensureMemberAccess is overly-restrictive
+     * due to a bug. We awkwardly work around it for now.
+     */
+    public static void ensureMemberAccess(Class<?> currentClass,
+                                          Class<?> memberClass,
+                                          Object target,
+                                          int modifiers)
+        throws IllegalAccessException
+    {
+        if (target == null && Modifier.isProtected(modifiers)) {
+            int mods = modifiers;
+            mods = mods & (~Modifier.PROTECTED);
+            mods = mods | Modifier.PUBLIC;
+
+            /*
+             * See if we fail because of class modifiers
+             */
+            Reflection.ensureMemberAccess(currentClass,
+                                          memberClass,
+                                          target,
+                                          mods);
+            try {
+                /*
+                 * We're still here so class access was ok.
+                 * Now try with default field access.
+                 */
+                mods = mods & (~Modifier.PUBLIC);
+                Reflection.ensureMemberAccess(currentClass,
+                                              memberClass,
+                                              target,
+                                              mods);
+                /*
+                 * We're still here so access is ok without
+                 * checking for protected.
+                 */
+                return;
+            } catch (IllegalAccessException e) {
+                /*
+                 * Access failed but we're 'protected' so
+                 * if the test below succeeds then we're ok.
+                 */
+                if (isSubclassOf(currentClass, memberClass)) {
+                    return;
+                } else {
+                    throw e;
+                }
+            }
+        } else {
+            Reflection.ensureMemberAccess(currentClass,
+                                          memberClass,
+                                          target,
+                                          modifiers);
+        }
+    }
 
     private static boolean isSubclassOf(Class<?> queryClass,
                                         Class<?> ofClass)
diff --git a/ojluni/src/main/java/sun/security/jca/Providers.java b/ojluni/src/main/java/sun/security/jca/Providers.java
index fd8d9c8..a9634f0 100644
--- a/ojluni/src/main/java/sun/security/jca/Providers.java
+++ b/ojluni/src/main/java/sun/security/jca/Providers.java
@@ -567,5 +567,6 @@
             }
         }
     }
+    // END Android-added: Check for requests of deprecated Bouncy Castle algorithms.
 
 }
diff --git a/ojluni/src/main/native/Android.bp b/ojluni/src/main/native/Android.bp
index 71546ca..7c77ee9 100644
--- a/ojluni/src/main/native/Android.bp
+++ b/ojluni/src/main/native/Android.bp
@@ -1,10 +1,10 @@
 filegroup {
     name: "libopenjdk_native_srcs",
     srcs: [
-        "java_util_zip_ZipFile.c",
-        "java_util_zip_Inflater.c",
-        "java_util_zip_Deflater.c",
-        "java_util_zip_CRC32.c",
+        "ZipFile.c",
+        "Inflater.c",
+        "Deflater.c",
+        "CRC32.c",
         "Adler32.c",
         "zip_util.c",
         "jni_util.c",
@@ -57,9 +57,8 @@
         "System.c",
         "Runtime.c",
         "UNIXProcess_md.c",
-        "Bits.c",
         "Character.cpp",
-        "Register.cpp",
         "socket_tagger_util.cpp",
+        "OnLoad.cpp",
     ],
 }
diff --git a/ojluni/src/main/native/Bits.c b/ojluni/src/main/native/Bits.c
deleted file mode 100644
index 50caf36..0000000
--- a/ojluni/src/main/native/Bits.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/*
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include <string.h>
-
-#include <nativehelper/JNIHelp.h>
-
-/*
- * WARNING:
- *
- * Do not replace instances of:
- *
- *   if (length > MBYTE)
- *     size = MBYTE;
- *   else
- *     size = length;
- *
- * with
- *
- *   size = (length > MBYTE ? MBYTE : length);
- *
- * This expression causes a c compiler assertion failure when compiling on
- * 32-bit sparc.
- */
-
-#define MBYTE 1048576
-
-#define GETCRITICAL(bytes, env, obj) { \
-    (bytes) = (*(env))->GetPrimitiveArrayCritical(env, obj, NULL); \
-    if ((bytes) == NULL) \
-        JNU_ThrowInternalError(env, "Unable to get array"); \
-}
-
-#define RELEASECRITICAL(bytes, env, obj, mode) { \
-    (*(env))->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \
-}
-
-#define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff)))
-#define SWAPINT(x)   ((jint)((SWAPSHORT((jshort)(x)) << 16) | \
-                            (SWAPSHORT((jshort)((x) >> 16)) & 0xffff)))
-#define SWAPLONG(x)  ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \
-                              ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff)))
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) }
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src,
-                                      jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jshort *srcShort, *dstShort, *endShort;
-    jshort tmpShort;
-
-    dstShort = (jshort *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        /* do not change this if-else statement, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, src);
-
-        srcShort = (jshort *)(bytes + srcPos);
-        endShort = srcShort + (size / sizeof(jshort));
-        while (srcShort < endShort) {
-          tmpShort = *srcShort++;
-          *dstShort++ = SWAPSHORT(tmpShort);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        dstAddr += size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr,
-                                    jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jshort *srcShort, *dstShort, *endShort;
-    jshort tmpShort;
-
-    srcShort = (jshort *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        /* do not change this if-else statement, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, dst);
-
-        dstShort = (jshort *)(bytes + dstPos);
-        endShort = srcShort + (size / sizeof(jshort));
-        while (srcShort < endShort) {
-            tmpShort = *srcShort++;
-            *dstShort++ = SWAPSHORT(tmpShort);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        srcAddr += size;
-        dstPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src,
-                                    jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jint *srcInt, *dstInt, *endInt;
-    jint tmpInt;
-
-    dstInt = (jint *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        /* do not change this code, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, src);
-
-        srcInt = (jint *)(bytes + srcPos);
-        endInt = srcInt + (size / sizeof(jint));
-        while (srcInt < endInt) {
-            tmpInt = *srcInt++;
-            *dstInt++ = SWAPINT(tmpInt);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        dstAddr += size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr,
-                                  jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jint *srcInt, *dstInt, *endInt;
-    jint tmpInt;
-
-    srcInt = (jint *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        /* do not change this code, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, dst);
-
-        dstInt = (jint *)(bytes + dstPos);
-        endInt = srcInt + (size / sizeof(jint));
-        while (srcInt < endInt) {
-            tmpInt = *srcInt++;
-            *dstInt++ = SWAPINT(tmpInt);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        srcAddr += size;
-        dstPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src,
-                                     jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jlong *srcLong, *dstLong, *endLong;
-    jlong tmpLong;
-
-    dstLong = (jlong *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        /* do not change this code, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, src);
-
-        srcLong = (jlong *)(bytes + srcPos);
-        endLong = srcLong + (size / sizeof(jlong));
-        while (srcLong < endLong) {
-            tmpLong = *srcLong++;
-            *dstLong++ = SWAPLONG(tmpLong);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        dstAddr += size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr,
-                                   jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jlong *srcLong, *dstLong, *endLong;
-    jlong tmpLong;
-
-    srcLong = (jlong *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        /* do not change this code, see WARNING above */
-        if (length > MBYTE)
-            size = MBYTE;
-        else
-            size = (size_t)length;
-
-        GETCRITICAL(bytes, env, dst);
-
-        dstLong = (jlong *)(bytes + dstPos);
-        endLong = srcLong + (size / sizeof(jlong));
-        while (srcLong < endLong) {
-            tmpLong = *srcLong++;
-            *dstLong++ = SWAPLONG(tmpLong);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        srcAddr += size;
-        dstPos += size;
-    }
-}
-
-static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Bits, copyFromShortArray, "(Ljava/lang/Object;JJJ)V"),
-    NATIVE_METHOD(Bits, copyToShortArray, "(JLjava/lang/Object;JJ)V"),
-    NATIVE_METHOD(Bits, copyFromIntArray, "(Ljava/lang/Object;JJJ)V"),
-    NATIVE_METHOD(Bits, copyToIntArray, "(JLjava/lang/Object;JJ)V"),
-    NATIVE_METHOD(Bits, copyFromLongArray, "(Ljava/lang/Object;JJJ)V"),
-    NATIVE_METHOD(Bits, copyToLongArray, "(JLjava/lang/Object;JJ)V"),
-};
-
-void register_java_nio_Bits(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/java_util_zip_CRC32.c b/ojluni/src/main/native/CRC32.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_CRC32.c
rename to ojluni/src/main/native/CRC32.c
diff --git a/ojluni/src/main/native/Character.cpp b/ojluni/src/main/native/Character.cpp
index 666184f..9fb24c3 100644
--- a/ojluni/src/main/native/Character.cpp
+++ b/ojluni/src/main/native/Character.cpp
@@ -1,11 +1,12 @@
 /*
- * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * 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.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/native/java_util_zip_Deflater.c b/ojluni/src/main/native/Deflater.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_Deflater.c
rename to ojluni/src/main/native/Deflater.c
diff --git a/ojluni/src/main/native/java_util_zip_Inflater.c b/ojluni/src/main/native/Inflater.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_Inflater.c
rename to ojluni/src/main/native/Inflater.c
diff --git a/ojluni/src/main/native/Math.c b/ojluni/src/main/native/Math.c
index 64f361a..4bbcd1d 100644
--- a/ojluni/src/main/native/Math.c
+++ b/ojluni/src/main/native/Math.c
@@ -1,11 +1,12 @@
 /*
- * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * 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.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/main/native/OnLoad.cpp b/ojluni/src/main/native/OnLoad.cpp
new file mode 100644
index 0000000..ab13939
--- /dev/null
+++ b/ojluni/src/main/native/OnLoad.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+#include <jni.h>
+#include <android-base/logging.h>
+
+extern "C" void register_java_util_zip_ZipFile(JNIEnv* env);
+extern "C" void register_java_util_zip_Inflater(JNIEnv* env);
+extern "C" void register_java_util_zip_Deflater(JNIEnv* env);
+extern "C" void register_java_util_zip_CRC32(JNIEnv* env);
+extern "C" void register_java_util_zip_Adler32(JNIEnv* env);
+extern "C" void register_java_io_FileDescriptor(JNIEnv* env);
+extern "C" void register_sun_nio_ch_DatagramChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_DatagramDispatcher(JNIEnv* env);
+extern "C" void register_java_io_Console(JNIEnv* env);
+extern "C" void register_sun_nio_ch_IOUtil(JNIEnv* env);
+extern "C" void register_sun_nio_ch_SocketChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileChannelImpl(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileDispatcherImpl(JNIEnv* env);
+extern "C" void register_java_io_FileOutputStream(JNIEnv* env);
+extern "C" void register_java_io_FileInputStream(JNIEnv* env);
+extern "C" void register_java_util_prefs_FileSystemPreferences(JNIEnv* env);
+extern "C" void register_sun_nio_ch_NativeThread(JNIEnv* env);
+extern "C" void register_sun_nio_ch_FileKey(JNIEnv* env);
+extern "C" void register_java_io_UnixFileSystem(JNIEnv* env);
+extern "C" void register_java_io_ObjectStreamClass(JNIEnv* env);
+extern "C" void register_java_io_ObjectOutputStream(JNIEnv* env);
+extern "C" void register_java_io_ObjectInputStream(JNIEnv* env);
+extern "C" void register_java_net_InetAddress(JNIEnv* env);
+extern "C" jint net_JNI_OnLoad(JavaVM *vm, void* ignored);
+extern "C" void register_sun_nio_ch_Net(JNIEnv* env);
+extern "C" void register_java_nio_MappedByteBuffer(JNIEnv* env);
+extern "C" void register_java_net_Inet6Address(JNIEnv* env);
+extern "C" void register_java_net_Inet4Address(JNIEnv* env);
+extern "C" void register_sun_nio_ch_ServerSocketChannelImpl(JNIEnv* env);
+extern "C" void register_java_net_SocketInputStream(JNIEnv* env);
+extern "C" void register_java_net_SocketOutputStream(JNIEnv* env);
+extern "C" void register_java_lang_Float(JNIEnv* env);
+extern "C" void register_java_lang_Double(JNIEnv* env);
+extern "C" void register_java_lang_StrictMath(JNIEnv* env);
+extern "C" void register_java_lang_Math(JNIEnv* env);
+extern "C" void register_java_lang_ProcessEnvironment(JNIEnv* env);
+extern "C" void register_java_lang_System(JNIEnv* env);
+extern "C" void register_java_lang_Runtime(JNIEnv* env);
+extern "C" void register_java_lang_UNIXProcess(JNIEnv* env);
+void register_java_lang_Character(JNIEnv* env);
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+  jint version = JNI_VERSION_1_6;
+  void* raw_env;
+  jint result = vm->GetEnv(&raw_env, version);
+  CHECK_EQ(result, JNI_OK);
+  CHECK(raw_env != nullptr);
+  JNIEnv* env = static_cast<JNIEnv*>(raw_env);
+
+  // Some registration functions also do some extra local initialization,
+  // creating local references in the process. ART does not expect JNI_OnLoad()
+  // to leave any local references in the current frame, so create a new one.
+  // Request space for 256 local references (increase if necessary).
+  result = env->PushLocalFrame(256);
+  CHECK_EQ(result, 0);
+
+  // Some registration functions also record field ids retrieved using
+  // GetFieldID(), forcing the initialization of the searched class. As some
+  // class initializers (notably Inet*Address) directly or indirectly use
+  // the StringBuilder, we need to start by registering native methods needed
+  // for resizing its internal buffer. That's done through Arrays.copyOf()
+  // which uses System.arraycopy() and Math.min(), forcing the initialization
+  // of System and Main. The former uses System's own native methods while the
+  // latter uses native methods of Float and Double but not Math's own.
+  register_java_lang_Float(env);
+  register_java_lang_Double(env);
+  register_java_lang_System(env);
+
+  // Initialize the rest in the order in which they appear in Android.bp .
+  register_java_util_zip_ZipFile(env);
+  register_java_util_zip_Inflater(env);
+  register_java_util_zip_Deflater(env);
+  register_java_util_zip_CRC32(env);
+  register_java_util_zip_Adler32(env);
+  register_java_io_FileDescriptor(env);
+  register_sun_nio_ch_DatagramChannelImpl(env);
+  register_sun_nio_ch_DatagramDispatcher(env);
+  register_java_io_Console(env);
+  register_sun_nio_ch_IOUtil(env);
+  register_sun_nio_ch_SocketChannelImpl(env);
+  register_sun_nio_ch_FileChannelImpl(env);
+  register_sun_nio_ch_FileDispatcherImpl(env);
+  register_java_io_FileOutputStream(env);
+  register_java_io_FileInputStream(env);
+  register_java_util_prefs_FileSystemPreferences(env);
+  register_sun_nio_ch_NativeThread(env);
+  register_sun_nio_ch_FileKey(env);
+  register_java_io_UnixFileSystem(env);
+  register_java_io_ObjectStreamClass(env);
+  register_java_io_ObjectOutputStream(env);
+  register_java_io_ObjectInputStream(env);
+  register_java_net_InetAddress(env);
+
+  jint net_jni_version = net_JNI_OnLoad(vm, /* ignored */ nullptr);
+  CHECK(net_jni_version == JNI_VERSION_1_2 ||
+        net_jni_version == JNI_VERSION_1_4 ||
+        net_jni_version == JNI_VERSION_1_6);
+
+  register_sun_nio_ch_Net(env);
+  register_java_nio_MappedByteBuffer(env);
+  register_java_net_Inet6Address(env);
+  register_java_net_Inet4Address(env);
+  register_sun_nio_ch_ServerSocketChannelImpl(env);
+  register_java_net_SocketInputStream(env);
+  register_java_net_SocketOutputStream(env);
+  register_java_lang_StrictMath(env);
+  register_java_lang_Math(env);
+  register_java_lang_ProcessEnvironment(env);
+  register_java_lang_Runtime(env);
+  register_java_lang_UNIXProcess(env);
+  register_java_lang_Character(env);
+
+  env->PopLocalFrame(/* result */ nullptr);  // Pop the local frame.
+  return version;
+}
diff --git a/ojluni/src/main/native/Register.cpp b/ojluni/src/main/native/Register.cpp
index 15ac1e4..6294981 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -58,7 +58,6 @@
 extern void register_java_net_PlainDatagramSocketImpl(JNIEnv*);
 extern void register_java_net_SocketInputStream(JNIEnv*);
 extern void register_java_net_SocketOutputStream(JNIEnv*);
-extern void register_java_nio_Bits(JNIEnv* env);
 extern void register_java_nio_MappedByteBuffer(JNIEnv* env);
 extern void register_java_util_zip_Adler32(JNIEnv* env);
 extern void register_java_util_zip_CRC32(JNIEnv*);
@@ -126,7 +125,6 @@
     register_java_net_Inet6Address(env);
     register_java_net_SocketInputStream(env);
     register_java_net_SocketOutputStream(env);
-    register_java_nio_Bits(env);
     register_java_util_prefs_FileSystemPreferences(env);
     register_sun_nio_ch_ServerSocketChannelImpl(env);
     register_sun_nio_ch_SocketChannelImpl(env);
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
index 4c023b5..ad734fd 100644
--- a/ojluni/src/main/native/Runtime.c
+++ b/ojluni/src/main/native/Runtime.c
@@ -62,7 +62,7 @@
 }
 
 JNIEXPORT void JNICALL
-Runtime_gc(JNIEnv *env, jobject this)
+Runtime_nativeGc(JNIEnv *env, jobject this)
 {
     JVM_GC();
 }
@@ -84,7 +84,7 @@
   FAST_NATIVE_METHOD(Runtime, freeMemory, "()J"),
   FAST_NATIVE_METHOD(Runtime, totalMemory, "()J"),
   FAST_NATIVE_METHOD(Runtime, maxMemory, "()J"),
-  NATIVE_METHOD(Runtime, gc, "()V"),
+  NATIVE_METHOD(Runtime, nativeGc, "()V"),
   NATIVE_METHOD(Runtime, nativeExit, "(I)V"),
   NATIVE_METHOD(Runtime, nativeLoad,
                 "(Ljava/lang/String;Ljava/lang/ClassLoader;)"
diff --git a/ojluni/src/main/native/Thread.c b/ojluni/src/main/native/Thread.c
deleted file mode 100644
index 83b448f..0000000
--- a/ojluni/src/main/native/Thread.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/*-
- *      Stuff for dealing with threads.
- *      originally in threadruntime.c, Sun Sep 22 12:09:39 1991
- */
-
-#include "jni.h"
-#include "jvm.h"
-
-
-#define THD "Ljava/lang/Thread;"
-#define OBJ "Ljava/lang/Object;"
-#define STE "Ljava/lang/StackTraceElement;"
-#define STR "Ljava/lang/String;"
-#include <nativehelper/JNIHelp.h>
-
-#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
-
-static JNINativeMethod methods[] = {
-    {"start0",           "(JZ)V",        (void *)&JVM_StartThread},
-    {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
-    {"yield",            "()V",        (void *)&JVM_Yield},
-    {"sleep",            "(Ljava/lang/Object;J)V",       (void *)&JVM_Sleep},
-    {"currentThread",    "()" THD,     (void *)&JVM_CurrentThread},
-    {"interrupt0",       "()V",        (void *)&JVM_Interrupt},
-    {"isInterrupted",    "(Z)Z",       (void *)&JVM_IsInterrupted},
-    {"holdsLock",        "(" OBJ ")Z", (void *)&JVM_HoldsLock},
-    {"setNativeName",    "(" STR ")V", (void *)&JVM_SetNativeThreadName},
-};
-
-#undef THD
-#undef OBJ
-#undef STE
-#undef STR
-
-void register_java_lang_Thread(JNIEnv* env) {
-  jclass cls = (*env)->FindClass(env, "java/lang/Thread");
-  (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
-}
diff --git a/ojluni/src/main/native/Throwable.c b/ojluni/src/main/native/Throwable.c
deleted file mode 100644
index 805c80a..0000000
--- a/ojluni/src/main/native/Throwable.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/*
- *      Implementation of class Throwable
- *
- *      former classruntime.c, Wed Jun 26 18:43:20 1991
- */
-
-#include <stdio.h>
-#include <signal.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-#include <nativehelper/JNIHelp.h>
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-/*
- * Fill in the current stack trace in this exception.  This is
- * usually called automatically when the exception is created but it
- * may also be called explicitly by the user.  This routine returns
- * `this' so you can write 'throw e.fillInStackTrace();'
- */
-JNIEXPORT jobject JNICALL
-Throwable_fillInStackTrace(JNIEnv *env, jobject throwable, int dummy)
-{
-    JVM_FillInStackTrace(env, throwable);
-    return throwable;
-}
-
-JNIEXPORT jint JNICALL
-Throwable_getStackTraceDepth(JNIEnv *env, jobject throwable)
-{
-    return JVM_GetStackTraceDepth(env, throwable);
-}
-
-JNIEXPORT jobject JNICALL
-Throwable_getStackTraceElement(JNIEnv *env,
-                                              jobject throwable, jint index)
-{
-    return JVM_GetStackTraceElement(env, throwable, index);
-}
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(Throwable, fillInStackTrace, "(I)Ljava/lang/Throwable;"),
-  NATIVE_METHOD(Throwable, getStackTraceDepth, "()I"),
-  NATIVE_METHOD(Throwable, getStackTraceElement, "(I)Ljava/lang/StackTraceElement;"),
-};
-
-void register_java_lang_Throwable(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/lang/Throwable", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/UNIXProcess_md.c b/ojluni/src/main/native/UNIXProcess_md.c
index 550a5c5..b289f1a 100644
--- a/ojluni/src/main/native/UNIXProcess_md.c
+++ b/ojluni/src/main/native/UNIXProcess_md.c
@@ -117,7 +117,8 @@
 #ifndef START_CHILD_USE_VFORK
 // Android-changed: disable vfork under AddressSanitizer.
 //  #ifdef __linux__
-  #if defined(__linux__) && !__has_feature(address_sanitizer)
+  #if defined(__linux__) && !__has_feature(address_sanitizer) && \
+      !__has_feature(hwaddress_sanitizer)
     #define START_CHILD_USE_VFORK 1
   #else
     #define START_CHILD_USE_VFORK 0
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.c b/ojluni/src/main/native/ZipFile.c
similarity index 100%
rename from ojluni/src/main/native/java_util_zip_ZipFile.c
rename to ojluni/src/main/native/ZipFile.c
diff --git a/ojluni/src/main/native/java_props_md.c b/ojluni/src/main/native/java_props_md.c
deleted file mode 100644
index a9fe5ba..0000000
--- a/ojluni/src/main/native/java_props_md.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include <stdio.h>
-#include <ctype.h>
-#endif
-#include <pwd.h>
-#include <locale.h>
-#ifndef ARCHPROPNAME
-#error "The macro ARCHPROPNAME has not been defined"
-#endif
-#include <sys/utsname.h>        /* For os_name and os_version */
-#include <langinfo.h>           /* For nl_langinfo */
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <time.h>
-#include <errno.h>
-
-#ifdef MACOSX
-#endif
-
-#if defined(_ALLBSD_SOURCE)
-#if !defined(P_tmpdir)
-#include <paths.h>
-#define P_tmpdir _PATH_VARTMP
-#endif
-#endif
-
-#include "locale_str.h"
-
-#if !defined(_ALLBSD_SOURCE)
-#ifdef __linux__
-  #ifndef CODESET
-  #define CODESET _NL_CTYPE_CODESET_NAME
-  #endif
-#else
-#ifdef ALT_CODESET_KEY
-#define CODESET ALT_CODESET_KEY
-#endif
-#endif
-#endif /* !_ALLBSD_SOURCE */
-
-#ifdef JAVASE_EMBEDDED
-#include <dlfcn.h>
-#include <sys/stat.h>
-#endif
-
-/* Take an array of string pairs (map of key->value) and a string (key).
- * Examine each pair in the map to see if the first string (key) matches the
- * string.  If so, store the second string of the pair (value) in the value and
- * return 1.  Otherwise do nothing and return 0.  The end of the map is
- * indicated by an empty string at the start of a pair (key of "").
- */
-static int
-mapLookup(char* map[], const char* key, char** value) {
-    int i;
-    for (i = 0; strcmp(map[i], ""); i += 2){
-        if (!strcmp(key, map[i])){
-            *value = map[i + 1];
-            return 1;
-        }
-    }
-    return 0;
-}
-
-/* This function sets an environment variable using envstring.
- * The format of envstring is "name=value".
- * If the name has already existed, it will append value to the name.
- */
-static void
-setPathEnvironment(char *envstring)
-{
-    char name[20], *value, *current;
-
-    value = strchr(envstring, '='); /* locate name and value separator */
-
-    if (! value)
-        return; /* not a valid environment setting */
-
-    /* copy first part as environment name */
-    strncpy(name, envstring, value - envstring);
-    name[value-envstring] = '\0';
-
-    value++; /* set value point to value of the envstring */
-
-    current = getenv(name);
-    if (current) {
-        if (! strstr(current, value)) {
-            /* value is not found in current environment, append it */
-            char *temp = malloc(strlen(envstring) + strlen(current) + 2);
-        strcpy(temp, name);
-        strcat(temp, "=");
-        strcat(temp, current);
-        strcat(temp, ":");
-        strcat(temp, value);
-        putenv(temp);
-        }
-        /* else the value has already been set, do nothing */
-    }
-    else {
-        /* environment variable is not found */
-        putenv(envstring);
-    }
-}
-
-#ifndef P_tmpdir
-#define P_tmpdir "/var/tmp"
-#endif
-
-static int ParseLocale(int cat, char ** std_language, char ** std_script,
-                       char ** std_country, char ** std_variant, char ** std_encoding) {
-    char temp[64];
-    char *language = NULL, *country = NULL, *variant = NULL,
-         *encoding = NULL;
-    char *p, encoding_variant[64];
-    char *lc;
-
-    /* Query the locale set for the category */
-
-#ifdef MACOSX
-    lc = setupMacOSXLocale(cat); // malloc'd memory, need to free
-#else
-    lc = setlocale(cat, NULL);
-#endif
-
-#ifndef __linux__
-    if (lc == NULL) {
-        return 0;
-    }
-
-    if (cat == LC_CTYPE) {
-        /*
-         * Workaround for Solaris bug 4201684: Xlib doesn't like @euro
-         * locales. Since we don't depend on the libc @euro behavior,
-         * we just remove the qualifier.
-         * On Linux, the bug doesn't occur; on the other hand, @euro
-         * is needed there because it's a shortcut that also determines
-         * the encoding - without it, we wouldn't get ISO-8859-15.
-         * Therefore, this code section is Solaris-specific.
-         */
-        lc = strdup(lc);    /* keep a copy, setlocale trashes original. */
-        strcpy(temp, lc);
-        p = strstr(temp, "@euro");
-        if (p != NULL) {
-            *p = '\0';
-            setlocale(LC_ALL, temp);
-        }
-    }
-#else
-    if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
-        lc = "en_US";
-    }
-#endif
-
-    /*
-     * locale string format in Solaris is
-     * <language name>_<country name>.<encoding name>@<variant name>
-     * <country name>, <encoding name>, and <variant name> are optional.
-     */
-
-    strcpy(temp, lc);
-#ifdef MACOSX
-    free(lc); // malloced memory
-#endif
-    /* Parse the language, country, encoding, and variant from the
-     * locale.  Any of the elements may be missing, but they must occur
-     * in the order language_country.encoding@variant, and must be
-     * preceded by their delimiter (except for language).
-     *
-     * If the locale name (without .encoding@variant, if any) matches
-     * any of the names in the locale_aliases list, map it to the
-     * corresponding full locale name.  Most of the entries in the
-     * locale_aliases list are locales that include a language name but
-     * no country name, and this facility is used to map each language
-     * to a default country if that's possible.  It's also used to map
-     * the Solaris locale aliases to their proper Java locale IDs.
-     */
-    if ((p = strchr(temp, '.')) != NULL) {
-        strcpy(encoding_variant, p); /* Copy the leading '.' */
-        *p = '\0';
-    } else if ((p = strchr(temp, '@')) != NULL) {
-        strcpy(encoding_variant, p); /* Copy the leading '@' */
-        *p = '\0';
-    } else {
-        *encoding_variant = '\0';
-    }
-
-    if (mapLookup(locale_aliases, temp, &p)) {
-        strcpy(temp, p);
-        // check the "encoding_variant" again, if any.
-        if ((p = strchr(temp, '.')) != NULL) {
-            strcpy(encoding_variant, p); /* Copy the leading '.' */
-            *p = '\0';
-        } else if ((p = strchr(temp, '@')) != NULL) {
-            strcpy(encoding_variant, p); /* Copy the leading '@' */
-            *p = '\0';
-        }
-    }
-
-    language = temp;
-    if ((country = strchr(temp, '_')) != NULL) {
-        *country++ = '\0';
-    }
-
-    p = encoding_variant;
-    if ((encoding = strchr(p, '.')) != NULL) {
-        p[encoding++ - p] = '\0';
-        p = encoding;
-    }
-    if ((variant = strchr(p, '@')) != NULL) {
-        p[variant++ - p] = '\0';
-    }
-
-    /* Normalize the language name */
-    if (std_language != NULL) {
-        *std_language = "en";
-        if (language != NULL && mapLookup(language_names, language, std_language) == 0) {
-            *std_language = malloc(strlen(language)+1);
-            strcpy(*std_language, language);
-        }
-    }
-
-    /* Normalize the country name */
-    if (std_country != NULL && country != NULL) {
-        if (mapLookup(country_names, country, std_country) == 0) {
-            *std_country = malloc(strlen(country)+1);
-            strcpy(*std_country, country);
-        }
-    }
-
-    /* Normalize the script and variant name.  Note that we only use
-     * variants listed in the mapping array; others are ignored.
-     */
-    if (variant != NULL) {
-        if (std_script != NULL) {
-            mapLookup(script_names, variant, std_script);
-        }
-
-        if (std_variant != NULL) {
-            mapLookup(variant_names, variant, std_variant);
-        }
-    }
-
-    /* Normalize the encoding name.  Note that we IGNORE the string
-     * 'encoding' extracted from the locale name above.  Instead, we use the
-     * more reliable method of calling nl_langinfo(CODESET).  This function
-     * returns an empty string if no encoding is set for the given locale
-     * (e.g., the C or POSIX locales); we use the default ISO 8859-1
-     * converter for such locales.
-     */
-    if (std_encoding != NULL) {
-        /* OK, not so reliable - nl_langinfo() gives wrong answers on
-         * Euro locales, in particular. */
-        if (strcmp(p, "ISO8859-15") == 0)
-            p = "ISO8859-15";
-        else
-            p = nl_langinfo(CODESET);
-
-        /* Convert the bare "646" used on Solaris to a proper IANA name */
-        if (strcmp(p, "646") == 0)
-            p = "ISO646-US";
-
-        /* return same result nl_langinfo would return for en_UK,
-         * in order to use optimizations. */
-        *std_encoding = (*p != '\0') ? p : "ISO8859-1";
-
-#ifdef __linux__
-        /*
-         * Remap the encoding string to a different value for japanese
-         * locales on linux so that customized converters are used instead
-         * of the default converter for "EUC-JP". The customized converters
-         * omit support for the JIS0212 encoding which is not supported by
-         * the variant of "EUC-JP" encoding used on linux
-         */
-        if (strcmp(p, "EUC-JP") == 0) {
-            *std_encoding = "EUC-JP-LINUX";
-        }
-#else
-        if (strcmp(p,"eucJP") == 0) {
-            /* For Solaris use customized vendor defined character
-             * customized EUC-JP converter
-             */
-            *std_encoding = "eucJP-open";
-        } else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
-            /*
-             * Remap the encoding string to Big5_Solaris which augments
-             * the default converter for Solaris Big5 locales to include
-             * seven additional ideographic characters beyond those included
-             * in the Java "Big5" converter.
-             */
-            *std_encoding = "Big5_Solaris";
-        } else if (strcmp(p, "Big5-HKSCS") == 0) {
-            /*
-             * Solaris uses HKSCS2001
-             */
-            *std_encoding = "Big5-HKSCS-2001";
-        }
-#endif
-    }
-
-    return 1;
-}
-
-#ifdef JAVASE_EMBEDDED
-/* Determine the default embedded toolkit based on whether lib/xawt/
- * exists in the JRE. This can still be overridden by -Dawt.toolkit=XXX
- */
-static char* getEmbeddedToolkit() {
-    Dl_info dlinfo;
-    char buf[MAXPATHLEN];
-    int32_t len;
-    char *p;
-    struct stat statbuf;
-
-    /* Get address of this library and the directory containing it. */
-    dladdr((void *)getEmbeddedToolkit, &dlinfo);
-    realpath((char *)dlinfo.dli_fname, buf);
-    len = strlen(buf);
-    p = strrchr(buf, '/');
-    /* Default AWT Toolkit on Linux and Solaris is XAWT. */
-    strncpy(p, "/xawt/", MAXPATHLEN-len-1);
-    /* Check if it exists */
-    if (stat(buf, &statbuf) == -1 && errno == ENOENT) {
-        /* No - this is a reduced-headless-jre so use special HToolkit */
-        return "sun.awt.HToolkit";
-    }
-    else {
-        /* Yes - this is a headful JRE so fallback to SE defaults */
-        return NULL;
-    }
-}
-#endif
-
-/* This function gets called very early, before VM_CALLS are setup.
- * Do not use any of the VM_CALLS entries!!!
- */
-java_props_t *
-GetJavaProperties(JNIEnv *env)
-{
-    static java_props_t sprops;
-    char *v; /* tmp var */
-
-    if (sprops.user_dir) {
-        return &sprops;
-    }
-
-    /* tmp dir */
-    sprops.tmp_dir = P_tmpdir;
-#ifdef MACOSX
-    /* darwin has a per-user temp dir */
-    static char tmp_path[PATH_MAX];
-    int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, tmp_path, PATH_MAX);
-    if (pathSize > 0 && pathSize <= PATH_MAX) {
-        sprops.tmp_dir = tmp_path;
-    }
-#endif /* MACOSX */
-
-    /* Printing properties */
-#ifdef MACOSX
-    sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";
-#else
-    sprops.printerJob = "sun.print.PSPrinterJob";
-#endif
-
-    /* patches/service packs installed */
-    sprops.patch_level = "unknown";
-
-    /* Java 2D properties */
-#ifdef MACOSX
-    PreferredToolkit prefToolkit = getPreferredToolkit();
-    switch (prefToolkit) {
-        case CToolkit:
-        case HToolkit:
-            sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
-            break;
-        case XToolkit:
-#endif
-    sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
-#ifdef MACOSX
-            break;
-    }
-#endif
-    /* AWT properties */
-#ifdef JAVASE_EMBEDDED
-    sprops.awt_toolkit = getEmbeddedToolkit();
-    if (sprops.awt_toolkit == NULL) // default as below
-#endif
-#ifdef MACOSX
-        switch (prefToolkit) {
-            case CToolkit:
-                sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";
-                break;
-            case XToolkit:
-#endif
-    sprops.awt_toolkit = "sun.awt.X11.XToolkit";
-#ifdef MACOSX
-                break;
-            default:
-                sprops.awt_toolkit = "sun.awt.HToolkit";
-                break;
-        }
-#endif
-
-    /* This is used only for debugging of font problems. */
-    v = getenv("JAVA2D_FONTPATH");
-    sprops.font_dir = v ? v : NULL;
-
-#ifdef SI_ISALIST
-    /* supported instruction sets */
-    {
-        char list[258];
-        sysinfo(SI_ISALIST, list, sizeof(list));
-        sprops.cpu_isalist = strdup(list);
-    }
-#else
-    sprops.cpu_isalist = NULL;
-#endif
-
-    /* endianness of platform */
-    {
-        unsigned int endianTest = 0xff000000;
-        if (((char*)(&endianTest))[0] != 0)
-            sprops.cpu_endian = "big";
-        else
-            sprops.cpu_endian = "little";
-    }
-
-    /* os properties */
-    {
-#ifdef MACOSX
-        setOSNameAndVersion(&sprops);
-#else
-        struct utsname name;
-        uname(&name);
-        sprops.os_name = strdup(name.sysname);
-        sprops.os_version = strdup(name.release);
-#endif
-
-        sprops.os_arch = ARCHPROPNAME;
-
-        if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {
-            sprops.desktop = "gnome";
-        }
-        else {
-            sprops.desktop = NULL;
-        }
-    }
-
-    /* Determine the language, country, variant, and encoding from the host,
-     * and store these in the user.language, user.country, user.variant and
-     * file.encoding system properties. */
-    setlocale(LC_ALL, "");
-    if (ParseLocale(LC_CTYPE,
-                    &(sprops.format_language),
-                    &(sprops.format_script),
-                    &(sprops.format_country),
-                    &(sprops.format_variant),
-                    &(sprops.encoding))) {
-        ParseLocale(LC_MESSAGES,
-                    &(sprops.language),
-                    &(sprops.script),
-                    &(sprops.country),
-                    &(sprops.variant),
-                    NULL);
-    } else {
-        sprops.language = "en";
-        sprops.encoding = "ISO8859-1";
-    }
-    sprops.display_language = sprops.language;
-    sprops.display_script = sprops.script;
-    sprops.display_country = sprops.country;
-    sprops.display_variant = sprops.variant;
-
-#ifdef MACOSX
-    sprops.sun_jnu_encoding = "UTF-8";
-#else
-    sprops.sun_jnu_encoding = sprops.encoding;
-#endif
-
-#ifdef _ALLBSD_SOURCE
-#if BYTE_ORDER == _LITTLE_ENDIAN
-     sprops.unicode_encoding = "UnicodeLittle";
- #else
-     sprops.unicode_encoding = "UnicodeBig";
- #endif
-#else /* !_ALLBSD_SOURCE */
-#ifdef __linux__
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-    sprops.unicode_encoding = "UnicodeLittle";
-#else
-    sprops.unicode_encoding = "UnicodeBig";
-#endif
-#else
-    sprops.unicode_encoding = "UnicodeBig";
-#endif
-#endif /* _ALLBSD_SOURCE */
-
-    /* user properties */
-    {
-        struct passwd *pwent = getpwuid(getuid());
-        sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";
-        sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?";
-    }
-
-    /* User TIMEZONE */
-    {
-        /*
-         * We defer setting up timezone until it's actually necessary.
-         * Refer to TimeZone.getDefault(). However, the system
-         * property is necessary to be able to be set by the command
-         * line interface -D. Here temporarily set a null string to
-         * timezone.
-         */
-        tzset();        /* for compatibility */
-        sprops.timezone = "";
-    }
-
-    /* Current directory */
-    {
-        char buf[MAXPATHLEN];
-        errno = 0;
-        if (getcwd(buf, sizeof(buf))  == NULL)
-            JNU_ThrowByName(env, "java/lang/Error",
-             "Properties init: Could not determine current working directory.");
-        else
-            sprops.user_dir = strdup(buf);
-    }
-
-    sprops.file_separator = "/";
-    sprops.path_separator = ":";
-    sprops.line_separator = "\n";
-
-#if !defined(_ALLBSD_SOURCE)
-    /* Append CDE message and resource search path to NLSPATH and
-     * XFILESEARCHPATH, in order to pick localized message for
-     * FileSelectionDialog window (Bug 4173641).
-     */
-    setPathEnvironment("NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat");
-    setPathEnvironment("XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt");
-#endif
-
-
-#ifdef MACOSX
-    setProxyProperties(&sprops);
-#endif
-
-    return &sprops;
-}
-
-jstring
-GetStringPlatform(JNIEnv *env, nchar* cstr)
-{
-    return JNU_NewStringPlatform(env, cstr);
-}
diff --git a/ojluni/src/main/native/socket_tagger_util.cpp b/ojluni/src/main/native/socket_tagger_util.cpp
index b62898f..2f91f6d 100644
--- a/ojluni/src/main/native/socket_tagger_util.cpp
+++ b/ojluni/src/main/native/socket_tagger_util.cpp
@@ -1,11 +1,12 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * 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.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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
diff --git a/ojluni/src/test/artrun b/ojluni/src/test/artrun
index e9afd78..d56753d 100755
--- a/ojluni/src/test/artrun
+++ b/ojluni/src/test/artrun
@@ -103,6 +103,7 @@
 conscrypt-hostdex.jar
 core-ojtests-hostdex.jar  # This is the *one* addition that makes our OJ tests actually run. The rest of these are standard jars on the bootclasspath.
 core-oj-hostdex.jar
+core-simple-hostdex.jar
 okhttp-hostdex.jar)
 
 BOOT_DEXJAR_PREFIX="$ANDROID_ROOT/framework"
diff --git a/openjdk_java_files.bp b/openjdk_java_files.bp
index c574f2d..3307923 100644
--- a/openjdk_java_files.bp
+++ b/openjdk_java_files.bp
@@ -249,6 +249,7 @@
         "ojluni/src/main/java/java/lang/invoke/MethodHandles.java",
         "ojluni/src/main/java/java/lang/invoke/MethodHandleImpl.java",
         "ojluni/src/main/java/java/lang/invoke/MethodHandleInfo.java",
+        "ojluni/src/main/java/java/lang/invoke/MethodHandleNatives.java",
         "ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java",
         "ojluni/src/main/java/java/lang/invoke/MethodType.java",
         "ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java",
diff --git a/run-libcore-tests b/run-libcore-tests
deleted file mode 100755
index 996030a..0000000
--- a/run-libcore-tests
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# Make sure there's a vogar on the path, but prefer the user's one.
-export PATH=$PATH:~dalvik-prebuild/vogar/bin
-
-VOGAR="vogar $VOGAR_FLAGS"
-
-# We enumerate the test packages for vogar rather than just giving it the classes.jar
-# so hundreds of packages can be tested in parallel, rather than one big jar file serially.
-all_test_packages=$(find `dirname $0`/*/src/test -name "*.java" | \
-  fgrep -v junit | \
-  fgrep -v org/w3c/domts | \
-  xargs grep -h '^package ' | sed 's/^package //' | sed 's/;$//' | sort | uniq | tr "\n" " ")
-all_test_packages="$all_test_packages tests.api.org.w3c.dom"
-
-# Use the list of packages supplied on the command-line, if any.
-test_packages=${*:-$all_test_packages}
-
-echo "Running tests for following test packages:"
-echo $test_packages | tr " " "\n"
-
-$VOGAR \
-  --vm-arg -Xmx32M \
-  --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests_intermediates/classes.jack \
-  --classpath out/target/common/obj/JAVA_LIBRARIES/sqlite-jdbc_intermediates/classes.jack \
-  --classpath out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jack \
-  --classpath out/target/common/obj/JAVA_LIBRARIES/okhttp_intermediates/classes.jack \
-  $test_packages \
-  || true
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index a9d60da..3ca3501 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -264,6 +264,7 @@
         provide("SSLContext", "TLSv1");
         provide("SSLContext", "TLSv1.1");
         provide("SSLContext", "TLSv1.2");
+        provide("SSLContext", "TLSv1.3");
         provide("SecretKeyFactory", "DES");
         provide("SecretKeyFactory", "DESede");
         provide("SecretKeyFactory", "PBEWithMD5AndDES");
@@ -683,7 +684,8 @@
     public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
         "TLSv1",
         "TLSv1.1",
-        "TLSv1.2"));
+        "TLSv1.2",
+        "TLSv1.3"));
     public static final Set<String> SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT =
             new HashSet<String>(Arrays.asList(
                 "TLSv1",
@@ -710,11 +712,13 @@
         }
     }
 
-    private static enum TLSVersion {
+    private enum TLSVersion {
         SSLv3("SSLv3"),
         TLSv1("TLSv1"),
         TLSv11("TLSv1.1"),
-        TLSv12("TLSv1.2");
+        TLSv12("TLSv1.2"),
+        TLSv13("TLSv1.3"),
+        ;
 
         private final String name;
 
@@ -735,8 +739,9 @@
 
     /**
      * Valid values for X509TrustManager.checkServerTrusted authType,
-     * either key exchange algorithm part of the cipher suite
-     * or UNKNOWN.
+     * either key exchange algorithm part of the cipher suite, UNKNOWN,
+     * or GENERIC (for TLS 1.3 cipher suites that don't imply a specific
+     * key exchange method).
      */
     public static final Set<String> SERVER_AUTH_TYPES = new HashSet<String>(Arrays.asList(
         "DHE_DSS",
@@ -756,7 +761,8 @@
         "ECDH_RSA",
         "ECDHE_ECDSA",
         "ECDHE_RSA",
-        "UNKNOWN"));
+        "UNKNOWN",
+        "GENERIC"));
 
     public static final String CIPHER_SUITE_INVALID = "SSL_NULL_WITH_NULL_NULL";
 
@@ -796,21 +802,26 @@
         addBoth(   "SSL_RSA_WITH_3DES_EDE_CBC_SHA");
 
         // TLSv1.2 cipher suites
-        addBoth(   "TLS_RSA_WITH_AES_128_CBC_SHA256");
-        addBoth(   "TLS_RSA_WITH_AES_256_CBC_SHA256");
+        addRi(   "TLS_RSA_WITH_AES_128_CBC_SHA256");
+        addRi(   "TLS_RSA_WITH_AES_256_CBC_SHA256");
         addOpenSsl("TLS_RSA_WITH_AES_128_GCM_SHA256");
         addOpenSsl("TLS_RSA_WITH_AES_256_GCM_SHA384");
-        addBoth(   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
-        addBoth(   "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
+        addRi(   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
+        addRi(   "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
         addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
         addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
-        addBoth(   "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
-        addBoth(   "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
+        addRi(   "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
+        addRi(   "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
         addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
         addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
         addOpenSsl("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256");
         addOpenSsl("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
 
+        // TLSv1.3 cipher suites
+        addOpenSsl("TLS_AES_128_GCM_SHA256");
+        addOpenSsl("TLS_AES_256_GCM_SHA384");
+        addOpenSsl("TLS_CHACHA20_POLY1305_SHA256");
+
         // Pre-Shared Key (PSK) cipher suites
         addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
         addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
@@ -943,6 +954,14 @@
                     "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
             );
 
+    /**
+     * Cipher suites that are only supported with TLS 1.3.
+     */
+    public static final List<String> CIPHER_SUITES_TLS13 = Arrays.asList(
+            "TLS_AES_128_GCM_SHA256",
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256");
+
     // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
     // javax.net.ssl.SSLEngine.
     private static final List<String> CIPHER_SUITES_ANDROID_AES_HARDWARE = Arrays.asList(
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index be9874f..691bdf3 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -693,13 +693,13 @@
         String keyAlgorithm = privateKey.getAlgorithm();
         String signatureAlgorithm;
         if (keyAlgorithm.equals("RSA")) {
-            signatureAlgorithm = "sha1WithRSA";
+            signatureAlgorithm = "sha256WithRSA";
         } else if (keyAlgorithm.equals("DSA")) {
-            signatureAlgorithm = "sha1WithDSA";
+            signatureAlgorithm = "sha256WithDSA";
         } else if (keyAlgorithm.equals("EC")) {
-            signatureAlgorithm = "sha1WithECDSA";
+            signatureAlgorithm = "sha256WithECDSA";
         } else if (keyAlgorithm.equals("EC_RSA")) {
-            signatureAlgorithm = "sha1WithRSA";
+            signatureAlgorithm = "sha256WithRSA";
         } else {
             throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm);
         }
diff --git a/tools/upstream/src/main/java/libcore/CompareUpstreams.java b/tools/upstream/src/main/java/libcore/CompareUpstreams.java
index fa6bd4f..e3504ae 100644
--- a/tools/upstream/src/main/java/libcore/CompareUpstreams.java
+++ b/tools/upstream/src/main/java/libcore/CompareUpstreams.java
@@ -16,7 +16,8 @@
 
 package libcore;
 
-import java.io.*;
+import java.io.IOException;
+import java.io.PrintStream;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -119,45 +120,6 @@
         return escapeTsv(String.join("\n", result));
     }
 
-    /**
-     * Computes the edit distance of two lists, i.e. the smallest number of list items to delete,
-     * insert or replace that would transform the content of one list into the other.
-     */
-    private <T> int editDistance(List<T> a, List<T> b) {
-        int numB = b.size();
-        int[] prevCost = new int[numB + 1];
-        for (int i = 0; i <= numB; i++) {
-            prevCost[i] = i;
-        }
-        int[] curCost = new int[numB + 1];
-        for (int endA = 1; endA <= a.size(); endA++) {
-            // For each valid index i, prevCost[i] is the edit distance between
-            // a.subList(0, endA-1) and b.sublist(0, i).
-            // We now calculate curCost[end_b] as the edit distance between
-            // a.subList(0, endA) and b.subList(0, endB)
-            curCost[0] = endA;
-            for (int endB = 1; endB <= numB; endB++) {
-                boolean endsMatch = a.get(endA - 1).equals(b.get(endB - 1));
-                curCost[endB] = min(
-                        curCost[endB - 1] + 1, // append item from b
-                        prevCost[endB] + 1, // append item from a
-                        prevCost[endB - 1] + (endsMatch ? 0 : 1)); // match or replace item
-            }
-            int[] tmp = curCost;
-            curCost = prevCost;
-            prevCost = tmp;
-        }
-        return prevCost[numB];
-    }
-
-    private static int min(int a, int b, int c) {
-        if (a < b) {
-            return a < c ? a : c;
-        } else {
-            return b < c ? b : c;
-        }
-    }
-
     private static String escapeTsv(String value) {
         if (value.contains("\t")) {
             throw new IllegalArgumentException(value); // tsv doesn't support escaping tabs
@@ -190,7 +152,8 @@
         headers.add("diff");
         printTsv(out, headers);
         for (Path relPath : relPaths) {
-            Repository expectedUpstream = standardRepositories.currentUpstream(relPath);
+            Repository expectedUpstream = standardRepositories.referenceUpstreamAsOfAndroidP(
+                relPath);
             out.print(relPath + "\t");
             Path ojluniFile = standardRepositories.ojluni().absolutePath(relPath);
             List<String> linesB = Util.readLines(ojluniFile);
@@ -207,7 +170,7 @@
                     comparison = "missing";
                 } else {
                     List<String> linesA = Util.readLines(upstreamFile);
-                    int distance = editDistance(linesA, linesB);
+                    int distance = Util.editDistance(linesA, linesB);
                     if (distance == 0) {
                         comparison = "identical";
                     } else {
@@ -230,7 +193,8 @@
             if (!comparisons.get(0).equals("identical")) {
                 Path expectedUpstreamPath = expectedUpstream.pathFromRepository(relPath);
                 if (expectedUpstreamPath != null) {
-                    diffCommand = "${ANDROID_BUILD_TOP}/libcore/tools/upstream/upstream-diff " + relPath;
+                    diffCommand = "${ANDROID_BUILD_TOP}/libcore/tools/upstream/upstream-diff "
+                            + "-r ojluni," + expectedUpstream.name() + " " + relPath;
                 } else {
                     diffCommand = "FILE MISSING";
                 }
@@ -246,7 +210,7 @@
     }
 
     public void run() throws IOException {
-        List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromMakefile();
+        List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromBlueprint();
         run(System.out, relPaths);
     }
 
diff --git a/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java b/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
index 007914f..7137861 100644
--- a/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
+++ b/tools/upstream/src/main/java/libcore/CopyUpstreamFiles.java
@@ -20,7 +20,6 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -36,7 +35,7 @@
     }
 
     public void run() throws IOException {
-        List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromMakefile();
+        List<Path> relPaths = standardRepositories.ojluni().loadRelPathsFromBlueprint();
         if (outputDir.toFile().exists()) {
             throw new IOException(outputDir + " already exists");
         } else {
@@ -46,7 +45,8 @@
             }
         }
         for (Path relPath : relPaths) {
-            Repository expectedUpstream = standardRepositories.currentUpstream(relPath);
+            Repository expectedUpstream = standardRepositories.referenceUpstreamAsOfAndroidP(
+                relPath);
             for (Repository upstream : standardRepositories.upstreams()) {
                 Path upstreamFile = upstream.absolutePath(relPath);
                 if (upstreamFile != null) {
diff --git a/tools/upstream/src/main/java/libcore/Lines.java b/tools/upstream/src/main/java/libcore/Lines.java
new file mode 100644
index 0000000..c60fd0b
--- /dev/null
+++ b/tools/upstream/src/main/java/libcore/Lines.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * A List of lines (eg. from a text file or a command's output).
+ */
+public class Lines extends AbstractList<String> implements RandomAccess {
+    public static Lines EMPTY = new Lines(Collections.emptyList());
+
+    private final List<String> delegate;
+    private volatile int hashCode = 0;
+
+    public Lines(Collection<String> collection) {
+        this.delegate = new ArrayList<>(collection);
+    }
+
+    @Override
+    public int hashCode() {
+        if (hashCode == 0) {
+            hashCode = super.hashCode();
+        }
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o.hashCode() != this.hashCode()) {
+            return false;
+        }
+        return super.equals(o);
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        return Collections.unmodifiableList(delegate).iterator();
+    }
+
+    @Override
+    public String get(int index) {
+        return delegate.get(index);
+    }
+
+    @Override
+    public int size() {
+        return delegate.size();
+    }
+}
diff --git a/tools/upstream/src/main/java/libcore/Repository.java b/tools/upstream/src/main/java/libcore/Repository.java
index 9a4eee6..89f64f0 100644
--- a/tools/upstream/src/main/java/libcore/Repository.java
+++ b/tools/upstream/src/main/java/libcore/Repository.java
@@ -23,7 +23,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,12 +35,50 @@
  */
 abstract class Repository {
 
+    /**
+     * Maps from a file's (current) relPath to the corresponding OpenJDK relPath from
+     * which it has been, and still remains, renamed.
+     */
+    static final Map<Path, Path> OPENJDK_REL_PATH = historicRenames();
+
+    static Map<Path, Path> historicRenames() {
+        Map<Path, Path> result = new HashMap<>();
+        // renamed in libcore commit 583eb0e4738456f0547014a4857a14456be267ee
+        result.put(Paths.get("native/linux_close.cpp"), Paths.get("native/linux_close.c"));
+        // Map ByteBufferAs*Buffer.java to an upstream file, even though there is
+        // not a 1:1 correspondence. This isn't perfect, but allows some rough
+        // comparison. See http://b/111583940
+        //
+        // More detail:
+        // The RI has four different generated files ...Buffer{B,L,RB,RL}.java
+        // for each of these six files specializing on big endian, little endian,
+        // read-only big endian, and read-only little endian, respectively. Those
+        // 6 x 4 files are generated from a single template:
+        //     java/nio/ByteBufferAs-X-Buffer.java.template
+        //
+        // On Android, the four variants {B,L,RB,RL} for each of the six types
+        // are folded into a single class with behavior configured via additional
+        // constructor arguments.
+        //
+        // For now, we map to upstream's "B" variant; "B" is more similar to
+        // Android's files than "RB" or "RL"; the choice of "B" vs. "L" is arbitrary.
+        for (String s : Arrays.asList("Char", "Double", "Float", "Int", "Long", "Short")) {
+            Path ojluniPath = Paths.get("java/nio/ByteBufferAs" + s + "Buffer.java");
+            Path upstreamPath =
+                    Paths.get("java/nio/ByteBufferAs" + s + "BufferB.java");
+            result.put(ojluniPath, upstreamPath);
+        }
+        return Collections.unmodifiableMap(result);
+    }
+
     protected final Path rootPath;
     protected final String name;
+    protected final List<String> sourceDirs;
 
-    protected Repository(Path rootPath, String name) {
+    protected Repository(Path rootPath, String name, List<String> sourceDirs) {
         this.rootPath = Objects.requireNonNull(rootPath);
         this.name = Objects.requireNonNull(name);
+        this.sourceDirs = Objects.requireNonNull(sourceDirs);
         if (!rootPath.toFile().isDirectory()) {
             throw new IllegalArgumentException("Missing or not a directory: " + rootPath);
         }
@@ -55,7 +95,31 @@
         return p == null ? null : rootPath.resolve(p).toAbsolutePath();
     }
 
-    public abstract Path pathFromRepository(Path relPath);
+    public Path pathFromRepository(Path relPath) {
+        // Search across all sourceDirs for the indicated file.
+        for (String sourceDir : sourceDirs) {
+            Path repositoryRelativePath = Paths.get(sourceDir).resolve(relPath);
+            File file = rootPath.resolve(repositoryRelativePath).toFile();
+            if (file.exists()) {
+                return repositoryRelativePath;
+            }
+        }
+        return null;
+    }
+
+    public final Path rootPath() {
+        return rootPath;
+    }
+
+    @Override
+    public int hashCode() {
+      return rootPath.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return (obj instanceof Repository) && rootPath.equals(((Repository) obj).rootPath);
+    }
 
     /**
      * @return A human readable name to identify this repository, suitable for use as a
@@ -76,18 +140,26 @@
      */
     public static Repository openJdk9(Path upstreamRoot, String upstreamName) {
         List<String> sourceDirs = Arrays.asList(
-                "jdk/src/java.base/share/classes",
-                "jdk/src/java.logging/share/classes",
-                "jdk/src/java.prefs/share/classes",
-                "jdk/src/java.sql/share/classes",
-                "jdk/src/java.desktop/share/classes",
-                "jdk/src/java.base/solaris/classes",
-                "jdk/src/java.base/unix/classes",
-                "jdk/src/java.prefs/unix/classes",
-                "jdk/src/jdk.unsupported/share/classes",
-                "jdk/src/jdk.net/share/classes",
-                "jdk/src/java.base/linux/classes",
-                "build/linux-x86_64-normal-server-release/support/gensrc/java.base"
+            "jdk/src/java.base/share/classes",
+            "jdk/src/java.logging/share/classes",
+            "jdk/src/java.prefs/share/classes",
+            "jdk/src/java.sql/share/classes",
+            "jdk/src/java.desktop/share/classes",
+            "jdk/src/java.base/solaris/classes",
+            "jdk/src/java.base/unix/classes",
+            "jdk/src/java.prefs/unix/classes",
+            "jdk/src/jdk.unsupported/share/classes",
+            "jdk/src/jdk.net/share/classes",
+            "jdk/src/java.base/linux/classes",
+            "build/linux-x86_64-normal-server-release/support/gensrc/java.base",
+
+            // Native (.c) files
+            "jdk/src/java.base/unix/native/libjava",
+            "jdk/src/java.base/share/native/libjava",
+            "jdk/src/java.base/unix/native/libnio",
+            "jdk/src/java.base/unix/native/libnio/ch",
+            "jdk/src/java.base/unix/native/libnio/fs",
+            "jdk/src/java.base/unix/native/libnet"
         );
         return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs);
     }
@@ -97,11 +169,27 @@
      * subdirectory {@code upstreamName} under the directory {@code upstreamRoot}.
      */
     public static Repository openJdkLegacy(Path upstreamRoot, String upstreamName) {
-        List<String> sourceDirs = Arrays.asList(
-                "jdk/src/share/classes",
-                "jdk/src/solaris/classes",
-                "build/linux-x86_64-normal-server-release/jdk/gensrc"
-                );
+        List<String> sourceDirs = new ArrayList<>();
+        sourceDirs.addAll(Arrays.asList(
+            "jdk/src/share/classes",
+            "jdk/src/solaris/classes",
+            "build/linux-x86_64-normal-server-release/jdk/gensrc"
+        ));
+
+        // In legacy OpenJDK versions, the source files are organized into a subfolder
+        // hierarchy based on package name, whereas in Android and OpenJDK 9+ they're in
+        // a flat folder. We work around this by just searching through all of the
+        // applicable folders (from which we have sources) in legacy OpenJDK versions.
+        List<String> nativeSourceDirs = new ArrayList<>();
+        List<String> pkgPaths = Arrays.asList("", "java/io", "java/lang", "java/net", "java/nio",
+            "java/util", "java/util/zip", "sun/nio/ch", "sun/nio/fs");
+        for (String pkgPath : pkgPaths) {
+            nativeSourceDirs.add("jdk/src/solaris/native/" + pkgPath);
+            nativeSourceDirs.add("jdk/src/share/native/" + pkgPath);
+            nativeSourceDirs.add("jdk/src/solaris/native/common/" + pkgPath);
+            nativeSourceDirs.add("jdk/src/share/native/common/" + pkgPath);
+        }
+        sourceDirs.addAll(nativeSourceDirs);
 
         return new OpenJdkRepository(upstreamRoot, upstreamName, sourceDirs);
     }
@@ -120,7 +208,6 @@
     }
 
     static class OjluniRepository extends Repository {
-
         /**
          * The repository of ojluni java files belonging to the Android sources under
          * {@code buildTop}.
@@ -129,29 +216,42 @@
          *        {@quote ANDROID_BUILD_TOP} environment variable.
          */
         public OjluniRepository(Path buildTop) {
-            super(buildTop.resolve("libcore"), "ojluni");
+            super(buildTop.resolve("libcore"), "ojluni",
+                /* sourceDirs */ Arrays.asList("ojluni/src/main/java", "ojluni/src/main/native"));
         }
 
 
         @Override
         public Path pathFromRepository(Path relPath) {
-            return Paths.get("ojluni/src/main/java").resolve(relPath);
+            // Enforce that the file exists in ojluni
+            return Objects.requireNonNull(super.pathFromRepository(relPath));
         }
 
         /**
-         * Returns the list of relative paths to .java files parsed from openjdk_java_files.mk
+         * Returns the list of relative paths to files parsed from blueprint files.
          */
-        public List<Path> loadRelPathsFromMakefile() throws IOException {
+        public List<Path> loadRelPathsFromBlueprint() throws IOException {
             List<Path> result = new ArrayList<>();
-            Path makefile = rootPath.resolve("openjdk_java_files.bp");
-            Pattern pattern = Pattern.compile("\"ojluni/src/main/java/(.+\\.java)\"");
-            for (String line : Util.readLines(makefile)) {
+            result.addAll(loadRelPathsFromBlueprint(
+                "openjdk_java_files.bp", "\"ojluni/src/main/java/(.+\\.java)\""));
+            result.addAll(loadRelPathsFromBlueprint(
+                "ojluni/src/main/native/Android.bp", "\\s+\"(.+\\.(?:c|cpp))\","));
+            return result;
+        }
+
+        private List<Path> loadRelPathsFromBlueprint(
+            String blueprintPathString, String patternString) throws IOException {
+            Path blueprintPath = rootPath.resolve(blueprintPathString);
+            Pattern pattern = Pattern.compile(patternString);
+            List<Path> result = new ArrayList<>();
+            for (String line : Util.readLines(blueprintPath)) {
                 Matcher matcher = pattern.matcher(line);
                 while (matcher.find()) {
-                    Path path = new File(matcher.group(1)).toPath();
-                    result.add(path);
+                    Path relPath = Paths.get(matcher.group(1));
+                    result.add(relPath);
                 }
             }
+            Collections.sort(result);
             return result;
         }
 
@@ -162,23 +262,17 @@
     }
 
     static class OpenJdkRepository extends Repository {
-        private final List<String> sourceDirs;
 
         public OpenJdkRepository(Path upstreamRoot, String name, List<String> sourceDirs) {
-            super(upstreamRoot.resolve(name), name);
-            this.sourceDirs = Objects.requireNonNull(sourceDirs);
+            super(upstreamRoot.resolve(name), name, sourceDirs);
         }
 
         @Override
         public Path pathFromRepository(Path relPath) {
-            for (String sourceDir : sourceDirs) {
-                Path repositoryRelativePath = Paths.get(sourceDir).resolve(relPath);
-                Path file = rootPath.resolve(repositoryRelativePath);
-                if (file.toFile().exists()) {
-                    return repositoryRelativePath;
-                }
+            if (OPENJDK_REL_PATH.containsKey(relPath)) {
+                relPath = OPENJDK_REL_PATH.get(relPath);
             }
-            return null;
+            return super.pathFromRepository(relPath);
         }
 
         @Override
@@ -187,5 +281,4 @@
         }
     }
 
-
 }
diff --git a/tools/upstream/src/main/java/libcore/StandardRepositories.java b/tools/upstream/src/main/java/libcore/StandardRepositories.java
index 36478dd..3bdbebf 100644
--- a/tools/upstream/src/main/java/libcore/StandardRepositories.java
+++ b/tools/upstream/src/main/java/libcore/StandardRepositories.java
@@ -22,6 +22,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import libcore.Repository.OjluniRepository;
@@ -31,18 +32,34 @@
 
 public class StandardRepositories {
 
+    private final List<Repository> allUpstreams;
+    // upstreams older than what is currently the default
     private final List<Repository> historicUpstreams;
-    private final Repository defaultUpstream;
-    private final Repository jsr166Upstream;
+    private final Repository openJdk8u121;
+    private final Repository openJdk9b113;
+    private final Repository openJdk7u40;
     private final OjluniRepository ojluni;
 
     private StandardRepositories(Path buildTop, Path upstreamRoot) {
-        this.historicUpstreams = openJdkLegacy(upstreamRoot, Arrays.asList("8u60", "7u40"));
-        this.defaultUpstream = openJdkLegacy(upstreamRoot, "8u121-b13");
-        this.jsr166Upstream = openJdk9(upstreamRoot, "9b113+");
+        // allUpstreams is ordered from latest to earliest
+        Set<Repository> allUpstreams = new LinkedHashSet<>();
+        allUpstreams.add(openJdk9(upstreamRoot, "9+181"));
+        this.openJdk9b113 = addAndReturn(allUpstreams, openJdk9(upstreamRoot, "9b113+"));
+        this.openJdk8u121 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u121-b13"));
+        Repository openJdk8u60 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "8u60"));
+        this.openJdk7u40 = addAndReturn(allUpstreams, openJdkLegacy(upstreamRoot, "7u40"));
+        this.allUpstreams = Collections.unmodifiableList(new ArrayList<>(allUpstreams));
+        this.historicUpstreams = Collections.unmodifiableList(new ArrayList<>(
+                Arrays.asList(openJdk8u60, openJdk7u40)
+        ));
         this.ojluni = new OjluniRepository(buildTop);
     }
 
+    private static Repository addAndReturn(Set<Repository> repositories, Repository repository) {
+        repositories.add(repository);
+        return repository;
+    }
+
     public List<Repository> historicUpstreams() {
         return historicUpstreams;
     }
@@ -55,10 +72,7 @@
      * Returns all upstream repository snapshots, in order from latest to earliest.
      */
     public List<Repository> upstreams() {
-        List<Repository> upstreams = new ArrayList<>(Arrays.asList(
-                jsr166Upstream, defaultUpstream));
-        upstreams.addAll(historicUpstreams);
-        return Collections.unmodifiableList(upstreams);
+        return allUpstreams;
     }
 
     public static StandardRepositories fromEnv() {
@@ -89,18 +103,29 @@
                     "SplittableRandom"
             )));
 
-    public Repository currentUpstream(Path relPath) {
-        boolean isJsr166 = relPath.toString().startsWith("java/util/concurrent");
+    public boolean isJsr166(Path relPath) {
+        boolean result = relPath.startsWith("java/util/concurrent/");
         String ju = "java/util/";
         String suffix = ".java";
-        if (!isJsr166 && relPath.startsWith(ju)) {
+        if (!result && relPath.startsWith(ju)) {
             String name = relPath.toString().substring(ju.length());
             if (name.endsWith(suffix)) {
                 name = name.substring(0, name.length() - suffix.length());
-                isJsr166 = juFilesFromJsr166.contains(name);
+                result = juFilesFromJsr166.contains(name);
             }
         }
-        return isJsr166 ? jsr166Upstream : defaultUpstream;
+        return result;
+    }
+
+    public Repository referenceUpstreamAsOfAndroidP(Path relPath) {
+        boolean isJsr166 = isJsr166(relPath);
+        if (isJsr166) {
+            return openJdk9b113;
+        } else if (relPath.startsWith("java/sql/") || relPath.startsWith("javax/sql/")) {
+            return openJdk7u40;
+        } else {
+            return openJdk8u121;
+        }
     }
 
 }
diff --git a/tools/upstream/src/main/java/libcore/Util.java b/tools/upstream/src/main/java/libcore/Util.java
index d213080..c50e990 100644
--- a/tools/upstream/src/main/java/libcore/Util.java
+++ b/tools/upstream/src/main/java/libcore/Util.java
@@ -17,25 +17,90 @@
 package libcore;
 
 import java.io.BufferedReader;
+import java.io.BufferedWriter;
 import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Utilities for dealing with text file contents.
+ */
 class Util {
     private Util() {
     }
 
-    public static List<String> readLines(Path path) throws IOException {
+    public static Lines readLines(Reader reader) throws IOException {
         List<String> result = new ArrayList<>();
-        try (BufferedReader reader = new BufferedReader(new FileReader(path.toFile()))) {
-            String line;
-            while ((line = reader.readLine()) != null) {
-                result.add(line);
+        BufferedReader br = (reader instanceof BufferedReader)
+                ? (BufferedReader) reader : new BufferedReader(reader);
+        String line;
+        while ((line = br.readLine()) != null) {
+            result.add(line);
+        }
+        return new Lines(result);
+    }
+
+    public static Lines readLines(Path path) throws IOException {
+        try (Reader reader = new FileReader(path.toFile())) {
+            return readLines(reader);
+        }
+    }
+
+    public static void writeLines(Path path, Lines lines) throws IOException {
+        try (PrintStream printStream = new PrintStream(path.toFile())) {
+            for (String line : lines) {
+                printStream.println(line);
             }
         }
-        return result;
+    }
+
+    /**
+     * Computes the edit distance of two lists, i.e. the smallest number of list items to delete,
+     * insert or replace that would transform the content of one list into the other.
+     */
+    public static <T> int editDistance(List<T> a, List<T> b) {
+        if (a.equals(b)) {
+            return 0;
+        }
+        int numB = b.size();
+        int[] prevCost = new int[numB + 1];
+        for (int i = 0; i <= numB; i++) {
+            prevCost[i] = i;
+        }
+        int[] curCost = new int[numB + 1];
+        for (int endA = 1; endA <= a.size(); endA++) {
+            // For each valid index i, prevCost[i] is the edit distance between
+            // a.subList(0, endA-1) and b.sublist(0, i).
+            // We now calculate curCost[end_b] as the edit distance between
+            // a.subList(0, endA) and b.subList(0, endB)
+            curCost[0] = endA;
+            for (int endB = 1; endB <= numB; endB++) {
+                boolean endsMatch = a.get(endA - 1).equals(b.get(endB - 1));
+                curCost[endB] = min(
+                        curCost[endB - 1] + 1, // append item from b
+                        prevCost[endB] + 1, // append item from a
+                        prevCost[endB - 1] + (endsMatch ? 0 : 1)); // match or replace item
+            }
+            int[] tmp = curCost;
+            curCost = prevCost;
+            prevCost = tmp;
+        }
+        return prevCost[numB];
+    }
+
+    private static int min(int a, int b, int c) {
+        if (a < b) {
+            return a < c ? a : c;
+        } else {
+            return b < c ? b : c;
+        }
     }
 
 }
diff --git a/tools/upstream/upstream-diff b/tools/upstream/upstream-diff
index f52fdb5..b689b33 100755
--- a/tools/upstream/upstream-diff
+++ b/tools/upstream/upstream-diff
@@ -51,6 +51,8 @@
 
 import argparse
 import os
+import os.path
+import re
 import subprocess
 import sys
 
@@ -60,27 +62,39 @@
     # Root of repository snapshots. See go/libcore-o-verify for how you'd want to set this.
     ojluni_upstreams = os.environ['OJLUNI_UPSTREAMS']
     for rel_path in rel_paths:
-        if not rel_path.endswith('.java'):
-            # Might be a fully qualified class name
+        # Paths end with a dot and lowercase file extension (.c, .java, ...) but
+        # fully qualified class names do not.
+        if ('/' not in rel_path) and (not re.match('.+\\.[a-z]{1,4}$', rel_path)):
+            # Assume a fully qualified class name
             rel_path = rel_path.replace('.', '/') + '.java'
         paths = []
         for repository in repositories:
-            if repository == "ojluni":
-                paths.append('%s/libcore/ojluni/src/main/java/%s' % (android_build_top, rel_path))
+            if repository == 'ojluni':
+                file_group = 'java/' if rel_path.endswith('.java') else 'native/'
+                paths.append('%s/libcore/ojluni/src/main/%s/%s'
+                             % (android_build_top, file_group, rel_path))
             else:
                 paths.append('%s/%s/%s' % (ojluni_upstreams, repository, rel_path))
         subprocess.call([diff] + paths)
 
 def main():
     parser = argparse.ArgumentParser(
-        description='Compare files between libcore/ojluni and ${OJLUNI_UPSTREAMS}.')
+        description='Compare files between libcore/ojluni and ${OJLUNI_UPSTREAMS}.',
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter, # include default values in help
+    )
+    upstreams = os.environ['OJLUNI_UPSTREAMS']
+    # natsort.natsorted() would be a nicer sort order, but I'd rather avoid the dependency
+    repositories = ['ojluni'] + sorted(
+        [d for d in os.listdir(upstreams) if os.path.isdir(os.path.join(upstreams, d))]
+    )
     parser.add_argument('-r', '--repositories', default='ojluni,expected',
-                    help='Comma-separated list of >= 2 repositories to compare.')
+                    help='Comma-separated list of 2-3 repositories, to compare, in order; '
+                          'available repositories: ' + ' '.join(repositories) + '.')
     parser.add_argument('-d', '--diff', default='meld',
                         help='Application to use for diffing.')
     parser.add_argument('rel_path', nargs="+",
-                        help='File to compare: either a relative path below '
-                             'libcore/ojluni/src/main/java, or a fully qualified class name.')
+                        help='File to compare: either a relative path below libcore/ojluni/'
+                             'src/main/{java,native}, or a fully qualified class name.')
     args = parser.parse_args()
     repositories = args.repositories.split(',')
     if (len(repositories) < 2):
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
similarity index 99%
rename from xml/src/main/java/org/kxml2/io/KXmlParser.java
rename to xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
index e010f1d..3814e63 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
@@ -20,7 +20,7 @@
 
 // Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
 
-package org.kxml2.io;
+package com.android.org.kxml2.io;
 
 import java.io.Closeable;
 import java.io.IOException;
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
similarity index 99%
rename from xml/src/main/java/org/kxml2/io/KXmlSerializer.java
rename to xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
index 25f0924..795448d 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
@@ -19,7 +19,7 @@
  * IN THE SOFTWARE. */
 
 
-package org.kxml2.io;
+package com.android.org.kxml2.io;
 
 import java.io.*;
 import java.util.Locale;
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
index 7215b3e..6190777 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -37,8 +37,8 @@
         serializerClasses = new ArrayList<String>();
 
         try {
-            parserClasses.add(Class.forName("org.kxml2.io.KXmlParser"));
-            serializerClasses.add(Class.forName("org.kxml2.io.KXmlSerializer"));
+            parserClasses.add(Class.forName("com.android.org.kxml2.io.KXmlParser"));
+            serializerClasses.add(Class.forName("com.android.org.kxml2.io.KXmlSerializer"));
         } catch (ClassNotFoundException e) {
             throw new AssertionError();
         }