Merge "[automerger skipped] Merge "[RESTRICT AUTOMERGE] Track behavior change in default HostnameVerifier." into oreo-mr1-cts-dev am: e79d676601 -s ours" into pie-cts-dev am: f79b99d030 -s ours am: 012ae97680 -s ours

am skip reason: subject contains skip directive

Original change: https://android-review.googlesource.com/c/platform/libcore/+/1547918

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I039b060ea930a12a347b67d90e28d16d9ac29b65
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/Android.mk b/Android.mk
index d68f654..465c964 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,12 +23,6 @@
 subdir_makefiles := $(call all-named-subdir-makefiles,$(subdirs))
 
 #
-# Include the definitions to build the Java code.
-#
-
-include $(LOCAL_PATH)/JavaLibrary.mk
-
-#
 # Disable test modules if LIBCORE_SKIP_TESTS environment variable is set.
 #
 
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/CleanSpec.mk b/CleanSpec.mk
index 993d1df..746bbb8 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -54,6 +54,16 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/core*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/core*)
+
+# Remove core-simple bootclasspath artifacts
+$(call add-clean-step, rm -rf $(OUT_DIR)/host/linux-x86/framework/*core-simple*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/host/linux-x86/framework/*/*core-simple*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/*core-simple*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/*/*core-simple*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/*/*core-simple*)
+$(call add-clean-step, touch -c $(OUT_DIR)/host/linux-x86/bin/dex2oat)
+$(call add-clean-step, touch -c $(OUT_DIR)/host/linux-x86/bin/dex2oatd)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/Docs.mk b/Docs.mk
deleted file mode 100644
index 28abc8b..0000000
--- a/Docs.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- mode: makefile -*-
-# List of libcore directories to include in documentation.
-# Shared between libcore and frameworks/base.
-# Exports: libcore_to_document as a list of .java files relative to libcore/.
-
-ifndef libcore_docs_include_once
-
-# List of libcore javadoc source files
-_libcore_files := $(openjdk_javadoc_files) $(non_openjdk_javadoc_files)
-
-_icu_files := \
- $(call find-files-in-subdirs, external/icu, \
-   "*.java", \
-   android_icu4j/src/main/java/android/icu/lang \
-   android_icu4j/src/main/java/android/icu/math \
-   android_icu4j/src/main/java/android/icu/text \
-   android_icu4j/src/main/java/android/icu/util \
-   )
-_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
-# returned that are relative to the build root / $(TOPDIR) and not libcore.
-# BUILD_DROIDDOC requires file names that are relative the *current* LOCAL_DIR so users must account
-# for this.
-# libcore_to_document_generated are files in $(TARGET_OUT_COMMON_INTERMEDIATES)
-libcore_to_document := $(_libcore_files) $(_icu_files)
-libcore_to_document_generated := $(_libcore_generated_files)
-
-libcore_docs_include_once := 1
-endif # libcore_docs_include_once
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 378aca2..2066c42 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -13,29 +13,35 @@
 // limitations under the License.
 
 //
-// Definitions for building the Java library and associated tests.
+// Definitions for building the Android core library and associated tests.
 //
 
-// libcore is divided into modules.
+// The Android core library provides low-level APIs for use by the rest of the
+// Android software stack. It is made up of various parts, some of which can be
+// found in libcore/ and other parts that can be found in various external/
+// directories. See the "core-system-modules" definition for the parts.
+
+// 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 +50,71 @@
     "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 this 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 this 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 for the core library that have been marked up with @hide
+// for the public SDK APIs. Used from frameworks/base/ to indicate the source
+// files for inclusion in the public SDK docs.
+filegroup {
+    name: "core_public_api_files",
+    srcs: [
+        ":core_oj_api_files",
+        ":core_libart_api_files",
+        ":conscrypt_public_api_files",
+    ],
+}
+
+// The set of files for the core library that have been marked up with @hide and
+// API-related annotations. Note that this includes the intra-core and
+// core-platform APIs as well as the public APIs.
+//
+// Some source files in :core_oj_api_files and :openjdk_mmodule_extra_files are
+// annotated by applying annotations to the .annotated.java stubs files in
+// ojluni/annotated/mmodules and rather than in the original source. See the comments
+// in openjdk_java_files.bp for more details.
+filegroup {
+    name: "core_api_files",
+    srcs: [
+        ":apache-xml_api_files",
+        ":bouncycastle_java_files",
+        ":conscrypt_java_files",
+        ":core_oj_api_files",
+        ":core_libart_api_files",
+        ":okhttp_api_files",
+        ":openjdk_mmodule_extra_files",
+    ],
+}
+
 java_defaults {
     name: "libcore_java_defaults",
     javacflags: [
@@ -51,10 +122,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
         ],
     },
 }
@@ -63,50 +134,75 @@
 // Build for the target (device).
 //
 
+// Rule generating resource lib for android_icu4j.
+// In the downstream branch master-icu-dev, the resource files are generated.
+// This rule can't be moved external/icu because soong enforces that no_standard_libs:true can only
+// be used in libcore/ or development/
+java_library {
+    name: "android_icu4j_resources_lib",
+    java_resources: [":android_icu4j_resources"],
+    no_standard_libs: true,
+    system_modules: "none",
+}
+
+// A target used to bootstrap compilation for the core library.
+// See core-all-system-modules for more details.
 java_library {
     name: "core-all",
     defaults: ["libcore_java_defaults"],
 
     srcs: [
-        ":openjdk_java_files",
-        ":non_openjdk_java_files",
-        ":android_icu4j_src_files",
+        ":core_oj_java_files",
+        ":core_libart_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"],
-
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-    ],
-
-    system_modules: "none",
+    static_libs: ["android_icu4j_resources_lib"],
+    java_version: "1.9",
 
     installable: false,
 }
 
+// A system modules definition for use by core library targets only. It only
+// contains the core-all jar, which contains the classes that end up in core-oj,
+// core-libart as well as the lambda stubs needed to compile Java lambda code.
+// It does not contain other parts of core library like conscrypt, bouncycastle,
+// etc. This system_modules definition is used to bootstrap compilation for
+// other parts of the core library like core-oj, core-libart, conscrypt,
+// bouncycastle, etc.
+//
+// If you want to compile against the entire core library implementation, for
+// example to build core library tests, see "core-system-modules" instead.
 java_system_modules {
     name: "core-all-system-modules",
     libs: ["core-all"],
 }
 
+// Contains the parts of core library associated with OpenJDK.
 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",
@@ -126,30 +222,28 @@
 
     notice: "ojluni/NOTICE",
 
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-    ],
-
 }
 
-// Definitions to make the core library.
+// Contains parts of core library not associated with OpenJDK. Contains not
+// just java.*, javax.* code but also android.icu.*, android.system.* and
+// various internal libcore.* packages.
 java_library {
     name: "core-libart",
     defaults: ["libcore_java_defaults"],
+    installable: true,
     hostdex: true,
 
-    srcs: [
-        ":non_openjdk_java_files",
-        ":android_icu4j_src_files",
-    ],
-    java_resources: [":android_icu4j_resources"],
+    srcs: [":core_libart_java_files"],
+    static_libs: ["android_icu4j_resources_lib"],
+    java_version: "1.9",
 
+    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",
@@ -158,16 +252,46 @@
     },
 
     required: [
+        // Device files put in /system.
         "tzdata",
-        "tzlookup.xml",
+        "tz_version",
+        // Files used to simulate the /system and runtime APEX dir
+        // structure on host.
+        "tzdata_host",
+        "tzdata_host_runtime_apex",
+        "tzlookup.xml_host_runtime_apex",
+        "tz_version_host",
+        "tz_version_host_runtime_apex",
     ],
 }
 
-// A guaranteed unstripped version of core-oj and core-libart.
+// Provided solely to contribute information about which hidden parts of the
+// core-oj API are used by apps.
+java_library {
+    name: "core-oj-hiddenapi",
+    defaults: ["libcore_java_defaults"],
+    compile_dex: true,
+
+    srcs: [":openjdk_hiddenapi_javadoc_files"],
+
+    no_standard_libs: true,
+    libs: ["core-all"],
+    system_modules: "core-all-system-modules",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
+//
+// Guaranteed unstripped versions of core-oj and core-libart.
+//
 // The build system may or may not strip the core-oj and core-libart jars,
 // 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"],
@@ -176,15 +300,13 @@
     dex_preopt: {
         enabled: false,
     },
+    java_version: "1.9",
     notice: "ojluni/NOTICE",
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-    ],
 }
 
 java_library {
     name: "core-libart-testdex",
+    installable: true,
     static_libs: ["core-libart"],
     no_standard_libs: true,
     libs: ["core-all"],
@@ -194,23 +316,15 @@
         enabled: false,
     },
     notice: "ojluni/NOTICE",
-    required: [
-        "tzdata",
-        "tzlookup.xml",
-    ],
 }
 
-// A library that exists to satisfy javac when
-// compiling source code that contains lambdas.
-java_library {
-    name: "core-lambda-stubs",
+
+java_defaults {
+    name: "core_lambda_stubs_defaults",
     defaults: ["libcore_java_defaults"],
+    hostdex: true,
 
-    srcs: [
-        ":openjdk_lambda_stub_files",
-        ":openjdk_lambda_duplicate_stub_files",
-    ],
-
+    no_standard_libs: true,
     libs: ["core-all"],
     system_modules: "core-all-system-modules",
     openjdk9: {
@@ -223,99 +337,368 @@
     include_srcs: true,
 }
 
+// Creates a jar that exists to satisfy javac when compiling source code that
+// contains lambdas. This contains all classes / methods required by javac
+// when generating invoke-dynamic lambda implementation code, even those that
+// are also in the public SDK API from API level 26 onwards.
+java_library {
+    name: "core-lambda-stubs",
+    defaults: ["core_lambda_stubs_defaults"],
+    srcs: [
+        ":openjdk_lambda_stub_files",
+        ":openjdk_lambda_duplicate_stub_files",
+    ],
+}
+
+// An alternative to core-lambda-stubs that omits openjdk_lambda_duplicate_stub_files
+// because those classes are also part of the core library public SDK API
+// (since API level 26).
+java_library {
+    name: "core-lambda-stubs-for-system-modules",
+    defaults: ["core_lambda_stubs_defaults"],
+    srcs: [
+        ":openjdk_lambda_stub_files",
+    ],
+}
+
+// A system modules definition containing the implementations for the various
+// parts that make up the core library.
+//
+// This system module is intended for use by tests that may need access to
+// core library internals. It should not be generally used; most of the
+// platform build should build against API stubs instead. See
+// "core-platform-api-stubs-system-modules", which is the default used by the
+// Android build.
+//
+// This module also includes lambda stubs for compiling source containing
+// Java lambdas.
 java_system_modules {
     name: "core-system-modules",
     libs: [
         "core-oj",
         "core-libart",
-        "core-lambda-stubs",
+        "bouncycastle",
+        "conscrypt",
+        "okhttp",
+        "apache-xml",
+        // This one is not on device but it's needed when javac compiles code
+        // containing lambdas.
+        "core-lambda-stubs-for-system-modules",
     ],
 }
 
-// Build libcore test rules
+// Builds libcore test rules
 java_library_static {
     name: "core-test-rules",
     hostdex: true,
-    no_framework_libs: true,
     srcs: [
         "dalvik/test-rules/src/main/**/*.java",
         "test-rules/src/main/**/*.java",
     ],
     static_libs: ["junit"],
+
+    no_standard_libs: true,
+    libs: ["core-all"],
+    system_modules: "core-all-system-modules",
 }
 
-// Make the core-tests-support library.
+// Builds the core-tests-support library used by various tests.
 java_library_static {
     name: "core-tests-support",
     hostdex: true,
-    no_framework_libs: true,
     srcs: ["support/src/test/java/**/*.java"],
-    libs: [
-        "junit",
-        "bouncycastle",
-    ],
+
+    no_framework_libs: true,
+    libs: ["junit"],
     static_libs: [
-        "bouncycastle-bcpkix",
-        "bouncycastle-ocsp",
+        "bouncycastle-unbundled",
+        "bouncycastle-bcpkix-unbundled",
+        "bouncycastle-ocsp-unbundled",
     ],
 }
 
-// Make the jsr166-tests library.
-java_library_static {
+// Builds the jsr166-tests library.
+java_test {
     name: "jsr166-tests",
     srcs: ["jsr166-tests/src/test/java/**/*.java"],
-    no_framework_libs: true,
+    no_standard_libs: true,
     libs: [
+        "core-all",
         "junit",
     ],
+    system_modules: "core-all-system-modules",
 }
 
-genrule {
-    name: "gen-ojluni-jaif-annotated-srcs",
-    tools: [
-        "gen-annotated-java-files-bp",
-        "soong_zip",
-    ],
-    tool_files: [
-        ":insert-annotations-to-source",
-        "annotations/ojluni.jaif",
-    ],
-    srcs: [
-        ":annotated_ojluni_files",
-    ],
-    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",
-    ],
+// Builds 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"],
+    },
 }
 
-droiddoc {
-    name: "core-docs",
+// Builds 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"],
+    },
+}
+
+// Builds the core-tests library.
+java_test {
+    name: "core-tests",
+    defaults: ["libcore_java_defaults"],
+    hostdex: true,
     srcs: [
-        ":openjdk_javadoc_files",
-        ":non_openjdk_javadoc_files",
-        ":android_icu4j_src_files_for_docs",
-        ":gen-ojluni-jaif-annotated-srcs",
+        "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",
+        "test-rules/src/test/java/**/*.java",
+        "xml/src/test/java/**/*.java",
     ],
     exclude_srcs: [
-        ":annotated_ojluni_files",
+        "luni/src/test/java/libcore/java/util/zip/Zip64Test.java",
+        "luni/src/test/java/libcore/java/util/zip/Zip64FileTest.java",
     ],
-    custom_template: "droiddoc-templates-sdk",
-    hdf: [
-        "android.whichdoc offline",
+
+    java_resource_dirs: [
+        "*/src/test/java",
+        "*/src/test/resources",
     ],
-    knowntags: [
+    exclude_java_resource_dirs: [
+        "ojluni/src/test/java",
+        "ojluni/src/test/resources",
+    ],
+
+    java_resources: [
+        ":filesystemstest",
+        ":parameter-metadata-test",
+    ],
+
+    no_standard_libs: true,
+    libs: [
+        "core-all",
+        "okhttp",
+        "bouncycastle",
+    ],
+    system_modules: "core-all-system-modules",
+
+    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",
+        "truth-prebuilt",
+    ],
+
+    errorprone: {
+        javacflags: [
+            "-Xep:TryFailThrowable:ERROR",
+            "-Xep:ComparisonOutOfRange:ERROR",
+        ],
+    },
+
+    test_config: "AndroidTest-core-tests.xml",
+}
+
+// Builds the core-ojtests library that contains test code from OpenJDK.
+java_test {
+    name: "core-ojtests",
+    defaults: ["libcore_java_defaults"],
+    hostdex: true,
+
+    srcs: [
+        "ojluni/src/test/java/**/*.java",
+    ],
+    java_resource_dirs: [
+        "ojluni/src/test/java",
+        "ojluni/src/test/resources",
+    ],
+
+    no_standard_libs: true,
+    libs: [
+        "core-all",
+        "okhttp",
+        "bouncycastle",
+    ],
+    system_modules: "core-all-system-modules",
+
+    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",
+}
+
+// Builds the core-ojtests-public library. Excludes any private API tests.
+// Like core-ojtests but smaller.
+java_test {
+    name: "core-ojtests-public",
+    defaults: ["libcore_java_defaults"],
+    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",
+    ],
+
+    no_standard_libs: true,
+    libs: [
+        "core-all",
+        "bouncycastle",
+        "okhttp",
+        "testng",
+    ],
+    system_modules: "core-all-system-modules",
+}
+
+// Exports annotated stubs source files in ojluni/annotations/sdk to make them
+// available to metalava. Used for nullability annotations in OpenJDK source.
+droiddoc_exported_dir {
+    name: "ojluni-annotated-sdk-stubs",
+    path: "ojluni/annotations/sdk",
+}
+droiddoc_exported_dir {
+    name: "ojluni-annotated-nullability-stubs",
+    path: "ojluni/annotations/sdk/nullability",
+}
+
+// Exports annotated stubs source files in ojluni/annotations/mmodules to make
+// them available to metalava. Used for core platform API and intra-code API
+// annotations in OpenJDK source.
+droiddoc_exported_dir {
+    name: "ojluni-annotated-mmodule-stubs",
+    path: "ojluni/annotations/mmodule",
+}
+
+// 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: [
         "known_oj_tags.txt",
     ],
-    proofread_file: "core-docs-proofread.txt",
-    todo_file: "core-docs-todo.html",
-    args: "-offlinemode -title \"libcore\"",
+}
+
+// Generates stubs for the parts of the public SDK API provided by the core
+// library.
+//
+// Only for use by core.current.stubs target below.
+droidstubs {
+    name: "core-current-stubs-gen",
+    srcs: [":core_api_files"],
+    java_version: "1.9",
+    installable: false,
+    no_framework_libs: true,
+    args: " --exclude-annotations "
+        + "--hide-annotation libcore.api.Hide",
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
+}
+
+// A stubs target containing the parts of the public SDK API provided by the
+// core library.
+//
+// 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",
+
+    dist: {
+        targets: [
+            "sdk",
+            "win_sdk",
+        ],
+    },
+}
+
+// Target for validating nullability annotations for correctness and
+// completeness. To check that there are no nullability errors:
+//   make core-current-stubs-nullability-validation
+// To check that there are only the expected nullability warnings:
+//   make core-current-stubs-nullability-validation-check-nullability-warnings
+// To update the the list of known expected nullability warnings:
+//   make core-current-stubs-nullability-validation-update-nullability-warnings
+droidstubs {
+    name: "core-current-stubs-nullability-validation",
+    srcs: [":core_api_files"],
+    installable: false,
+    no_framework_libs: true,
+    annotations_enabled: true,
+    args: "--hide-annotation libcore.api.Hide " +
+        "--validate-nullability-from-merged-stubs ",
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
+    merge_annotations_dirs: [
+        "metalava-manual",
+        // N.B. Stubs in this filegroup will be validated:
+        "ojluni-annotated-nullability-stubs",
+    ],
+    // The list of classes which have nullability annotations included in the source.
+    // (This is in addition to those which have annotations in the merged stubs.)
+    validate_nullability_from_list: "nullability_annotated_classes.txt",
+    // The expected set of warnings about missing annotations:
+    check_nullability_warnings: "nullability_warnings.txt",
+}
+
+// A host library containing time zone related classes. Used for
+// host-side tools and tests that have to deal with Android
+// time zone data.
+java_library_host {
+    name: "timezone-host",
+    srcs: [":timezone_host_files"],
 }
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
deleted file mode 100644
index 81fb460..0000000
--- a/JavaLibrary.mk
+++ /dev/null
@@ -1,411 +0,0 @@
-# -*- mode: makefile -*-
-# 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.
-
-#
-# 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.
-$(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..38f57b3 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",
@@ -38,12 +37,9 @@
 
 cc_defaults {
     name: "core_native_default_libs",
-    static_libs: [
-        "libbase",
-        "libfdlibm",
-    ],
 
     shared_libs: [
+        "libbase",
         "liblog",
         "libnativehelper",
     ],
@@ -59,8 +55,9 @@
         ":luni_native_srcs",
         "dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp",
     ],
-
     shared_libs: [
+        "libandroidio",
+        "libbase",
         "libcrypto",
         "libexpat",
         "libicuuc",
@@ -70,17 +67,36 @@
     ],
     static_libs: [
         "libziparchive",
-        "libbase",
     ],
     target: {
         android: {
-            shared_libs: [
-                "libutils",
+            cflags: [
+                // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
+                // See external/icu/android_icu4c/include/uconfig_local.h
+                // for more information.
+                "-DANDROID_LINK_SHARED_ICU4C",
             ],
         },
     },
 }
 
+cc_library_shared {
+    name: "libandroidio",
+    defaults: [
+        "core_native_default_flags",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    srcs: [
+        ":libandroidio_srcs",
+    ],
+    stubs: {
+        symbol_file: "libandroidio.map.txt",
+        versions: ["1"],
+    },
+}
+
 cc_defaults {
     name: "libopenjdk_native_defaults",
     defaults: [
@@ -88,6 +104,9 @@
         "core_native_default_libs",
     ],
     srcs: [":libopenjdk_native_srcs"],
+    include_dirs: [
+        "libcore/luni/src/main/native",
+    ],
     cflags: [
         // TODO(narayan): Prune down this list of exclusions once the underlying
         // issues have been fixed. Most of these are small changes except for
@@ -97,18 +116,14 @@
         "-Wno-parentheses-equality",
         "-Wno-constant-logical-operand",
         "-Wno-sometimes-uninitialized",
-
-        // TODO(http://b/64362645): remove when upstream replaces readdir_r with readdir.
-        "-Wno-deprecated-declarations",
     ],
 
     shared_libs: [
+        "libandroidio",
         "libcrypto",
         "libicuuc",
-        "libssl",
-        "libz",
-
         "libnativehelper",
+        "libz",
     ],
     static_libs: ["libfdlibm"],
 
@@ -121,6 +136,17 @@
                 "-D__GLIBC__",
             ],
         },
+        android: {
+            cflags: [
+                // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
+                // See external/icu/android_icu4c/include/uconfig_local.h
+                // for more information.
+                "-DANDROID_LINK_SHARED_ICU4C",
+            ],
+            shared_libs: [
+                "libdl_android",
+            ],
+        },
     },
 
     notice: "ojluni/NOTICE",
diff --git a/OWNERS b/OWNERS
index 91f818d..c35f898 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,15 +4,17 @@
 # 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
+nikitai@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
+dbrazdil@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..3a75225
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,10 @@
+[Hook Scripts]
+# Ensure there are no GPL-licensed files under:
+# * luni/src/main/java
+# * json/src/main/java
+# * xml/src/main/java
+checkstyle-luni-json-xml = java -jar ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.jar -c tools/checkstyle/checkstyle-forbid-gpl.xml luni/src/main/java json/src/main/java xml/src/main/java
+
+# Ensure there are no Apache-licensed files under:
+# * ojluni/src/main/java
+checkstyle-ojluni        = java -jar ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.jar -c tools/checkstyle/checkstyle-forbid-apache.xml ojluni/src/main/java
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..f8c149d
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsSaxTestCases"
+    }
+  ]
+}
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/Android.mk b/benchmarks/Android.mk
index b73f167..623ba9c 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -27,10 +27,7 @@
   caliper-api-target \
   core-oj \
   core-libart \
-  conscrypt \
-  android.test.base \
-  bouncycastle \
-  framework
+  android.test.base
 LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/data/caliperperf
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
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/GetInstancesOfClassesBenchmark.java b/benchmarks/src/benchmarks/GetInstancesOfClassesBenchmark.java
deleted file mode 100644
index 2e85fae..0000000
--- a/benchmarks/src/benchmarks/GetInstancesOfClassesBenchmark.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2017 Google Inc.
- *
- * 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 dalvik.system.VMDebug;
-
-public class GetInstancesOfClassesBenchmark {
-    private static class ObjectTree {
-        ObjectTree left;
-        ObjectTree right;
-
-        public ObjectTree(int depth) {
-            if (depth > 1) {
-                left = new ObjectTree(depth - 1);
-                right = new ObjectTree(depth - 1);
-            }
-        }
-    }
-
-    // 2^19 = 524288
-    private static ObjectTree tree = new ObjectTree(19);
-
-    public void timeGetInstancesOf1Class(int reps) {
-        Class[] classes = new Class[]{
-            Integer.class
-        };
-        for (int rep = 0; rep < reps; ++rep) {
-            VMDebug.getInstancesOfClasses(classes, true);
-        }
-    }
-
-    public void timeGetInstancesOf2Classes(int reps) {
-        Class[] classes = new Class[]{
-            Integer.class,
-            Long.class
-        };
-        for (int rep = 0; rep < reps; ++rep) {
-            VMDebug.getInstancesOfClasses(classes, true);
-        }
-    }
-
-    public void timeGetInstancesOf4Classes(int reps) {
-        Class[] classes = new Class[]{
-            Integer.class,
-            Long.class,
-            Float.class,
-            Double.class
-        };
-        for (int rep = 0; rep < reps; ++rep) {
-            VMDebug.getInstancesOfClasses(classes, true);
-        }
-    }
-}
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/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java b/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java
deleted file mode 100644
index 3cde240..0000000
--- a/benchmarks/src/benchmarks/regression/DateIntervalFormatBenchmark.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc.
- *
- * 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.regression;
-
-import android.icu.util.TimeZone;
-import android.icu.util.ULocale;
-import libcore.icu.DateIntervalFormat;
-
-import static libcore.icu.DateUtilsBridge.*;
-
-public class DateIntervalFormatBenchmark {
-  public void timeDateIntervalFormat_formatDateRange_DATE(int reps) throws Exception {
-    ULocale l = ULocale.US;
-    TimeZone utc = TimeZone.getTimeZone("UTC");
-    int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      DateIntervalFormat.formatDateRange(l, utc, 0L, 0L, flags);
-    }
-  }
-
-  public void timeDateIntervalFormat_formatDateRange_TIME(int reps) throws Exception {
-    ULocale l = ULocale.US;
-    TimeZone utc = TimeZone.getTimeZone("UTC");
-    int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      DateIntervalFormat.formatDateRange(l, utc, 0L, 0L, flags);
-    }
-  }
-
-  public void timeDateIntervalFormat_formatDateRange_DATE_TIME(int reps) throws Exception {
-    ULocale l = ULocale.US;
-    TimeZone utc = TimeZone.getTimeZone("UTC");
-    int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_TIME | FORMAT_24HOUR;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      DateIntervalFormat.formatDateRange(l, utc, 0L, 0L, flags);
-    }
-  }
-}
diff --git a/benchmarks/src/benchmarks/regression/DateToStringBenchmark.java b/benchmarks/src/benchmarks/regression/DateToStringBenchmark.java
deleted file mode 100644
index 052fe38..0000000
--- a/benchmarks/src/benchmarks/regression/DateToStringBenchmark.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * 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.regression;
-
-import android.text.format.DateFormat;
-import com.google.caliper.BeforeExperiment;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-public final class DateToStringBenchmark {
-    Date date;
-    Calendar calendar;
-    SimpleDateFormat format;
-
-    @BeforeExperiment
-    protected void setUp() throws Exception {
-        date = new Date(0);
-        calendar = new GregorianCalendar();
-        calendar.setTime(date);
-        format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
-    }
-
-    public void timeDateToString(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            date.toString();
-        }
-    }
-
-    public void timeDateToString_Formatter(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(date);
-        }
-    }
-
-    public void timeDateToString_ClonedFormatter(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            ((SimpleDateFormat) format.clone()).format(date);
-        }
-    }
-
-    public void timeDateToString_AndroidDateFormat(int reps) {
-        for (int i = 0; i < reps; i++) {
-            DateFormat.format("EEE MMM dd HH:mm:ss zzz yyyy", calendar);
-        }
-    }
-}
diff --git a/benchmarks/src/benchmarks/regression/DigestBenchmark.java b/benchmarks/src/benchmarks/regression/DigestBenchmark.java
deleted file mode 100644
index e576d87..0000000
--- a/benchmarks/src/benchmarks/regression/DigestBenchmark.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * 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.regression;
-
-import com.android.org.bouncycastle.crypto.Digest;
-import com.google.caliper.BeforeExperiment;
-import com.google.caliper.Param;
-
-public class DigestBenchmark {
-
-    private static final int DATA_SIZE = 8192;
-    private static final byte[] DATA = new byte[DATA_SIZE];
-    static {
-        for (int i = 0; i < DATA_SIZE; i++) {
-            DATA[i] = (byte)i;
-        }
-    }
-
-    @Param private Algorithm algorithm;
-
-    public enum Algorithm { MD5, SHA1, SHA256,  SHA384, SHA512 };
-
-    @Param private Implementation implementation;
-
-    public enum Implementation { OPENSSL, BOUNCYCASTLE };
-
-    private Class<? extends Digest> digestClass;
-
-    @BeforeExperiment
-    protected void setUp() throws Exception {
-        String className = "com.android.org.bouncycastle.crypto.digests.";
-        switch (implementation) {
-            case OPENSSL:
-                className += ("OpenSSLDigest$" + algorithm);
-                break;
-            case BOUNCYCASTLE:
-                className += (algorithm + "Digest");
-                break;
-            default:
-                throw new RuntimeException(implementation.toString());
-        }
-        this.digestClass = (Class<? extends Digest>)Class.forName(className);
-    }
-
-    public void time(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            Digest digest = digestClass.newInstance();
-            digest.update(DATA, 0, DATA_SIZE);
-            digest.doFinal(new byte[digest.getDigestSize()], 0);
-        }
-    }
-}
diff --git a/benchmarks/src/benchmarks/regression/IcuBenchmark.java b/benchmarks/src/benchmarks/regression/IcuBenchmark.java
deleted file mode 100644
index 47661b8..0000000
--- a/benchmarks/src/benchmarks/regression/IcuBenchmark.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc.
- *
- * 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.regression;
-
-import java.util.Locale;
-import libcore.icu.ICU;
-
-public class IcuBenchmark {
-
-    private static final String ASCII_LOWERCASE = makeUnicodeRange(97, 122);
-    private static final String ASCII_UPPERCASE = makeUnicodeRange(65, 90);
-
-    private static final String LAT_1_SUPPLEMENT = makeUnicodeRange(0xC0, 0xFF);
-    private static final String LAT_EXTENDED_A = makeUnicodeRange(0x100, 0x17F);
-    private static final String LAT_EXTENDED_B = makeUnicodeRange(0x180, 0x24F);
-
-    private static final Locale CZECH_LOCALE = Locale.forLanguageTag("cs-CZ");
-    private static final Locale PINYIN_LOCALE = Locale.forLanguageTag("zh-Latn");
-
-    public static String makeUnicodeRange(int startingCodePoint, int endingCodePoint) {
-        char[] tmp = new char[endingCodePoint - startingCodePoint + 1];
-        for (int i = startingCodePoint; i <= endingCodePoint; i++) {
-            tmp[i - startingCodePoint] = (char) i;
-        }
-        return new String(tmp);
-    }
-
-    public void time_getBestDateTimePattern(int reps) throws Exception {
-        for (int rep = 0; rep < reps; ++rep) {
-            ICU.getBestDateTimePattern("dEEEMMM", new Locale("en", "US"));
-        }
-    }
-
-    // Convert standard lowercase ASCII characters to uppercase using ICU4C in the US locale.
-    public void time_toUpperCaseAsciiUS(int reps) {
-        for (int i = 0; i < reps; i++) {
-            ICU.toUpperCase(ASCII_LOWERCASE, Locale.US);
-        }
-    }
-
-    // Convert standard uppercase ASCII characters to lowercase.
-    public void time_toLowerCaseAsciiUs(int reps) {
-        for (int i = 0; i < reps; i++) {
-            ICU.toLowerCase(ASCII_UPPERCASE, Locale.US);
-        }
-    }
-
-    // Convert Latin 1 supplement characters to uppercase in France locale.
-    public void time_toUpperCaseLat1SuplFr(int reps) {
-        for (int i = 0; i < reps; i++) {
-            ICU.toUpperCase(LAT_1_SUPPLEMENT, Locale.FRANCE);
-        }
-    }
-
-    // Convert Latin Extension A characters to uppercase in Czech locale
-    public void time_toUpperCaseLatExtACz(int reps) {
-        for (int i = 0; i < reps; i++) {
-            ICU.toUpperCase(LAT_EXTENDED_A, CZECH_LOCALE);
-        }
-    }
-
-    // Convert Latin Extension B characters to uppercase in Pinyin locale.
-    public void time_toUpperCaseLatExtBPinyin(int reps) {
-        for (int i = 0; i < reps; i++) {
-            ICU.toUpperCase(LAT_EXTENDED_B, PINYIN_LOCALE);
-        }
-    }
-
-}
diff --git a/benchmarks/src/benchmarks/regression/ParseBenchmark.java b/benchmarks/src/benchmarks/regression/ParseBenchmark.java
deleted file mode 100644
index 8f52a34..0000000
--- a/benchmarks/src/benchmarks/regression/ParseBenchmark.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.
- *
- * 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.regression;
-
-import com.google.caliper.BeforeExperiment;
-import com.google.caliper.Param;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.SAXParserFactory;
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.xml.sax.InputSource;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xmlpull.v1.XmlPullParser;
-
-/**
- * Measure throughput of various parsers.
- *
- * <p>This benchmark requires that ParseBenchmarkData.zip is on the classpath.
- * That file contains Twitter feed data, which is representative of what
- * applications will be parsing.
- */
-public final class ParseBenchmark {
-
-    @Param Document document;
-    @Param Api api;
-
-    private enum Document {
-        TWEETS,
-        READER_SHORT,
-        READER_LONG
-    }
-
-    private enum Api {
-        ANDROID_STREAM("json") {
-            @Override Parser newParser() {
-                return new AndroidStreamParser();
-            }
-        },
-        ORG_JSON("json") {
-            @Override Parser newParser() {
-                return new OrgJsonParser();
-            }
-        },
-        XML_PULL("xml") {
-            @Override Parser newParser() {
-                return new GeneralXmlPullParser();
-            }
-        },
-        XML_DOM("xml") {
-            @Override Parser newParser() {
-                return new XmlDomParser();
-            }
-        },
-        XML_SAX("xml") {
-            @Override Parser newParser() {
-                return new XmlSaxParser();
-            }
-        };
-
-        final String extension;
-
-        private Api(String extension) {
-            this.extension = extension;
-        }
-
-        abstract Parser newParser();
-    }
-
-    private String text;
-    private Parser parser;
-
-    @BeforeExperiment
-    protected void setUp() throws Exception {
-        text = resourceToString("/" + document.name() + "." + api.extension);
-        parser = api.newParser();
-    }
-
-    public void timeParse(int reps) throws Exception {
-        for (int i = 0; i < reps; i++) {
-            parser.parse(text);
-        }
-    }
-
-    private static String resourceToString(String path) throws Exception {
-        InputStream in = ParseBenchmark.class.getResourceAsStream(path);
-        if (in == null) {
-            throw new IllegalArgumentException("No such file: " + path);
-        }
-
-        Reader reader = new InputStreamReader(in, "UTF-8");
-        char[] buffer = new char[8192];
-        StringWriter writer = new StringWriter();
-        int count;
-        while ((count = reader.read(buffer)) != -1) {
-            writer.write(buffer, 0, count);
-        }
-        reader.close();
-        return writer.toString();
-    }
-
-    interface Parser {
-        void parse(String data) throws Exception;
-    }
-
-    private static class AndroidStreamParser implements Parser {
-        @Override public void parse(String data) throws Exception {
-            android.util.JsonReader jsonReader
-                    = new android.util.JsonReader(new StringReader(data));
-            readToken(jsonReader);
-            jsonReader.close();
-        }
-
-        public void readObject(android.util.JsonReader reader) throws IOException {
-            reader.beginObject();
-            while (reader.hasNext()) {
-                reader.nextName();
-                readToken(reader);
-            }
-            reader.endObject();
-        }
-
-        public void readArray(android.util.JsonReader reader) throws IOException {
-            reader.beginArray();
-            while (reader.hasNext()) {
-                readToken(reader);
-            }
-            reader.endArray();
-        }
-
-        private void readToken(android.util.JsonReader reader) throws IOException {
-            switch (reader.peek()) {
-            case BEGIN_ARRAY:
-                readArray(reader);
-                break;
-            case BEGIN_OBJECT:
-                readObject(reader);
-                break;
-            case BOOLEAN:
-                reader.nextBoolean();
-                break;
-            case NULL:
-                reader.nextNull();
-                break;
-            case NUMBER:
-                reader.nextLong();
-                break;
-            case STRING:
-                reader.nextString();
-                break;
-            default:
-                throw new IllegalArgumentException("Unexpected token" + reader.peek());
-            }
-        }
-    }
-
-    private static class OrgJsonParser implements Parser {
-        @Override public void parse(String data) throws Exception {
-            if (data.startsWith("[")) {
-                new JSONArray(data);
-            } else if (data.startsWith("{")) {
-                new JSONObject(data);
-            } else {
-                throw new IllegalArgumentException();
-            }
-        }
-    }
-
-    private static class GeneralXmlPullParser implements Parser {
-        @Override public void parse(String data) throws Exception {
-            XmlPullParser xmlParser = android.util.Xml.newPullParser();
-            xmlParser.setInput(new StringReader(data));
-            xmlParser.nextTag();
-            while (xmlParser.next() != XmlPullParser.END_DOCUMENT) {
-                xmlParser.getName();
-                xmlParser.getText();
-            }
-        }
-    }
-
-    private static class XmlDomParser implements Parser {
-        @Override public void parse(String data) throws Exception {
-            DocumentBuilderFactory.newInstance().newDocumentBuilder()
-                    .parse(new InputSource(new StringReader(data)));
-        }
-    }
-
-    private static class XmlSaxParser implements Parser {
-        @Override public void parse(String data) throws Exception {
-            SAXParserFactory.newInstance().newSAXParser().parse(
-                    new InputSource(new StringReader(data)), new DefaultHandler());
-        }
-    }
-}
diff --git a/benchmarks/src/benchmarks/regression/RelativeDateTimeFormatterBenchmark.java b/benchmarks/src/benchmarks/regression/RelativeDateTimeFormatterBenchmark.java
deleted file mode 100644
index 6ddbc77..0000000
--- a/benchmarks/src/benchmarks/regression/RelativeDateTimeFormatterBenchmark.java
+++ /dev/null
@@ -1,66 +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 benchmarks.regression;
-
-import java.util.Locale;
-import java.util.TimeZone;
-
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_RELATIVE;
-import static libcore.icu.RelativeDateTimeFormatter.getRelativeDateTimeString;
-import static libcore.icu.RelativeDateTimeFormatter.getRelativeTimeSpanString;
-
-public class RelativeDateTimeFormatterBenchmark {
-  public void timeRelativeDateTimeFormatter_getRelativeTimeSpanString(int reps) throws Exception {
-    Locale l = Locale.US;
-    TimeZone utc = TimeZone.getTimeZone("Europe/London");
-    int flags = 0;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      getRelativeTimeSpanString(l, utc, 0L, 0L, 0L, flags);
-    }
-  }
-
-  public void timeRelativeDateTimeFormatter_getRelativeTimeSpanString_ABBREV(int reps) throws Exception {
-    Locale l = Locale.US;
-    TimeZone utc = TimeZone.getTimeZone("UTC");
-    int flags = FORMAT_ABBREV_RELATIVE;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      getRelativeTimeSpanString(l, utc, 0L, 0L, 0L, flags);
-    }
-  }
-
-  public void timeRelativeDateTimeFormatter_getRelativeDateTimeString(int reps) throws Exception {
-    Locale l = Locale.US;
-    TimeZone utc = TimeZone.getTimeZone("UTC");
-    int flags = 0;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      getRelativeDateTimeString(l, utc, 0L, 0L, 0L, 0L, flags);
-    }
-  }
-
-  public void timeRelativeDateTimeFormatter_getRelativeDateTimeString_ABBREV(int reps) throws Exception {
-    Locale l = Locale.US;
-    TimeZone utc = TimeZone.getTimeZone("America/Los_Angeles");
-    int flags = FORMAT_ABBREV_RELATIVE;
-
-    for (int rep = 0; rep < reps; ++rep) {
-      getRelativeDateTimeString(l, utc, 0L, 0L, 0L, 0L, flags);
-    }
-  }
-}
diff --git a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
deleted file mode 100644
index 1693157..0000000
--- a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.
- *
- * 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.regression;
-
-import com.google.caliper.Param;
-import java.util.Locale;
-
-public class StringCaseMappingBenchmark {
-    enum Inputs {
-        EMPTY(""),
-
-        // TODO: include hairy inputs like turkish and greek.
-        // TODO: locale makes a difference too.
-
-        LOWER2(lower(2)),
-        UPPER2(upper(2)),
-        MIXED2(mixed(2)),
-
-        LOWER8(lower(8)),
-        UPPER8(upper(8)),
-        MIXED8(mixed(8)),
-
-        LOWER32(lower(32)),
-        UPPER32(upper(32)),
-        MIXED32(mixed(32)),
-
-        LOWER512(lower(512)),
-        UPPER512(upper(512)),
-        MIXED512(mixed(512)),
-
-        LOWER2048(lower(2048)),
-        UPPER2048(upper(2048)),
-        MIXED2048(mixed(2048)),
-
-        LOWER_1M(lower(1024*1024)),
-        UPPER_1M(upper(1024*1024)),
-        MIXED_1M(mixed(1024*1024));
-
-        final String value;
-        private Inputs(String value) { this.value = value; }
-        private static String lower(int length) {
-            return makeString(length, "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz");
-        }
-        private static String upper(int length) {
-            return makeString(length, "A0B1C2D3E4F5G6H7I8J9KLMNOPQRSTUVWXYZ");
-        }
-        private static String mixed(int length) {
-            return makeString(length, "Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9KkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
-        }
-        private static String makeString(int length, String alphabet) {
-            StringBuilder sb = new StringBuilder(length);
-            for (int i = 0; i < length; ++i) {
-                sb.append(alphabet.charAt(i % alphabet.length()));
-            }
-            return sb.toString();
-        }
-    }
-    @Param private Inputs s;
-
-    public void timeToUpperCase_US(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            s.value.toUpperCase(Locale.US);
-        }
-    }
-
-    // toUpperCase for Greek is an extra-hard case that uses icu4c's Transliterator.
-    public void timeToUpperCase_el_GR(int reps) {
-        Locale el_GR = new Locale("el", "GR");
-        for (int i = 0; i < reps; ++i) {
-            s.value.toUpperCase(el_GR);
-        }
-    }
-
-    public void timeToLowerCase_US(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            s.value.toLowerCase(Locale.US);
-        }
-    }
-
-    public void timeToUpperCase_Ascii(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            toUpperCaseAscii(s.value);
-        }
-    }
-
-    public void timeToLowerCase_Ascii(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            toLowerCaseAscii(s.value);
-        }
-    }
-
-    public void timeToUpperCase_ICU(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            libcore.icu.ICU.toUpperCase(s.value, Locale.US);
-        }
-    }
-
-    public void timeToLowerCase_ICU(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            libcore.icu.ICU.toLowerCase(s.value, Locale.US);
-        }
-    }
-
-    public static String toUpperCaseAscii(String s) {
-        for (int i = 0, length = s.length(); i < length; i++) {
-            char c = s.charAt(i);
-            if (c < 'a' || c > 'z') {
-                continue; // fast path avoids allocation
-            }
-
-            // slow path: s contains lower case chars
-            char[] result = s.toCharArray();
-            for (; i < length; i++) {
-                c = result[i];
-                if (c >= 'a' && c <= 'z') {
-                    result[i] -= ('a' - 'A');
-                }
-            }
-            return new String(result);
-        }
-        return s;
-    }
-
-    public static String toLowerCaseAscii(String s) {
-        for (int i = 0, length = s.length(); i < length; i++) {
-            char c = s.charAt(i);
-            if (c < 'A' || c > 'Z') {
-                continue; // fast path avoids allocation
-            }
-
-            // slow path: s contains upper case chars
-            char[] result = s.toCharArray();
-            for (; i < length; i++) {
-                c = result[i];
-                if (c >= 'A' && c <= 'Z') {
-                    result[i] += ('a' - 'A');
-                }
-            }
-            return new String(result);
-        }
-        return s;
-    }
-}
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/annotation/compat/UnsupportedAppUsage.java b/dalvik/src/main/java/dalvik/annotation/compat/UnsupportedAppUsage.java
new file mode 100644
index 0000000..82b2f10
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/compat/UnsupportedAppUsage.java
@@ -0,0 +1,138 @@
+/*
+ * 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.compat;
+
+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 static java.lang.annotation.RetentionPolicy.CLASS;
+
+import dalvik.system.VersionCodes;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import libcore.api.CorePlatformApi;
+import libcore.api.IntraCoreApi;
+
+/**
+ * Indicates that a class member, that is not part of the SDK, is used by apps.
+ * Since the member is not part of the SDK, such use is not supported.
+ *
+ * <p>This annotation acts as a heads up that changing a given method or field
+ * may affect apps, potentially breaking them when the next Android version is
+ * released. In some cases, for members that are heavily used, this annotation
+ * may imply restrictions on changes to the member.
+ *
+ * <p>This annotation also results in access to the member being permitted by the
+ * runtime, with a warning being generated in debug builds.
+ *
+ * <p>For more details, see go/UnsupportedAppUsage.
+ *
+ * {@hide}
+ */
+@Retention(CLASS)
+@Target({CONSTRUCTOR, METHOD, FIELD, TYPE})
+@Repeatable(UnsupportedAppUsage.Container.class)
+@CorePlatformApi
+@IntraCoreApi
+public @interface UnsupportedAppUsage {
+
+    /**
+     * Associates a bug tracking the work to add a public alternative to this API. Optional.
+     *
+     * @return ID of the associated tracking bug
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    long trackingBug() default 0;
+
+    /**
+     * Indicates that usage of this API is limited to apps based on their target SDK version.
+     *
+     * <p>Access to the API is allowed if the targetSdkVersion in the apps manifest is no greater
+     * than this value. Access checks are performed at runtime.
+     *
+     * <p>This is used to give app developers a grace period to migrate off a non-SDK interface.
+     * When making Android version N, existing APIs can have a maxTargetSdk of N-1 added to them.
+     * Developers must then migrate off the API when their app is updated in future, but it will
+     * continue working in the meantime.
+     *
+     * <p>Possible values are:
+     * <ul>
+     *     <li>
+     *         {@link VersionCodes#O} - in which case the API is available up to and including the
+     *         O release and all intermediate releases between O and P. Or in other words the API
+     *         is blacklisted (unavailable) from P onwards.
+     *     </li>
+     *     <li>
+     *         {@link VersionCodes#P} - in which case the API is available up to and including the
+     *         P release and all intermediate releases between P and Q. Or in other words the API
+     *         is blacklisted (unavailable) from Q onwards.
+     *     </li>
+     *     <li>
+     *         absent (default value) - All apps can access this API, but doing so may result in
+     *         warnings in the log, UI warnings (on developer builds) and/or strictmode violations.
+     *         The API is likely to be further restricted in future.
+     *     </li>
+     *
+     * </ul>
+     *
+     * @return The maximum value for an apps targetSdkVersion in order to access this API.
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    int maxTargetSdk() default Integer.MAX_VALUE;
+
+    /**
+     * For debug use only. The expected dex signature to be generated for this API, used to verify
+     * parts of the build process.
+     *
+     * @return A dex API signature.
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    String expectedSignature() default "";
+
+    /**
+     * The signature of an implicit (not present in the source) member that forms part of the
+     * hiddenapi.
+     *
+     * <p>Allows access to non-SDK API elements that are not represented in the input source to be
+     * managed.
+     *
+     * <p>This must only be used when applying the annotation to a type, using it in any other
+     * situation is an error.
+     *
+     * @return A dex API signature.
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    String implicitMember() default "";
+
+    /**
+     * Container for {@link UnsupportedAppUsage} that allows it to be applied repeatedly to types.
+     */
+    @Retention(CLASS)
+    @Target(TYPE)
+    @CorePlatformApi
+    @IntraCoreApi
+    @interface Container {
+        @CorePlatformApi
+        @IntraCoreApi
+        UnsupportedAppUsage[] value();
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java b/dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java
index 4564b18..c64aa5f 100644
--- a/dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java
+++ b/dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java
@@ -93,6 +93,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 @Retention(RetentionPolicy.CLASS)  // Save memory, don't instantiate as an object at runtime.
 @Target(ElementType.METHOD)
 public @interface CriticalNative {}
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/DeadReferenceSafe.java b/dalvik/src/main/java/dalvik/annotation/optimization/DeadReferenceSafe.java
new file mode 100644
index 0000000..50880c8
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/annotation/optimization/DeadReferenceSafe.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.annotation.optimization;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Allow the implementation to eliminate object references that are no longer needed, just as it
+ * would eliminate other dead variables.
+ *
+ * The annotation applies to methods of the annotated class, and to methods declared in any inner
+ * class declared inside the annotated class. It does not apply to methods declared in subclasses
+ * or superclasses. It is ignored for interfaces.
+ *
+ * The annotation promises that the implementation of this class remains correct if objects are
+ * finalized, and java.lang.ref References are enqueued, as soon as the JLS allows them to be,
+ * i.e. after they are allowed to be marked as unreachable according to the JLS. Historically, the
+ * Android runtime has garbage collected objects later than the JLS would allow, by retaining
+ * objects references that are no longer needed. Some classes that implement finalize() or make
+ * use of java.lang.ref APIs may have grown to depend on this historic Android runtime behavior.
+ *
+ * For example, consider the method
+ *
+ * <pre> {@code
+ *   void m() {
+ *     long tmpNativePtr = this.nativePtrField;
+ *     foo(tmpNativePtr);
+ *   }}</pre>
+ *
+ * where foo() accesses the memory M referenced by {@code this.nativePtrField}.  Once {@code
+ * tmpNativePtr} is computed, this object itself is no longer needed, and may be unreachable by JLS
+ * rules.  This may cause this object to be finalized, and M to be deleted, while {@code foo()} is
+ * still running and accessing M.
+ *
+ * Historically, ART has avoided this by keeping "this" reachable until {@code m()} completes.
+ * (Class file and dex level tools may not always do the same.) With this annotation, the Android
+ * runtime may no longer retain the "this" reference, again making the erroneous early
+ * finalization possible.
+ *
+ * The above example code could be made safe to annotate with {@code DeadReferenceSafe} by either
+ * adding Reference.reachabilityFence(this) to the end of {@code m()} and similar methods, or
+ * (Android-only) by declaring nativePtrField with a {@code @ReachabilitySensitive} annotation.
+ *
+ * The annotation will normally be safe for classes that do not use or rely on finalization-like
+ * cleanup mechanisms. It is unlikely to be safe for classes that use {@code java.lang.ref} or
+ * finalization but never mention {@code reachabilityFence()} or {@code @ReachabilitySensitive}.
+ *
+ * When it is safe, this annotation might result in better performance because more memory can be
+ * reclaimed earlier by the garbage collector.
+ *
+ * Since this is technically safe for all classes that follow Java language rules, we expect this
+ * to eventually become the default. This annotation allows us to selectively enable dead
+ * reference elimination during the transition, and while the details of {@code
+ * @ReachabilitySensitive} (like its name) are in flux.
+ *
+ * @hide
+ */
+@Retention(RetentionPolicy.RUNTIME)  // Let the GC or interpreter ask, if they need to.
+@Target({ElementType.TYPE})
+public @interface DeadReferenceSafe {}
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java b/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
index 605df4d..a5c0dc5 100644
--- a/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
+++ b/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
@@ -62,6 +62,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 @Retention(RetentionPolicy.CLASS)  // Save memory, don't instantiate as an object at runtime.
 @Target(ElementType.METHOD)
 public @interface FastNative {}
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java b/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java
index 35a6563..4eea1a5 100644
--- a/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java
+++ b/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java
@@ -80,6 +80,6 @@
  * @hide
  */
 @Retention(RetentionPolicy.RUNTIME)  // Let the GC or interpreter ask, if they need to.
-                                     // TODO: Reconsider later. b/72332040 .
+                                     // TODO(b/72332040): Reconsider retention later.
 @Target({ElementType.FIELD, ElementType.METHOD})
 public @interface ReachabilitySensitive {}
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index 2ff1814..9cf5f80 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -16,13 +16,17 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.File;
+import java.io.IOException;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
+import sun.misc.CompoundEnumeration;
 
 /**
  * Base class for common functionality between various dex-based
@@ -43,9 +47,24 @@
      */
     /* @NonNull */ private static volatile Reporter reporter = null;
 
+    @UnsupportedAppUsage
     private final DexPathList pathList;
 
     /**
+     * Array of ClassLoaders that can be used to load classes and resources that the code in
+     * {@code pathList} may depend on. This is used to implement Android's
+     * <a href=https://developer.android.com/guide/topics/manifest/uses-library-element>
+     * shared libraries</a> feature.
+     * <p>The shared library loaders are always checked before the {@code pathList} when looking
+     * up classes and resources.
+     *
+     * <p>{@code null} if the class loader has no shared library.
+     *
+     * @hide
+     */
+    protected final ClassLoader[] sharedLibraryLoaders;
+
+    /**
      * Constructs an instance.
      * Note that all the *.jar and *.apk files from {@code dexPath} might be
      * first extracted in-memory before the code is loaded. This can be avoided
@@ -62,15 +81,48 @@
      */
     public BaseDexClassLoader(String dexPath, File optimizedDirectory,
             String librarySearchPath, ClassLoader parent) {
-        this(dexPath, optimizedDirectory, librarySearchPath, parent, false);
+        this(dexPath, librarySearchPath, parent, null, false);
     }
 
     /**
      * @hide
      */
+    @UnsupportedAppUsage
     public BaseDexClassLoader(String dexPath, File optimizedDirectory,
             String librarySearchPath, ClassLoader parent, boolean isTrusted) {
+        this(dexPath, librarySearchPath, parent, null, isTrusted);
+    }
+
+    /**
+     * @hide
+     */
+    public BaseDexClassLoader(String dexPath,
+            String librarySearchPath, ClassLoader parent, ClassLoader[] libraries) {
+        this(dexPath, librarySearchPath, parent, libraries, false);
+    }
+
+    /**
+     * BaseDexClassLoader implements the Android
+     * <a href=https://developer.android.com/guide/topics/manifest/uses-library-element>
+     * shared libraries</a> feature by changing the typical parent delegation mechanism
+     * of class loaders.
+     * <p> Each shared library is associated with its own class loader, which is added to a list of
+     * class loaders this BaseDexClassLoader tries to load from in order, immediately checking
+     * after the parent.
+     * The shared library loaders are always checked before the {@code pathList} when looking
+     * up classes and resources.
+     *
+     * @hide
+     */
+    public BaseDexClassLoader(String dexPath,
+            String librarySearchPath, ClassLoader parent, ClassLoader[] sharedLibraryLoaders,
+            boolean isTrusted) {
         super(parent);
+        // Setup shared libraries before creating the path list. ART relies on the class loader
+        // hierarchy being finalized before loading dex files.
+        this.sharedLibraryLoaders = sharedLibraryLoaders == null
+                ? null
+                : Arrays.copyOf(sharedLibraryLoaders, sharedLibraryLoaders.length);
         this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);
 
         if (reporter != null) {
@@ -80,34 +132,30 @@
 
     /**
      * Reports the current class loader chain to the registered {@code reporter}.
-     * The chain is reported only if all its elements are {@code BaseDexClassLoader}.
      */
     private void reportClassLoaderChain() {
-        ArrayList<BaseDexClassLoader> classLoadersChain = new ArrayList<>();
+        ArrayList<ClassLoader> classLoadersChain = new ArrayList<>();
         ArrayList<String> classPaths = new ArrayList<>();
 
         classLoadersChain.add(this);
         classPaths.add(String.join(File.pathSeparator, pathList.getDexPaths()));
 
-        boolean onlySawSupportedClassLoaders = true;
         ClassLoader bootClassLoader = ClassLoader.getSystemClassLoader().getParent();
         ClassLoader current = getParent();
 
         while (current != null && current != bootClassLoader) {
+            classLoadersChain.add(current);
             if (current instanceof BaseDexClassLoader) {
                 BaseDexClassLoader bdcCurrent = (BaseDexClassLoader) current;
-                classLoadersChain.add(bdcCurrent);
                 classPaths.add(String.join(File.pathSeparator, bdcCurrent.pathList.getDexPaths()));
             } else {
-                onlySawSupportedClassLoaders = false;
-                break;
+                // We can't determine the classpath for arbitrary class loaders.
+                classPaths.add(null);
             }
             current = current.getParent();
         }
 
-        if (onlySawSupportedClassLoaders) {
-            reporter.report(classLoadersChain, classPaths);
-        }
+        reporter.report(classLoadersChain, classPaths);
     }
 
     /**
@@ -116,18 +164,32 @@
      * dexFile must be an in-memory representation of a full dexFile.
      *
      * @param dexFiles the array of in-memory dex files containing classes.
+     * @param librarySearchPath the list of directories containing native
+     *   libraries, delimited by {@code File.pathSeparator}; may be {@code null}
      * @param parent the parent class loader
      *
      * @hide
      */
-    public BaseDexClassLoader(ByteBuffer[] dexFiles, ClassLoader parent) {
-        // TODO We should support giving this a library search path maybe.
+    public BaseDexClassLoader(ByteBuffer[] dexFiles, String librarySearchPath, ClassLoader parent) {
         super(parent);
-        this.pathList = new DexPathList(this, dexFiles);
+        this.sharedLibraryLoaders = null;
+        this.pathList = new DexPathList(this, librarySearchPath);
+        this.pathList.initByteBufferDexPath(dexFiles);
     }
 
     @Override
     protected Class<?> findClass(String name) throws ClassNotFoundException {
+        // First, check whether the class is present in our shared libraries.
+        if (sharedLibraryLoaders != null) {
+            for (ClassLoader loader : sharedLibraryLoaders) {
+                try {
+                    return loader.loadClass(name);
+                } catch (ClassNotFoundException ignored) {
+                }
+            }
+        }
+        // Check whether the class in question is present in the dexPath that
+        // this classloader operates on.
         List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
         Class c = pathList.findClass(name, suppressedExceptions);
         if (c == null) {
@@ -144,6 +206,8 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public void addDexPath(String dexPath) {
         addDexPath(dexPath, false /*isTrusted*/);
     }
@@ -151,6 +215,7 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
     public void addDexPath(String dexPath, boolean isTrusted) {
         pathList.addDexPath(dexPath, null /*optimizedDirectory*/, isTrusted);
     }
@@ -160,18 +225,44 @@
      * {@link #findLibrary(String)}
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public void addNativePath(Collection<String> libPaths) {
         pathList.addNativePath(libPaths);
     }
 
     @Override
     protected URL findResource(String name) {
+        if (sharedLibraryLoaders != null) {
+            for (ClassLoader loader : sharedLibraryLoaders) {
+                URL url = loader.getResource(name);
+                if (url != null) {
+                    return url;
+                }
+            }
+        }
         return pathList.findResource(name);
     }
 
     @Override
     protected Enumeration<URL> findResources(String name) {
-        return pathList.findResources(name);
+        Enumeration<URL> myResources = pathList.findResources(name);
+        if (sharedLibraryLoaders == null) {
+          return myResources;
+        }
+
+        Enumeration<URL>[] tmp =
+            (Enumeration<URL>[]) new Enumeration<?>[sharedLibraryLoaders.length + 1];
+        // This will add duplicate resources if a shared library is loaded twice, but that's ok
+        // as we don't guarantee uniqueness.
+        for (int i = 0; i < sharedLibraryLoaders.length; i++) {
+            try {
+                tmp[i] = sharedLibraryLoaders[i].getResources(name);
+            } catch (IOException e) {
+                // Ignore.
+            }
+        }
+        tmp[sharedLibraryLoaders.length] = myResources;
+        return new CompoundEnumeration<>(tmp);
     }
 
     @Override
@@ -224,6 +315,8 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String getLdLibraryPath() {
         StringBuilder result = new StringBuilder();
         for (File directory : pathList.getNativeLibraryDirectories()) {
@@ -248,6 +341,7 @@
      * @param newReporter the new Reporter. Setting null will cancel reporting.
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static void setReporter(Reporter newReporter) {
         reporter = newReporter;
     }
@@ -262,11 +356,11 @@
     /**
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public interface Reporter {
         /**
          * Reports the construction of a BaseDexClassLoader and provides information about the
          * class loader chain.
-         * Note that this only reports if all class loader in the chain are BaseDexClassLoader.
          *
          * @param classLoadersChain the chain of class loaders used during the construction of the
          *     class loader. The first element is the BaseDexClassLoader being constructed,
@@ -274,8 +368,10 @@
          * @param classPaths the class paths of the class loaders present in
          *     {@param classLoadersChain}. The first element corresponds to the first class
          *     loader and so on. A classpath is represented as a list of dex files separated by
-         *     {@code File.pathSeparator}.
+         *     {@code File.pathSeparator}. If the class loader is not a BaseDexClassLoader the
+         *     classpath will be null.
          */
-        void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths);
+        @libcore.api.CorePlatformApi
+        void report(List<ClassLoader> classLoadersChain, List<String> classPaths);
     }
 }
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 6426bd8..c608407 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -16,79 +16,127 @@
 
 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 dalvik.annotation.compat.UnsupportedAppUsage;
+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
  */
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
 public final class BlockGuard {
 
     // 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}.
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public interface Policy {
         /**
          * Called on disk writes.
          */
+        @libcore.api.CorePlatformApi
         void onWriteToDisk();
 
         /**
          * Called on disk reads.
          */
+        @UnsupportedAppUsage
+        @libcore.api.CorePlatformApi
         void onReadFromDisk();
 
         /**
          * Called on network operations.
          */
+        @UnsupportedAppUsage
+        @libcore.api.IntraCoreApi
         void onNetwork();
 
         /**
          * Called on unbuffered input/ouput operations.
          */
+        @libcore.api.CorePlatformApi
         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
          * PENALTY_* constants.
          */
+        @libcore.api.CorePlatformApi
         int getPolicyMask();
     }
 
+    /**
+     * Per-process interface used to implement {@code StrictMode.VmPolicy}.
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    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.
+         */
+        @libcore.api.CorePlatformApi
+        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
+        @UnsupportedAppUsage
         private final int mPolicyState;
+        @UnsupportedAppUsage
         private final int mPolicyViolated;
+        @UnsupportedAppUsage
         private final String mMessage;   // may be null
 
         public BlockGuardPolicyException(int policyState, int policyViolated) {
             this(policyState, policyViolated, null);
         }
 
+        @UnsupportedAppUsage
         public BlockGuardPolicyException(int policyState, int policyViolated, String message) {
             mPolicyState = policyState;
             mPolicyViolated = policyViolated;
@@ -117,45 +165,93 @@
     }
 
     /**
-     * The default, permissive policy that doesn't prevent any operations.
+     * The default, permissive per-thread policy.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     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.
+     */
+    @libcore.api.CorePlatformApi
+    public static final VmPolicy LAX_VM_POLICY = new VmPolicy() {
+        @Override public String toString() { return "LAX_VM_POLICY"; }
+        @Override public void onPathAccess(String path) {}
+    };
+
+    @UnsupportedAppUsage
     private static ThreadLocal<Policy> threadPolicy = new ThreadLocal<Policy>() {
         @Override protected Policy initialValue() {
             return LAX_POLICY;
         }
     };
 
+    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() {
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
+    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);
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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.
+     */
+    @libcore.api.CorePlatformApi
+    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.
+     */
+    @libcore.api.CorePlatformApi
+    public static void setVmPolicy(@NonNull VmPolicy policy) {
+        vmPolicy = Objects.requireNonNull(policy);
     }
 
     private BlockGuard() {}
diff --git a/dalvik/src/main/java/dalvik/system/CloseGuard.java b/dalvik/src/main/java/dalvik/system/CloseGuard.java
index 072959b..6fe94a9 100644
--- a/dalvik/src/main/java/dalvik/system/CloseGuard.java
+++ b/dalvik/src/main/java/dalvik/system/CloseGuard.java
@@ -16,6 +16,8 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * CloseGuard is a mechanism for flagging implicit finalizer cleanup of
  * resources that should have been cleaned up by explicit close
@@ -108,6 +110,8 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
 public final class CloseGuard {
 
     /**
@@ -134,6 +138,9 @@
      * Returns a CloseGuard instance. {@code #open(String)} can be used to set
      * up the instance to warn on failure to close.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public static CloseGuard get() {
         return new CloseGuard();
     }
@@ -145,6 +152,8 @@
      * #getReporter() reporter} is informed of unclosed resources; otherwise a
      * one-line warning is logged.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void setEnabled(boolean enabled) {
         CloseGuard.stackAndTrackingEnabled = enabled;
     }
@@ -160,6 +169,8 @@
      * Used to replace default Reporter used to warn of CloseGuard
      * violations when stack tracking is enabled. Must be non-null.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void setReporter(Reporter rep) {
         if (rep == null) {
             throw new NullPointerException("reporter == null");
@@ -170,6 +181,7 @@
     /**
      * Returns non-null CloseGuard.Reporter.
      */
+    @libcore.api.CorePlatformApi
     public static Reporter getReporter() {
         return reporter;
     }
@@ -197,6 +209,7 @@
         return currentTracker;
     }
 
+    @UnsupportedAppUsage
     private CloseGuard() {}
 
     /**
@@ -207,6 +220,9 @@
      * @param closer non-null name of explicit termination method. Printed by warnIfOpen.
      * @throws NullPointerException if closer is null.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public void open(String closer) {
         // always perform the check for valid API usage...
         if (closer == null) {
@@ -235,6 +251,9 @@
      * Marks this CloseGuard instance as closed to avoid warnings on
      * finalization.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public void close() {
         Tracker tracker = currentTracker;
         if (tracker != null && closerNameOrAllocationInfo instanceof Throwable) {
@@ -251,6 +270,9 @@
      * the allocation to the current reporter. If it was not enabled, it just
      * directly logs a brief message.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public void warnIfOpen() {
         if (closerNameOrAllocationInfo != null) {
             if (closerNameOrAllocationInfo instanceof String) {
@@ -279,15 +301,22 @@
 
     /**
      * Interface to allow customization of reporting behavior.
+     * @hide
      */
+    @libcore.api.CorePlatformApi
     public interface Reporter {
-        void report (String message, Throwable allocationSite);
+        @UnsupportedAppUsage
+        @libcore.api.CorePlatformApi
+        void report(String message, Throwable allocationSite);
     }
 
     /**
      * Default Reporter which reports CloseGuard violations to the log.
      */
     private static final class DefaultReporter implements Reporter {
+        @UnsupportedAppUsage
+        private DefaultReporter() {}
+
         @Override public void report (String message, Throwable allocationSite) {
             System.logW(message, allocationSite);
         }
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java b/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
index a62ca3b..9d5eff1 100644
--- a/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
+++ b/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
@@ -29,6 +29,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public interface DalvikLogHandler {
 
     /**
@@ -41,7 +42,8 @@
      * @param tag the short (23 characters or fewer) logger tag identifying
      *      {@code logger}.
      */
+    @libcore.api.CorePlatformApi
     void publish(Logger source, String tag, Level level, String message);
 
     // TODO: support messages with throwables?
-}
\ No newline at end of file
+}
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogging.java b/dalvik/src/main/java/dalvik/system/DalvikLogging.java
index b5c7ad5..5c529a6 100644
--- a/dalvik/src/main/java/dalvik/system/DalvikLogging.java
+++ b/dalvik/src/main/java/dalvik/system/DalvikLogging.java
@@ -21,6 +21,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class DalvikLogging {
     private DalvikLogging() {}
 
@@ -29,6 +30,7 @@
      * Traditionally loggers are named by fully-qualified Java classes; this
      * method attempts to return a concise identifying part of such names.
      */
+    @libcore.api.CorePlatformApi
     public static String loggerNameToTag(String loggerName) {
         // Anonymous logger.
         if (loggerName == null) {
diff --git a/dalvik/src/main/java/dalvik/system/DelegateLastClassLoader.java b/dalvik/src/main/java/dalvik/system/DelegateLastClassLoader.java
index 4b29902..9481e3f 100644
--- a/dalvik/src/main/java/dalvik/system/DelegateLastClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DelegateLastClassLoader.java
@@ -22,6 +22,9 @@
 import java.net.URL;
 import java.util.Enumeration;
 
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
 /**
  * A {@code ClassLoader} implementation that implements a <b>delegate last</b> lookup policy.
  * For every class or resource this loader is requested to load, the following lookup order
@@ -37,11 +40,24 @@
 public final class DelegateLastClassLoader extends PathClassLoader {
 
     /**
-     * Equivalent to calling {@link #DelegateLastClassLoader(String, String, ClassLoader)}
-     * with {@code librarySearchPath = null}.
+     * Whether resource loading delegates to the parent class loader. True by default.
+     */
+    private final boolean delegateResourceLoading;
+
+    /**
+     * Equivalent to calling {@link #DelegateLastClassLoader(String, String, ClassLoader, boolean)}
+     * with {@code librarySearchPath = null, delegateResourceLoading = true}.
      */
     public DelegateLastClassLoader(String dexPath, ClassLoader parent) {
-        super(dexPath, parent);
+        this(dexPath, null, parent, true);
+    }
+
+    /**
+     * Equivalent to calling {@link #DelegateLastClassLoader(String, String, ClassLoader, boolean)}
+     * with {@code delegateResourceLoading = true}.
+     */
+    public DelegateLastClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
+        this(dexPath, librarySearchPath, parent, true);
     }
 
     /**
@@ -75,10 +91,28 @@
      *                {@code File.pathSeparator}, which defaults to {@code ":"} on Android.
      * @param librarySearchPath the list of directories containing native libraries, delimited
      *                          by {@code File.pathSeparator}; may be {@code null}.
-     * @param parent the parent class loader
+     * @param parent the parent class loader. May be {@code null} for the boot classloader.
+     * @param delegateResourceLoading whether to delegate resource loading to the parent if
+     *                                the resource is not found. This does not affect class
+     *                                loading delegation.
      */
-    public DelegateLastClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
+
+    public DelegateLastClassLoader(@NonNull String dexPath, @Nullable String librarySearchPath,
+            @Nullable ClassLoader parent, boolean delegateResourceLoading) {
         super(dexPath, librarySearchPath, parent);
+        this.delegateResourceLoading = delegateResourceLoading;
+    }
+
+    /**
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    public DelegateLastClassLoader(
+            String dexPath, String librarySearchPath, ClassLoader parent,
+            ClassLoader[] sharedLibraryLoaders) {
+        super(dexPath, librarySearchPath, parent, sharedLibraryLoaders);
+        // Delegating is the default behavior.
+        this.delegateResourceLoading = true;
     }
 
     @Override
@@ -97,7 +131,7 @@
         }
 
         // Next, check whether the class in question is present in the dexPath that this classloader
-        // operates on.
+        // operates on, or its shared libraries.
         ClassNotFoundException fromSuper = null;
         try {
             return findClass(name);
@@ -131,9 +165,11 @@
             return resource;
         }
 
-
-        final ClassLoader cl = getParent();
-        return (cl == null) ? null : cl.getResource(name);
+        if (delegateResourceLoading) {
+            final ClassLoader cl = getParent();
+            return (cl == null) ? null : cl.getResource(name);
+        }
+        return null;
     }
 
     @Override
@@ -142,7 +178,8 @@
         final Enumeration<URL>[] resources = (Enumeration<URL>[]) new Enumeration<?>[] {
                 Object.class.getClassLoader().getResources(name),
                 findResources(name),
-                (getParent() == null) ? null : getParent().getResources(name) };
+                (getParent() == null || !delegateResourceLoading)
+                        ? null : getParent().getResources(name) };
 
         return new CompoundEnumeration<>(resources);
     }
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index afedba5..486ee90 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -17,6 +17,7 @@
 package dalvik.system;
 
 import android.system.ErrnoException;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.ReachabilitySensitive;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -37,16 +38,20 @@
  *     as {@link dalvik.system.PathClassLoader} instead. <b>This API will be removed
  *     in a future Android release</b>.
  */
+@libcore.api.CorePlatformApi
 @Deprecated
 public final class DexFile {
   /**
    * If close is called, mCookie becomes null but the internal cookie is preserved if the close
    * failed so that we can free resources in the finalizer.
    */
+    @UnsupportedAppUsage
     @ReachabilitySensitive
     private Object mCookie;
 
+    @UnsupportedAppUsage
     private Object mInternalCookie;
+    @UnsupportedAppUsage
     private final String mFileName;
 
     /**
@@ -97,15 +102,17 @@
      * @param elements
      *            the temporary dex path list elements from DexPathList.makeElements
      */
-    DexFile(String fileName, ClassLoader loader, DexPathList.Element[] elements) throws IOException {
+    DexFile(String fileName, ClassLoader loader, DexPathList.Element[] elements)
+            throws IOException {
         mCookie = openDexFile(fileName, null, 0, loader, elements);
         mInternalCookie = mCookie;
         mFileName = fileName;
         //System.out.println("DEX FILE cookie is " + mCookie + " fileName=" + fileName);
     }
 
-    DexFile(ByteBuffer buf) throws IOException {
-        mCookie = openInMemoryDexFile(buf);
+    DexFile(ByteBuffer[] bufs, ClassLoader loader, DexPathList.Element[] elements)
+            throws IOException {
+        mCookie = openInMemoryDexFiles(bufs, loader, elements);
         mInternalCookie = mCookie;
         mFileName = null;
     }
@@ -189,6 +196,7 @@
      * @throws IOException
      *  If unable to open the source or output file.
      */
+    @UnsupportedAppUsage
     static DexFile loadDex(String sourcePathName, String outputPathName,
         int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException {
 
@@ -272,6 +280,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed) {
         return defineClass(name, loader, mCookie, this, suppressed);
     }
@@ -308,6 +317,7 @@
      */
     private static class DFEnum implements Enumeration<String> {
         private int mIndex;
+        @UnsupportedAppUsage
         private String[] mNameList;
 
         DFEnum(DexFile df) {
@@ -348,6 +358,7 @@
      * Open a DEX file.  The value returned is a magic VM cookie.  On
      * failure, an IOException is thrown.
      */
+    @UnsupportedAppUsage
     private static Object openDexFile(String sourceName, String outputName, int flags,
             ClassLoader loader, DexPathList.Element[] elements) throws IOException {
         // Use absolute paths to enable the use of relative paths when testing on host.
@@ -360,20 +371,45 @@
                                  elements);
     }
 
-    private static Object openInMemoryDexFile(ByteBuffer buf) throws IOException {
-        if (buf.isDirect()) {
-            return createCookieWithDirectBuffer(buf, buf.position(), buf.limit());
-        } else {
-            return createCookieWithArray(buf.array(), buf.position(), buf.limit());
+    private static Object openInMemoryDexFiles(ByteBuffer[] bufs, ClassLoader loader,
+            DexPathList.Element[] elements) throws IOException {
+        // Preprocess the ByteBuffers for openInMemoryDexFilesNative. We extract
+        // the backing array (non-direct buffers only) and start/end positions
+        // so that the native method does not have to call Java methods anymore.
+        byte[][] arrays = new byte[bufs.length][];
+        int[] starts = new int[bufs.length];
+        int[] ends = new int[bufs.length];
+        for (int i = 0; i < bufs.length; ++i) {
+            arrays[i] = bufs[i].isDirect() ? null : bufs[i].array();
+            starts[i] = bufs[i].position();
+            ends[i] = bufs[i].limit();
         }
+        return openInMemoryDexFilesNative(bufs, arrays, starts, ends, loader, elements);
     }
 
-    private static native Object createCookieWithDirectBuffer(ByteBuffer buf, int start, int end);
-    private static native Object createCookieWithArray(byte[] buf, int start, int end);
+    private static native Object openInMemoryDexFilesNative(ByteBuffer[] bufs, byte[][] arrays,
+            int[] starts, int[] ends, ClassLoader loader, DexPathList.Element[] elements);
+
+    /*
+     * Initiates background verification of this DexFile. This is a sepearate down-call
+     * from openDexFile and openInMemoryDexFiles because it requires the class loader's
+     * DexPathList to have been initialized for its classes to be resolvable by ART.
+     * DexPathList will open the dex files first, finalize `dexElements` and then call this.
+     */
+    /*package*/ void verifyInBackground(ClassLoader classLoader, String classLoaderContext) {
+        verifyInBackgroundNative(mCookie, classLoader, classLoaderContext);
+    }
+
+    private static native void verifyInBackgroundNative(Object mCookie, ClassLoader classLoader,
+            String classLoaderContext);
+
+    /*package*/ static native String getClassLoaderContext(ClassLoader classLoader,
+            DexPathList.Element[] elements);
 
     /*
      * Returns true if the dex file is backed by a valid oat file.
      */
+    @UnsupportedAppUsage
     /*package*/ boolean isBackedByOatFile() {
         return isBackedByOatFile(mCookie);
     }
@@ -392,6 +428,7 @@
     private static native Class defineClassNative(String name, ClassLoader loader, Object cookie,
                                                   DexFile dexFile)
             throws ClassNotFoundException, NoClassDefFoundError;
+    @UnsupportedAppUsage
     private static native String[] getClassNameList(Object cookie);
     private static native boolean isBackedByOatFile(Object cookie);
     private static native void setTrusted(Object cookie);
@@ -399,6 +436,7 @@
      * Open a DEX file.  The value returned is a magic VM cookie.  On
      * failure, an IOException is thrown.
      */
+    @UnsupportedAppUsage
     private static native Object openDexFileNative(String sourceName, String outputName, int flags,
             ClassLoader loader, DexPathList.Element[] elements);
 
@@ -424,6 +462,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static final int NO_DEXOPT_NEEDED = 0;
 
     /**
@@ -453,18 +492,9 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     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)}
@@ -508,6 +538,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static native int getDexOptNeeded(String fileName,
             String instructionSet, String compilerFilter, String classLoaderContext,
             boolean newProfile, boolean downgrade)
@@ -532,6 +563,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static final class OptimizationInfo {
         // The optimization status.
         private final String status;
@@ -544,10 +576,12 @@
             this.reason = reason;
         }
 
+        @libcore.api.CorePlatformApi
         public String getStatus() {
             return status;
         }
 
+        @libcore.api.CorePlatformApi
         public String getReason() {
             return reason;
         }
@@ -558,6 +592,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static OptimizationInfo getDexFileOptimizationInfo(
             String fileName, String instructionSet) throws FileNotFoundException {
         String[] status = getDexFileOptimizationStatus(fileName, instructionSet);
@@ -584,6 +619,7 @@
      * If no optimized code exists the method returns null.
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static native String[] getDexFileOutputPaths(String fileName, String instructionSet)
         throws FileNotFoundException;
 
@@ -592,6 +628,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public native static boolean isValidCompilerFilter(String filter);
 
     /**
@@ -599,6 +636,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public native static boolean isProfileGuidedCompilerFilter(String filter);
 
     /**
@@ -617,6 +655,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public native static String getSafeModeCompilerFilter(String filter);
 
     /**
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index e68e365..c63bb13 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -18,6 +18,7 @@
 
 import android.system.ErrnoException;
 import android.system.StructStat;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -48,12 +49,15 @@
  *
  * <p>This class also contains methods to use these lists to look up
  * classes and resources.</p>
+ *
+ * @hide
  */
-/*package*/ final class DexPathList {
+public final class DexPathList {
     private static final String DEX_SUFFIX = ".dex";
     private static final String zipSeparator = "!/";
 
     /** class definition context */
+    @UnsupportedAppUsage
     private final ClassLoader definingContext;
 
     /**
@@ -61,23 +65,34 @@
      * Should be called pathElements, but the Facebook app uses reflection
      * to modify 'dexElements' (http://b/7726934).
      */
+    @UnsupportedAppUsage
     private Element[] dexElements;
 
     /** List of native library path elements. */
     // Some applications rely on this field being an array or we'd use a final list here
+    @UnsupportedAppUsage
     /* package visible for testing */ NativeLibraryElement[] nativeLibraryPathElements;
 
     /** List of application native library directories. */
+    @UnsupportedAppUsage
     private final List<File> nativeLibraryDirectories;
 
     /** List of system native library directories. */
+    @UnsupportedAppUsage
     private final List<File> systemNativeLibraryDirectories;
 
     /**
      * Exceptions thrown during creation of the dexElements list.
      */
+    @UnsupportedAppUsage
     private IOException[] dexElementsSuppressedExceptions;
 
+    private List<File> getAllNativeLibraryDirectories() {
+        List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories);
+        allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories);
+        return allNativeLibraryDirectories;
+    }
+
     /**
      * Construct an instance.
      *
@@ -86,32 +101,16 @@
      *
      * @param dexFiles the bytebuffers containing the dex files that we should load classes from.
      */
-    public DexPathList(ClassLoader definingContext, ByteBuffer[] dexFiles) {
+    public DexPathList(ClassLoader definingContext, String librarySearchPath) {
         if (definingContext == null) {
             throw new NullPointerException("definingContext == null");
         }
-        if (dexFiles == null) {
-            throw new NullPointerException("dexFiles == null");
-        }
-        if (Arrays.stream(dexFiles).anyMatch(v -> v == null)) {
-            throw new NullPointerException("dexFiles contains a null Buffer!");
-        }
 
         this.definingContext = definingContext;
-        // TODO It might be useful to let in-memory dex-paths have native libraries.
-        this.nativeLibraryDirectories = Collections.emptyList();
+        this.nativeLibraryDirectories = splitPaths(librarySearchPath, false);
         this.systemNativeLibraryDirectories =
                 splitPaths(System.getProperty("java.library.path"), true);
-        this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
-
-        ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();
-        this.dexElements = makeInMemoryDexElements(dexFiles, suppressedExceptions);
-        if (suppressedExceptions.size() > 0) {
-            this.dexElementsSuppressedExceptions =
-                    suppressedExceptions.toArray(new IOException[suppressedExceptions.size()]);
-        } else {
-            dexElementsSuppressedExceptions = null;
-        }
+        this.nativeLibraryPathElements = makePathElements(getAllNativeLibraryDirectories());
     }
 
     /**
@@ -127,6 +126,7 @@
      * should be found and written to, or {@code null} to use the default
      * system directory for same
      */
+    @UnsupportedAppUsage
     public DexPathList(ClassLoader definingContext, String dexPath,
             String librarySearchPath, File optimizedDirectory) {
         this(definingContext, dexPath, librarySearchPath, optimizedDirectory, false);
@@ -177,10 +177,7 @@
         this.nativeLibraryDirectories = splitPaths(librarySearchPath, false);
         this.systemNativeLibraryDirectories =
                 splitPaths(System.getProperty("java.library.path"), true);
-        List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories);
-        allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories);
-
-        this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories);
+        this.nativeLibraryPathElements = makePathElements(getAllNativeLibraryDirectories());
 
         if (suppressedExceptions.size() > 0) {
             this.dexElementsSuppressedExceptions =
@@ -191,15 +188,9 @@
     }
 
     @Override public String toString() {
-        List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories);
-        allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories);
-
-        File[] nativeLibraryDirectoriesArray =
-                allNativeLibraryDirectories.toArray(
-                    new File[allNativeLibraryDirectories.size()]);
-
         return "DexPathList[" + Arrays.toString(dexElements) +
-            ",nativeLibraryDirectories=" + Arrays.toString(nativeLibraryDirectoriesArray) + "]";
+            ",nativeLibraryDirectories=" +
+            Arrays.toString(getAllNativeLibraryDirectories().toArray()) + "]";
     }
 
     /**
@@ -217,6 +208,7 @@
      * should be found and written to, or {@code null} to use the default
      * system directory for same
      */
+    @UnsupportedAppUsage
     public void addDexPath(String dexPath, File optimizedDirectory) {
       addDexPath(dexPath, optimizedDirectory, false);
     }
@@ -254,6 +246,57 @@
     }
 
     /**
+     * For InMemoryDexClassLoader. Initializes {@code dexElements} with dex files
+     * loaded from {@code dexFiles} buffers.
+     *
+     * @param dexFiles ByteBuffers containing raw dex data. Apks are not supported.
+     */
+    /* package */ void initByteBufferDexPath(ByteBuffer[] dexFiles) {
+        if (dexFiles == null) {
+            throw new NullPointerException("dexFiles == null");
+        }
+        if (Arrays.stream(dexFiles).anyMatch(v -> v == null)) {
+            throw new NullPointerException("dexFiles contains a null Buffer!");
+        }
+        if (dexElements != null || dexElementsSuppressedExceptions != null) {
+            throw new IllegalStateException("Should only be called once");
+        }
+
+        final List<IOException> suppressedExceptions = new ArrayList<IOException>();
+
+        try {
+            Element[] null_elements = null;
+            DexFile dex = new DexFile(dexFiles, definingContext, null_elements);
+            // Capture class loader context from *before* `dexElements` is set (see comment below).
+            String classLoaderContext = dex.isBackedByOatFile()
+                    ? null : DexFile.getClassLoaderContext(definingContext, null_elements);
+            dexElements = new Element[] { new Element(dex) };
+            // Spawn background thread to verify all classes and cache verification results.
+            // Must be called *after* `dexElements` has been initialized for ART to find
+            // its classes (the field is hardcoded in ART and dex files iterated over in
+            // the order of the array), but with class loader context from *before*
+            // `dexElements` was set because that is what it will be compared against next
+            // time the same bytecode is loaded.
+            // We only spawn the background thread if the bytecode is not backed by an oat
+            // file, i.e. this is the first time this bytecode is being loaded and/or
+            // verification results have not been cached yet. Skip spawning the thread on
+            // all subsequent loads of the same bytecode in the same class loader context.
+            if (classLoaderContext != null) {
+                dex.verifyInBackground(definingContext, classLoaderContext);
+            }
+        } catch (IOException suppressed) {
+            System.logE("Unable to load dex files", suppressed);
+            suppressedExceptions.add(suppressed);
+            dexElements = new Element[0];
+        }
+
+        if (suppressedExceptions.size() > 0) {
+            dexElementsSuppressedExceptions = suppressedExceptions.toArray(
+                    new IOException[suppressedExceptions.size()]);
+        }
+    }
+
+    /**
      * Splits the given dex path string into elements using the path
      * separator, pruning out any elements that do not refer to existing
      * and readable files.
@@ -271,6 +314,7 @@
      * are empty or {@code null}, or all elements get pruned out, then
      * this returns a zero-element list.
      */
+    @UnsupportedAppUsage
     private static List<File> splitPaths(String searchPath, boolean directoriesOnly) {
         List<File> result = new ArrayList<>();
 
@@ -293,13 +337,17 @@
         return result;
     }
 
-    private static Element[] makeInMemoryDexElements(ByteBuffer[] dexFiles,
+    // This method is not used anymore. Kept around only because there are many legacy users of it.
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage
+    public static Element[] makeInMemoryDexElements(ByteBuffer[] dexFiles,
             List<IOException> suppressedExceptions) {
         Element[] elements = new Element[dexFiles.length];
         int elementPos = 0;
         for (ByteBuffer buf : dexFiles) {
             try {
-                DexFile dex = new DexFile(buf);
+                DexFile dex = new DexFile(new ByteBuffer[] { buf }, /* classLoader */ null,
+                        /* dexElements */ null);
                 elements[elementPos++] = new Element(dex);
             } catch (IOException suppressed) {
                 System.logE("Unable to load dex file: " + buf, suppressed);
@@ -316,6 +364,7 @@
      * Makes an array of dex/resource path elements, one per element of
      * the given array.
      */
+    @UnsupportedAppUsage
     private static Element[] makeDexElements(List<File> files, File optimizedDirectory,
             List<IOException> suppressedExceptions, ClassLoader loader) {
         return makeDexElements(files, optimizedDirectory, suppressedExceptions, loader, false);
@@ -387,6 +436,7 @@
      * {@code optimizedDirectory} is {@code null}. An application image file may be associated with
      * the {@code loader} if it is not null.
      */
+    @UnsupportedAppUsage
     private static DexFile loadDexFile(File file, File optimizedDirectory, ClassLoader loader,
                                        Element[] elements)
             throws IOException {
@@ -437,6 +487,7 @@
      * TODO (dimitry): Revert after apps stops relying on the existence of this
      * method (see http://b/21957414 and http://b/26317852 for details)
      */
+    @UnsupportedAppUsage
     @SuppressWarnings("unused")
     private static Element[] makePathElements(List<File> files, File optimizedDirectory,
             List<IOException> suppressedExceptions) {
@@ -447,6 +498,7 @@
      * Makes an array of directory/zip path elements for the native library search path, one per
      * element of the given array.
      */
+    @UnsupportedAppUsage
     private static NativeLibraryElement[] makePathElements(List<File> files) {
         NativeLibraryElement[] elements = new NativeLibraryElement[files.size()];
         int elementsPos = 0;
@@ -580,6 +632,7 @@
      * Note: This method will attempt to dedupe elements.
      * Note: This method replaces the value of {@link #nativeLibraryPathElements}
      */
+    @UnsupportedAppUsage
     public void addNativePath(Collection<String> libPaths) {
         if (libPaths.isEmpty()) {
             return;
@@ -608,8 +661,12 @@
          * A file denoting a zip file (in case of a resource jar or a dex jar), or a directory
          * (only when dexFile is null).
          */
+        @UnsupportedAppUsage
         private final File path;
+        /** Whether {@code path.isDirectory()}, or {@code null} if {@code path == null}. */
+        private final Boolean pathIsDirectory;
 
+        @UnsupportedAppUsage
         private final DexFile dexFile;
 
         private ClassPathURLStreamHandler urlHandler;
@@ -619,19 +676,23 @@
          * Element encapsulates a dex file. This may be a plain dex file (in which case dexZipPath
          * should be null), or a jar (in which case dexZipPath should denote the zip file).
          */
+        @UnsupportedAppUsage
         public Element(DexFile dexFile, File dexZipPath) {
+            if (dexFile == null && dexZipPath == null) {
+                throw new NullPointerException("Either dexFile or path must be non-null");
+            }
             this.dexFile = dexFile;
             this.path = dexZipPath;
+            // Do any I/O in the constructor so we don't have to do it elsewhere, eg. toString().
+            this.pathIsDirectory = (path == null) ? null : path.isDirectory();
         }
 
         public Element(DexFile dexFile) {
-            this.dexFile = dexFile;
-            this.path = null;
+            this(dexFile, null);
         }
 
         public Element(File path) {
-          this.path = path;
-          this.dexFile = null;
+            this(null, path);
         }
 
         /**
@@ -642,8 +703,10 @@
          *             classes and resources, and NativeLibraryElement for the library
          *             search path.
          */
+        @UnsupportedAppUsage
         @Deprecated
         public Element(File dir, boolean isDirectory, File zip, DexFile dexFile) {
+            this(dir != null ? null : dexFile, dir != null ? dir : zip);
             System.err.println("Warning: Using deprecated Element constructor. Do not use internal"
                     + " APIs, this constructor will be removed in the future.");
             if (dir != null && (zip != null || dexFile != null)) {
@@ -653,13 +716,6 @@
             if (isDirectory && (zip != null || dexFile != null)) {
                 throw new IllegalArgumentException("Unsupported argument combination.");
             }
-            if (dir != null) {
-                this.path = dir;
-                this.dexFile = null;
-            } else {
-                this.path = zip;
-                this.dexFile = dexFile;
-            }
         }
 
         /*
@@ -678,13 +734,11 @@
         @Override
         public String toString() {
             if (dexFile == null) {
-              return (path.isDirectory() ? "directory \"" : "zip file \"") + path + "\"";
+              return (pathIsDirectory ? "directory \"" : "zip file \"") + path + "\"";
+            } else if (path == null) {
+              return "dex file \"" + dexFile + "\"";
             } else {
-              if (path == null) {
-                return "dex file \"" + dexFile + "\"";
-              } else {
-                return "zip file \"" + path + "\"";
-              }
+              return "zip file \"" + path + "\"";
             }
         }
 
@@ -693,7 +747,7 @@
                 return;
             }
 
-            if (path == null || path.isDirectory()) {
+            if (path == null || pathIsDirectory) {
                 initialized = true;
                 return;
             }
@@ -756,6 +810,7 @@
         /**
          * A file denoting a directory or zip file.
          */
+        @UnsupportedAppUsage
         private final File path;
 
         /**
@@ -766,6 +821,7 @@
         private ClassPathURLStreamHandler urlHandler;
         private boolean initialized;
 
+        @UnsupportedAppUsage
         public NativeLibraryElement(File dir) {
             this.path = dir;
             this.zipDir = null;
diff --git a/dalvik/src/main/java/dalvik/system/InMemoryDexClassLoader.java b/dalvik/src/main/java/dalvik/system/InMemoryDexClassLoader.java
index 0603260..d57e2d7 100644
--- a/dalvik/src/main/java/dalvik/system/InMemoryDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/InMemoryDexClassLoader.java
@@ -16,6 +16,8 @@
 
 package dalvik.system;
 
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 import java.nio.ByteBuffer;
 
 /**
@@ -29,10 +31,25 @@
      *
      * @param dexBuffers array of buffers containing DEX files between
      *                       <tt>buffer.position()</tt> and <tt>buffer.limit()</tt>.
+     * @param librarySearchPath the list of directories containing native
+     *   libraries, delimited by {@code File.pathSeparator}; may be {@code null}
      * @param parent the parent class loader for delegation.
      */
-    public InMemoryDexClassLoader(ByteBuffer[] dexBuffers, ClassLoader parent) {
-        super(dexBuffers, parent);
+    public InMemoryDexClassLoader(@NonNull ByteBuffer @NonNull [] dexBuffers,
+            @Nullable String librarySearchPath, @Nullable ClassLoader parent) {
+        super(dexBuffers, librarySearchPath, parent);
+    }
+
+    /**
+     * Create an in-memory DEX class loader with the given dex buffers.
+     *
+     * @param dexBuffers array of buffers containing DEX files between
+     *                       <tt>buffer.position()</tt> and <tt>buffer.limit()</tt>.
+     * @param parent the parent class loader for delegation.
+     */
+    public InMemoryDexClassLoader(@NonNull ByteBuffer @NonNull [] dexBuffers,
+            @Nullable ClassLoader parent) {
+        this(dexBuffers, null, parent);
     }
 
     /**
@@ -42,7 +59,7 @@
      *                       <tt>buffer.position()</tt> and <tt>buffer.limit()</tt>.
      * @param parent the parent class loader for delegation.
      */
-    public InMemoryDexClassLoader(ByteBuffer dexBuffer, ClassLoader parent) {
+    public InMemoryDexClassLoader(@NonNull ByteBuffer dexBuffer, @Nullable ClassLoader parent) {
         this(new ByteBuffer[] { dexBuffer }, parent);
     }
 }
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 382d361..cbd494f 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -63,4 +63,14 @@
     public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
         super(dexPath, null, librarySearchPath, parent);
     }
+
+    /**
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    public PathClassLoader(
+            String dexPath, String librarySearchPath, ClassLoader parent,
+            ClassLoader[] sharedLibraryLoaders) {
+        super(dexPath, librarySearchPath, parent, sharedLibraryLoaders);
+    }
 }
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..320ea28
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
@@ -0,0 +1,80 @@
+/*
+ * 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
+ */
+@libcore.api.CorePlatformApi
+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.
+     */
+    @libcore.api.CorePlatformApi
+    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)}.
+     */
+    @libcore.api.CorePlatformApi
+    public static void setUncaughtExceptionPreHandler(
+            Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
+        Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/SocketTagger.java b/dalvik/src/main/java/dalvik/system/SocketTagger.java
index 97059a4..54ede15 100644
--- a/dalvik/src/main/java/dalvik/system/SocketTagger.java
+++ b/dalvik/src/main/java/dalvik/system/SocketTagger.java
@@ -16,6 +16,7 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 import java.net.DatagramSocket;
 import java.net.Socket;
@@ -26,6 +27,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public abstract class SocketTagger {
 
     private static SocketTagger tagger = new SocketTagger() {
@@ -33,11 +35,16 @@
         @Override public void untag(FileDescriptor socketDescriptor) throws SocketException {}
     };
 
+    @libcore.api.CorePlatformApi
+    public SocketTagger() {
+    }
+
     /**
      * Notified when {@code socketDescriptor} is either assigned to the current
      * thread. The socket is either newly connected or reused from a connection
      * pool. Implementations of this method should be thread-safe.
      */
+    @libcore.api.CorePlatformApi
     public abstract void tag(FileDescriptor socketDescriptor) throws SocketException;
 
     /**
@@ -48,26 +55,33 @@
      * <p><strong>Note:</strong> this method will not be invoked when the socket
      * is closed.
      */
+    @libcore.api.CorePlatformApi
     public abstract void untag(FileDescriptor socketDescriptor) throws SocketException;
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public final void tag(Socket socket) throws SocketException {
         if (!socket.isClosed()) {
             tag(socket.getFileDescriptor$());
         }
     }
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public final void untag(Socket socket) throws SocketException {
         if (!socket.isClosed()) {
             untag(socket.getFileDescriptor$());
         }
     }
 
+    @libcore.api.CorePlatformApi
     public final void tag(DatagramSocket socket) throws SocketException {
         if (!socket.isClosed()) {
             tag(socket.getFileDescriptor$());
         }
     }
 
+    @libcore.api.CorePlatformApi
     public final void untag(DatagramSocket socket) throws SocketException {
         if (!socket.isClosed()) {
             untag(socket.getFileDescriptor$());
@@ -77,6 +91,7 @@
     /**
      * Sets this process' socket tagger to {@code tagger}.
      */
+    @libcore.api.CorePlatformApi
     public static synchronized void set(SocketTagger tagger) {
         if (tagger == null) {
             throw new NullPointerException("tagger == null");
@@ -87,6 +102,8 @@
     /**
      * Returns this process socket tagger.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static synchronized SocketTagger get() {
         return tagger;
     }
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 7c03ed6..2a0e4ef 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -16,6 +16,7 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -31,11 +32,13 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class VMDebug {
     /**
      * flag for startMethodTracing(), which adds the results from
      * startAllocCounting to the trace key file.
      */
+    @libcore.api.CorePlatformApi
     public static final int TRACE_COUNT_ALLOCS = 1;
 
     /* constants for getAllocCount */
@@ -51,18 +54,25 @@
     private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
     private static final int KIND_EXT_FREED_BYTES       = 1<<15;
 
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
         KIND_ALLOCATED_OBJECTS;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_ALLOCATED_BYTES =
         KIND_ALLOCATED_BYTES;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_FREED_OBJECTS =
         KIND_FREED_OBJECTS;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_FREED_BYTES =
         KIND_FREED_BYTES;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_GC_INVOCATIONS =
         KIND_GC_INVOCATIONS;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
         KIND_CLASS_INIT_COUNT;
+    @libcore.api.CorePlatformApi
     public static final int KIND_GLOBAL_CLASS_INIT_TIME =
         KIND_CLASS_INIT_TIME;
     public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS =
@@ -74,14 +84,17 @@
     public static final int KIND_GLOBAL_EXT_FREED_BYTES =
         KIND_EXT_FREED_BYTES;
 
+    @libcore.api.CorePlatformApi
     public static final int KIND_THREAD_ALLOCATED_OBJECTS =
         KIND_ALLOCATED_OBJECTS << 16;
+    @libcore.api.CorePlatformApi
     public static final int KIND_THREAD_ALLOCATED_BYTES =
         KIND_ALLOCATED_BYTES << 16;
     public static final int KIND_THREAD_FREED_OBJECTS =
         KIND_FREED_OBJECTS << 16;
     public static final int KIND_THREAD_FREED_BYTES =
         KIND_FREED_BYTES << 16;
+    @libcore.api.CorePlatformApi
     public static final int KIND_THREAD_GC_INVOCATIONS =
         KIND_GC_INVOCATIONS << 16;
     public static final int KIND_THREAD_CLASS_INIT_COUNT =
@@ -97,6 +110,7 @@
     public static final int KIND_THREAD_EXT_FREED_BYTES =
         KIND_EXT_FREED_BYTES << 16;
 
+    @libcore.api.CorePlatformApi
     public static final int KIND_ALL_COUNTS = 0xffffffff;
 
     /* all methods are static */
@@ -107,6 +121,7 @@
      *
      * @return the time in milliseconds, or -1 if the debugger is not connected
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native long lastDebuggerActivity();
 
@@ -116,6 +131,7 @@
      *
      * @return true if debugging is enabled
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native boolean isDebuggingEnabled();
 
@@ -124,6 +140,8 @@
      *
      * @return true if (and only if) a debugger is connected
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native boolean isDebuggerConnected();
 
@@ -132,6 +150,7 @@
      * used by DDMS to determine what sorts of operations the VM can
      * perform.
      */
+    @libcore.api.CorePlatformApi
     public static native String[] getVmFeatureList();
 
     /**
@@ -167,6 +186,7 @@
      * @param intervalUs the time between samples in microseconds when
      * sampling is enabled.
      */
+    @libcore.api.CorePlatformApi
     public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
         startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
     }
@@ -188,6 +208,7 @@
      * supplied simply for logging.  Makes a dup of the file descriptor.
      * Streams tracing data to the file if streamingOutput is true.
      */
+    @libcore.api.CorePlatformApi
     public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize,
                                           int flags, boolean samplingEnabled, int intervalUs,
                                           boolean streamingOutput) {
@@ -203,6 +224,7 @@
      * is called, the result is sent directly to DDMS.  (If DDMS is not
      * attached when tracing ends, the profiling data will be discarded.)
      */
+    @libcore.api.CorePlatformApi
     public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
         startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
     }
@@ -227,21 +249,25 @@
      * Determine whether method tracing is currently active and what type is
      * active.
      */
+    @libcore.api.CorePlatformApi
     public static native int getMethodTracingMode();
 
     /**
      * Stops method tracing.
      */
+    @libcore.api.CorePlatformApi
     public static native void stopMethodTracing();
 
     /**
      * Starts sending Dalvik method trace info to the emulator.
      */
+    @libcore.api.CorePlatformApi
     public static native void startEmulatorTracing();
 
     /**
      * Stops sending Dalvik method trace info to the emulator.
      */
+    @libcore.api.CorePlatformApi
     public static native void stopEmulatorTracing();
 
     /**
@@ -256,6 +282,7 @@
      * @return the CPU usage. A value of -1 means the system does not support
      *         this feature.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native long threadCpuTimeNanos();
 
@@ -263,9 +290,13 @@
      * Count the number and aggregate size of memory allocations between
      * two points.
      */
+    @libcore.api.CorePlatformApi
     public static native void startAllocCounting();
+    @libcore.api.CorePlatformApi
     public static native void stopAllocCounting();
+    @libcore.api.CorePlatformApi
     public static native int getAllocCount(int kind);
+    @libcore.api.CorePlatformApi
     public static native void resetAllocCount(int kinds);
 
     /**
@@ -297,6 +328,7 @@
     /**
      * Dumps a list of loaded class to the log file.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native void printLoadedClasses(int flags);
 
@@ -305,6 +337,7 @@
      *
      * @return the number of loaded classes
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native int getLoadedClassCount();
 
@@ -318,6 +351,7 @@
      *         HPROF support.
      * @throws IOException if an error occurs while opening or writing files.
      */
+    @libcore.api.CorePlatformApi
     public static void dumpHprofData(String filename) throws IOException {
         if (filename == null) {
             throw new NullPointerException("filename == null");
@@ -331,6 +365,7 @@
      * @throws UnsupportedOperationException if the VM was built without
      *         HPROF support.
      */
+    @libcore.api.CorePlatformApi
     public static native void dumpHprofDataDdms();
 
     /**
@@ -341,6 +376,7 @@
      * @param fd Descriptor of open file that will receive the output.
      *        If this is null, the fileName is used instead.
      */
+    @libcore.api.CorePlatformApi
     public static void dumpHprofData(String fileName, FileDescriptor fd)
             throws IOException {
        dumpHprofData(fileName, fd != null ? fd.getInt$() : -1);
@@ -352,12 +388,15 @@
     /**
      * Primes the register map cache.
      */
+    @libcore.api.CorePlatformApi
     public static native boolean cacheRegisterMap(String classAndMethodDesc);
 
     /**
      * Dumps the contents of the VM reference tables (e.g. JNI locals and
      * globals) to the log file.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static native void dumpReferenceTables();
 
     /**
@@ -399,6 +438,7 @@
      *                   equal to <code>klass</code> are counted.
      * @return the number of matching instances.
      */
+    @libcore.api.CorePlatformApi
     public static native long countInstancesOfClass(Class klass, boolean assignable);
 
     /**
@@ -415,6 +455,7 @@
      *         for index <code>i</code> is the number of instances of
      *         the class <code>classes[i]</code>
      */
+    @libcore.api.CorePlatformApi
     public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable);
 
     /**
@@ -476,6 +517,7 @@
      *            the name of the runtime statistic to look up.
      * @return the value of the runtime statistic.
      */
+    @libcore.api.CorePlatformApi
     public static String getRuntimeStat(String statName) {
         if (statName == null) {
             throw new NullPointerException("statName == null");
@@ -493,6 +535,7 @@
      *
      * @return a map of the names/values of the supported runtime statistics.
      */
+    @libcore.api.CorePlatformApi
     public static Map<String, String> getRuntimeStats() {
         HashMap<String, String> map = new HashMap<>();
         String[] values = getRuntimeStatsInternal();
@@ -522,6 +565,7 @@
      * @param agent The path to the agent .so file plus optional agent arguments.
      * @param classLoader The classloader to use as a loading context.
      */
+    @libcore.api.CorePlatformApi
     public static void attachAgent(String agent, ClassLoader classLoader) throws IOException {
         nativeAttachAgent(agent, classLoader);
     }
@@ -539,5 +583,14 @@
      *
      * @param klass The class whose methods should be exempted.
      */
+    @UnsupportedAppUsage
     public static native void allowHiddenApiReflectionFrom(Class<?> klass);
+
+    /**
+     * Sets the number of frames recorded for allocation tracking.
+     *
+     * @param stackDepth The number of frames captured for each stack trace.
+     */
+    @libcore.api.CorePlatformApi
+    public static native void setAllocTrackerStackDepth(int stackDepth);
 }
diff --git a/dalvik/src/main/java/dalvik/system/VersionCodes.java b/dalvik/src/main/java/dalvik/system/VersionCodes.java
new file mode 100644
index 0000000..670db0f
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/VersionCodes.java
@@ -0,0 +1,53 @@
+/*
+ * 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 libcore.api.CorePlatformApi;
+import libcore.api.IntraCoreApi;
+
+/**
+ * Version code constants for Android releases.
+ *
+ * <p>Note: The constants are "public static final int" and are intended for use with annotations
+ * so must stay compile-time resolvable and inline-able. They must match the values from
+ * framework's android.os.Build.VERSION_CODES class.
+ *
+ * <p>Only historically fixed API levels should be included or abstract concepts like "CURRENT"
+ * should be added. Do not predict API levels.
+ *
+ * {@hide}
+ */
+@CorePlatformApi
+@IntraCoreApi
+public class VersionCodes {
+
+    private VersionCodes() {
+    }
+
+    /**
+     * The version code for Android Oreo (API version 26).
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    public static final int O = 26;
+
+    /**
+     * The version code for Android Pie (API version 28).
+     */
+    @CorePlatformApi
+    @IntraCoreApi
+    public static final int P = 28;
+}
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
index 61c1b95..13769e1 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;
 
 /**
@@ -24,32 +28,92 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class ZygoteHooks {
-    private long token;
+    private static long token;
+
+    /** All methods are static, no need to instantiate. */
+    private ZygoteHooks() {
+    }
 
     /**
      * Called by the zygote when starting up. It marks the point when any thread
      * start should be an error, as only internal daemon threads are allowed there.
      */
+    @libcore.api.CorePlatformApi
     public static native void startZygoteNoThreadCreation();
 
     /**
+     * Called when the zygote begins preloading classes and data.
+     */
+    @libcore.api.CorePlatformApi
+    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.
+     */
+    @libcore.api.CorePlatformApi
+    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().
+     */
+    @libcore.api.CorePlatformApi
+    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.
      */
+    @libcore.api.CorePlatformApi
     public static native void stopZygoteNoThreadCreation();
 
     /**
      * 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.
      */
-    public void preFork() {
+    @libcore.api.CorePlatformApi
+    public static void preFork() {
         Daemons.stop();
-        waitUntilAllThreadsStopped();
         token = nativePreFork();
+        waitUntilAllThreadsStopped();
+    }
+
+    /**
+     * Called by the zygote in the system server process after forking. This method is is called
+     * before {@code postForkChild} for system server.
+     */
+    @libcore.api.CorePlatformApi
+    public static void postForkSystemServer() {
+        nativePostForkSystemServer();
     }
 
     /**
@@ -57,7 +121,8 @@
      * flags from {@code runtimeFlags} are applied to the child process. The string
      * {@code instructionSet} determines whether to use a native bridge.
      */
-    public void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
+    @libcore.api.CorePlatformApi
+    public static void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
             String instructionSet) {
         nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);
 
@@ -69,11 +134,20 @@
      * every fork. In the child process, this method is called after
      * {@code postForkChild}.
      */
-    public void postForkCommon() {
+    @libcore.api.CorePlatformApi
+    public static void postForkCommon() {
         Daemons.startPostZygoteFork();
+        nativePostZygoteFork();
     }
 
+
+    // Hook for SystemServer specific early initialization post-forking.
+    private static native void nativePostForkSystemServer();
+
     private static native long nativePreFork();
+    private static native void nativePostZygoteFork();
+
+    // Hook for all child processes post forking.
     private static native void nativePostForkChild(long token, int runtimeFlags,
                                                    boolean isSystemServer, boolean isZygote,
                                                    String instructionSet);
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java b/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java
index a9efabe..271a985 100644
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java
+++ b/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java
@@ -23,47 +23,62 @@
  * Methods used to test calling into native code. The methods in this
  * class are all effectively no-ops and may be used to test the mechanisms
  * and performance of calling native methods.
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class NativeTestTarget {
+    @libcore.api.CorePlatformApi
     public NativeTestTarget() {
     }
 
     /**
      * This is used to benchmark dalvik's inline natives.
      */
+    @libcore.api.CorePlatformApi
     public static void emptyInlineMethod() {
     }
 
     /**
      * This is used to benchmark dalvik's inline natives.
      */
+    @libcore.api.CorePlatformApi
     public static native void emptyInternalStaticMethod();
 
     // Synchronized methods. Test normal JNI only.
+    @libcore.api.CorePlatformApi
     public static native synchronized void emptyJniStaticSynchronizedMethod0();
+    @libcore.api.CorePlatformApi
     public native synchronized void emptyJniSynchronizedMethod0();
 
     // Static methods without object parameters. Test all optimization combinations.
 
     // Normal native.
+    @libcore.api.CorePlatformApi
     public static native void emptyJniStaticMethod0();
     // Normal native.
+    @libcore.api.CorePlatformApi
     public static native void emptyJniStaticMethod6(int a, int b, int c, int d, int e, int f);
 
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native void emptyJniStaticMethod0_Fast();
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native void emptyJniStaticMethod6_Fast(int a, int b, int c, int d, int e, int f);
 
+    @libcore.api.CorePlatformApi
     @CriticalNative
     public static native void emptyJniStaticMethod0_Critical();
+    @libcore.api.CorePlatformApi
     @CriticalNative
     public static native void emptyJniStaticMethod6_Critical(int a, int b, int c, int d, int e, int f);
     // Instance methods or methods with object parameters. Test {Normal, @FastNative} combinations.
 
     // Normal native.
+    @libcore.api.CorePlatformApi
     public native void emptyJniMethod0();
     // Normal native.
+    @libcore.api.CorePlatformApi
     public native void emptyJniMethod6(int a, int b, int c, int d, int e, int f);
 
     /**
@@ -73,15 +88,19 @@
      * references.
      */
     // Normal native.
+    @libcore.api.CorePlatformApi
     public static native void emptyJniStaticMethod6L(String a, String[] b,
         int[][] c, Object d, Object[] e, Object[][][][] f);
 
     // Normal native.
+    @libcore.api.CorePlatformApi
     public native void emptyJniMethod6L(String a, String[] b,
         int[][] c, Object d, Object[] e, Object[][][][] f);
 
+    @libcore.api.CorePlatformApi
     @FastNative
     public native void emptyJniMethod0_Fast();
+    @libcore.api.CorePlatformApi
     @FastNative
     public native void emptyJniMethod6_Fast(int a, int b, int c, int d, int e, int f);
 
@@ -91,10 +110,12 @@
      * parsing the signature. All six values should be null
      * references.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public static native void emptyJniStaticMethod6L_Fast(String a, String[] b,
         int[][] c, Object d, Object[] e, Object[][][][] f);
 
+    @libcore.api.CorePlatformApi
     @FastNative
     public native void emptyJniMethod6L_Fast(String a, String[] b,
         int[][] c, Object d, Object[] e, Object[][][][] f);
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java
index 9b98893..373364b 100644
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java
+++ b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.dalvik.ddmc;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.nio.ByteBuffer;
 
 /**
@@ -24,12 +25,16 @@
  *
  * The "offset" and "length" fields are present so handlers can over-allocate
  * or share byte buffers.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class Chunk {
 
     /*
      * Public members.  Do not rename without updating the VM.
      */
+    @libcore.api.CorePlatformApi
     public int type;                // chunk type
     public byte[] data;             // chunk data
     public int offset, length;      // position within "data"
@@ -42,6 +47,7 @@
     /**
      * Constructor with all fields.
      */
+    @libcore.api.CorePlatformApi
     public Chunk(int type, byte[] data, int offset, int length) {
         this.type = type;
         this.data = data;
@@ -53,6 +59,8 @@
      * Construct from a ByteBuffer.  The chunk is assumed to start at
      * offset 0 and continue to the current position.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public Chunk(int type, ByteBuffer buf) {
         this.type = type;
 
@@ -61,4 +69,3 @@
         this.length = buf.position();
     }
 }
-
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java
index 5d0073b..d7f370d 100644
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java
+++ b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/ChunkHandler.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.dalvik.ddmc;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
@@ -24,26 +25,34 @@
  *
  * To handle a chunk type, sub-class ChunkHandler and register your class
  * with DdmServer.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public abstract class ChunkHandler {
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN;
 
     public static final int CHUNK_FAIL = type("FAIL");
 
 
+    @libcore.api.CorePlatformApi
     public ChunkHandler() {}
 
     /**
      * Called when the DDM server connects.  The handler is allowed to
      * send messages to the server.
      */
+    @libcore.api.CorePlatformApi
     public abstract void connected();
 
     /**
      * Called when the DDM server disconnects.  Can be used to disable
      * periodic transmissions or clean up saved state.
      */
+    @libcore.api.CorePlatformApi
     public abstract void disconnected();
 
     /**
@@ -52,12 +61,14 @@
      *
      * Returns a response in a Chunk.
      */
+    @libcore.api.CorePlatformApi
     public abstract Chunk handleChunk(Chunk request);
 
     /**
      * Create a FAIL chunk.  The "handleChunk" methods can use this to
      * return an error message when they are not able to process a chunk.
      */
+    @libcore.api.CorePlatformApi
     public static Chunk createFailChunk(int errorCode, String msg) {
         if (msg == null)
             msg = "";
@@ -74,6 +85,7 @@
     /**
      * Utility function to wrap a ByteBuffer around a Chunk.
      */
+    @libcore.api.CorePlatformApi
     public static ByteBuffer wrapChunk(Chunk request) {
         ByteBuffer in;
 
@@ -89,6 +101,7 @@
      * This is here because multiple chunk handlers can make use of it,
      * and there's nowhere better to put it.
      */
+    @libcore.api.CorePlatformApi
     public static String getString(ByteBuffer buf, int len) {
         char[] data = new char[len];
         for (int i = 0; i < len; i++)
@@ -99,6 +112,7 @@
     /**
      * Utility function to copy a String into a ByteBuffer.
      */
+    @libcore.api.CorePlatformApi
     public static void putString(ByteBuffer buf, String str) {
         int len = str.length();
         for (int i = 0; i < len; i++)
@@ -108,6 +122,7 @@
     /**
      * Convert a 4-character string to a 32-bit type.
      */
+    @libcore.api.CorePlatformApi
     public static int type(String typeName) {
         if (typeName.length() != 4) {
             throw new IllegalArgumentException("Bad type name: " + typeName);
@@ -122,6 +137,7 @@
     /**
      * Convert an integer type to a 4-character string.
      */
+    @libcore.api.CorePlatformApi
     public static String name(int type)
     {
         char[] ascii = new char[4];
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java
index 5a2c06d..e961d56 100644
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java
+++ b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmServer.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.dalvik.ddmc;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 import java.util.Collection;
 import java.util.HashMap;
@@ -24,11 +25,12 @@
 
 /**
  * This represents our connection to the DDM Server.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class DdmServer {
 
-    public static final int CLIENT_PROTOCOL_VERSION = 1;
-
     private static HashMap<Integer,ChunkHandler> mHandlerMap =
         new HashMap<Integer,ChunkHandler>();
 
@@ -50,6 +52,7 @@
      *
      * Throws an exception if the type already has a handler registered.
      */
+    @libcore.api.CorePlatformApi
     public static void registerHandler(int type, ChunkHandler handler) {
         if (handler == null) {
             throw new NullPointerException("handler == null");
@@ -78,6 +81,7 @@
      * The application must call here after it finishes registering
      * handlers.
      */
+    @libcore.api.CorePlatformApi
     public static void registrationComplete() {
         // sync on mHandlerMap because it's convenient and makes a kind of
         // sense
@@ -93,6 +97,8 @@
      *
      * Use this for "unsolicited" chunks.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void sendChunk(Chunk chunk) {
         nativeSendChunk(chunk.type, chunk.data, chunk.offset, chunk.length);
     }
@@ -105,6 +111,7 @@
     /*
      * Called by the VM when the DDM server connects or disconnects.
      */
+    @UnsupportedAppUsage
     private static void broadcast(int event)
     {
         synchronized (mHandlerMap) {
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java
index 786efe7..ac994bb 100644
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java
+++ b/dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/DdmVmInternal.java
@@ -16,11 +16,15 @@
 
 package org.apache.harmony.dalvik.ddmc;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 
 /**
  * Declarations for some VM-internal DDM stuff.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class DdmVmInternal {
 
     /* do not instantiate */
@@ -31,6 +35,7 @@
      *
      * This is built into the VM, since that's where threads get managed.
      */
+    @libcore.api.CorePlatformApi
     native public static void threadNotify(boolean enable);
 
     /**
@@ -42,6 +47,7 @@
      * @return true on success.  false if 'when' is bad or if there was
      *         an internal error.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     native public static boolean heapInfoNotify(int when);
 
@@ -51,6 +57,7 @@
      *
      * This is built into the VM, since that's where the heap is managed.
      */
+    @libcore.api.CorePlatformApi
     native public static boolean heapSegmentNotify(int when, int what,
         boolean isNative);
 
@@ -60,30 +67,36 @@
      * Returns a byte array with the THST data, or null if something
      * went wrong.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     native public static byte[] getThreadStats();
 
     /**
      * Get a stack trace for the specified thread ID.  The ID can be found
      * in the data from getThreadStats.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     native public static StackTraceElement[] getStackTraceById(int threadId);
 
     /**
      * Enable or disable "recent allocation" tracking.
      */
+    @libcore.api.CorePlatformApi
     native public static void enableRecentAllocations(boolean enable);
 
     /*
      * Return a boolean indicating whether or not the "recent allocation"
      * feature is currently enabled.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     native public static boolean getRecentAllocationStatus();
 
     /**
      * Fill a buffer with data on recent heap allocations.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     native public static byte[] getRecentAllocations();
 }
-
diff --git a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp b/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp
index f3c552f..9f2b429 100644
--- a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp
+++ b/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp
@@ -17,7 +17,9 @@
 #define LOG_TAG "NativeTestTarget"
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
+
+#define NATIVE_METHOD(className, functionName, signature)               \
+    { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
 
 static void NativeTestTarget_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { }
 static void NativeTestTarget_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { }
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 46221d1..6c14660 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1478,7 +1478,7 @@
   bug: 19764047,
   result: EXEC_FAILED,
   names: [
-    "libcore.libcore.io.OsTest#test_PacketSocketAddress"
+    "libcore.android.system.OsTest#test_PacketSocketAddress"
   ]
 },
 {
@@ -1533,15 +1533,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/io/ObjectStreamClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
index 6253b6b..16a7415 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
@@ -18,7 +18,6 @@
 package org.apache.harmony.tests.java.io;
 
 import dalvik.system.DexFile;
-import dalvik.system.VMRuntime;
 import java.io.Externalizable;
 import java.io.File;
 import java.io.IOException;
@@ -28,15 +27,21 @@
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
-import junit.framework.TestCase;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
-public class ObjectStreamClassTest extends TestCase {
+public class ObjectStreamClassTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
     static class DummyClass implements Serializable {
         private static final long serialVersionUID = 999999999999999L;
@@ -228,102 +233,55 @@
     }
 
     // http://b/28106822
-    public void testBug28106822() throws Exception {
-        int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+    @TargetSdkVersion(24)
+    public void testBug28106822_target24() throws Exception {
+        // Assert behavior up to 24
+        Method getConstructorId = getConstructorIdMethod();
+
+        assertEquals(1189998819991197253L, getConstructorId.invoke(null, Object.class));
+        assertEquals(1189998819991197253L, getConstructorId.invoke(null, String.class));
+
+        Method newInstance = getNewInstanceMethod();
+
+        Object obj = newInstance.invoke(null, String.class, 0 /* ignored */);
+        assertNotNull(obj);
+        assertTrue(obj instanceof String);
+    }
+
+    // http://b/28106822
+    @TargetSdkVersion(25)
+    public void testBug28106822_target25() throws Exception {
+        // Assert behavior from API 25
+        Method getConstructorId = getConstructorIdMethod();
+
+        Method newInstance = getNewInstanceMethod();
+
         try {
-            // Assert behavior up to 24
-            VMRuntime.getRuntime().setTargetSdkVersion(24);
-            Method getConstructorId = ObjectStreamClass.class.getDeclaredMethod(
-                    "getConstructorId", Class.class);
-            getConstructorId.setAccessible(true);
-
-            assertEquals(1189998819991197253L, getConstructorId.invoke(null, Object.class));
-            assertEquals(1189998819991197253L, getConstructorId.invoke(null, String.class));
-
-            Method newInstance = ObjectStreamClass.class.getDeclaredMethod("newInstance",
-                    Class.class, Long.TYPE);
-            newInstance.setAccessible(true);
-
-            Object obj = newInstance.invoke(null, String.class, 0 /* ignored */);
-            assertNotNull(obj);
-            assertTrue(obj instanceof String);
-
-            // Assert behavior from API 25
-            VMRuntime.getRuntime().setTargetSdkVersion(25);
-            try {
-                getConstructorId.invoke(null, Object.class);
-                fail();
-            } catch (InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
-            }
-            try {
-                newInstance.invoke(null, String.class, 0 /* ignored */);
-                fail();
-            } catch (InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
-            }
-
-        } finally {
-            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
+            getConstructorId.invoke(null, Object.class);
+            fail();
+        } catch (InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsupportedOperationException);
+        }
+        try {
+            newInstance.invoke(null, String.class, 0 /* ignored */);
+            fail();
+        } catch (InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsupportedOperationException);
         }
     }
 
-    // Class without <clinit> method
-    public static class NoClinitParent {
-    }
-    // Class without <clinit> method
-    public static class NoClinitChildWithNoClinitParent extends NoClinitParent {
+    private Method getConstructorIdMethod() throws NoSuchMethodException {
+        Method getConstructorId = ObjectStreamClass.class.getDeclaredMethod(
+            "getConstructorId", Class.class);
+        getConstructorId.setAccessible(true);
+        return getConstructorId;
     }
 
-    // Class with <clinit> method
-    public static class ClinitParent {
-        // This field will trigger creation of <clinit> method for this class
-        private static final String TAG = ClinitParent.class.getName();
-        static {
-
-        }
-    }
-    // Class without <clinit> but with parent that has <clinit> method
-    public static class NoClinitChildWithClinitParent extends ClinitParent {
-    }
-
-    // http://b/29064453
-    public void testHasClinit() throws Exception {
-        Method hasStaticInitializer =
-            ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer", Class.class,
-                                                      boolean.class);
-        hasStaticInitializer.setAccessible(true);
-
-        assertTrue((Boolean)
-                   hasStaticInitializer.invoke(null, ClinitParent.class,
-                                               false /* checkSuperclass */));
-
-        // RI will return correctly False in this case, but android has been returning true
-        // in this particular case. We're returning true to enable deserializing classes
-        // like NoClinitChildWithClinitParent without explicit serialVersionID field.
-        assertTrue((Boolean)
-                   hasStaticInitializer.invoke(null, NoClinitChildWithClinitParent.class,
-                                               false /* checkSuperclass */));
-        assertFalse((Boolean)
-                    hasStaticInitializer.invoke(null, NoClinitParent.class,
-                                                false /* checkSuperclass */));
-        assertFalse((Boolean)
-                    hasStaticInitializer.invoke(null, NoClinitChildWithNoClinitParent.class,
-                                                false /* checkSuperclass */));
-
-
-        assertTrue((Boolean)
-                   hasStaticInitializer.invoke(null, ClinitParent.class,
-                                               true /* checkSuperclass */));
-        assertFalse((Boolean)
-                   hasStaticInitializer.invoke(null, NoClinitChildWithClinitParent.class,
-                                               true /* checkSuperclass */));
-        assertFalse((Boolean)
-                    hasStaticInitializer.invoke(null, NoClinitParent.class,
-                                                true /* checkSuperclass */));
-        assertFalse((Boolean)
-                    hasStaticInitializer.invoke(null, NoClinitChildWithNoClinitParent.class,
-                                                true /* checkSuperclass */));
+    private Method getNewInstanceMethod() throws NoSuchMethodException {
+        Method newInstance = ObjectStreamClass.class.getDeclaredMethod("newInstance",
+            Class.class, Long.TYPE);
+        newInstance.setAccessible(true);
+        return newInstance;
     }
 
     // http://b/29721023
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/lang/String2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java
index a3e6e54..de7ec1a 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/String2Test.java
@@ -718,6 +718,7 @@
     /**
      * java.lang.String#substring(int)
      */
+    @SuppressWarnings("SubstringOfZero")
     public void test_substringI() {
         // Test for method java.lang.String java.lang.String.substring(int)
         assertEquals("Incorrect substring returned", "World", hw1.substring(5));
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/net/IDNTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java
index dfd4d66..d6cf4a9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/IDNTest.java
@@ -153,4 +153,12 @@
                 "www\uFF0Exn--gwtq9nb2a\uFF61jp", IDN.USE_STD3_ASCII_RULES));
 
     }
+
+    // b/113787610: "." is a valid IDN, as are absolute domain names with a trailing dot.
+    public void test_TrailingDots() {
+        assertEquals("google.com.", IDN.toASCII("google.com."));
+        assertEquals(".", IDN.toASCII("."));
+        assertEquals("google.com.", IDN.toUnicode("google.com."));
+        assertEquals(".", IDN.toUnicode("."));
+    }
 }
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/DirectByteBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java
index 517973c..642688f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectByteBufferTest.java
@@ -25,7 +25,7 @@
 
     protected void setUp() throws Exception {
         super.setUp();
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH);
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Byte.BYTES);
         baseBuf = buf;
     }
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java
index 80a9be4..6d25de9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectCharBufferTest.java
@@ -20,12 +20,11 @@
 import java.nio.CharBuffer;
 import java.nio.DirectByteBuffer;
 import java.nio.NIOAccess;
-import libcore.io.SizeOf;
 
 public class DirectCharBufferTest extends CharBufferTest {
     
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asCharBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Character.BYTES).asCharBuffer();
         super.loadTestData1(buf);
         baseBuf = buf;
     }
@@ -66,7 +65,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         charBuffer.put('b');
-        assertEquals(charBufferBasePointer + SizeOf.CHAR, NIOAccess.getBasePointer(charBuffer));
+        assertEquals(charBufferBasePointer + Character.BYTES, NIOAccess.getBasePointer(charBuffer));
     }
 
     public void testIsDirect() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java
index f27c897..cd99312 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectDoubleBufferTest.java
@@ -20,11 +20,10 @@
 import java.nio.DirectByteBuffer;
 import java.nio.DoubleBuffer;
 import java.nio.NIOAccess;
-import libcore.io.SizeOf;
 
 public class DirectDoubleBufferTest extends DoubleBufferTest {
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asDoubleBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Double.BYTES).asDoubleBuffer();
         loadTestData1(buf);
         baseBuf = buf;
     }
@@ -65,7 +64,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         doubleBuffer.put(1.0);
-        assertEquals(doubleBufferBasePointer + SizeOf.DOUBLE, NIOAccess.getBasePointer(doubleBuffer));
+        assertEquals(doubleBufferBasePointer + Double.BYTES, NIOAccess.getBasePointer(doubleBuffer));
     }
 
     public void testIsDirect() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java
index ecbd542..0812d53 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectFloatBufferTest.java
@@ -20,11 +20,10 @@
 import java.nio.DirectByteBuffer;
 import java.nio.FloatBuffer;
 import java.nio.NIOAccess;
-import libcore.io.SizeOf;
 
 public class DirectFloatBufferTest extends FloatBufferTest {
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asFloatBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Float.BYTES).asFloatBuffer();
         loadTestData1(buf);
         baseBuf = buf;
     }
@@ -66,7 +65,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         floatBuffer.put((float)1);
-        assertEquals(floatBufferBasePointer + SizeOf.FLOAT, NIOAccess.getBasePointer(floatBuffer));
+        assertEquals(floatBufferBasePointer + Float.BYTES, NIOAccess.getBasePointer(floatBuffer));
     }
 
     public void testIsDirect() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java
index 4421ba0..68bd896 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectIntBufferTest.java
@@ -20,11 +20,10 @@
 import java.nio.DirectByteBuffer;
 import java.nio.IntBuffer;
 import java.nio.NIOAccess;
-import libcore.io.SizeOf;
 
 public class DirectIntBufferTest extends IntBufferTest {
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*4).asIntBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Integer.BYTES).asIntBuffer();
         loadTestData1(buf);
         baseBuf = buf;
     }
@@ -66,7 +65,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         intBuffer.put(1);
-        assertEquals(intBufferBasePointer + SizeOf.INT, NIOAccess.getBasePointer(intBuffer));
+        assertEquals(intBufferBasePointer + Integer.BYTES, NIOAccess.getBasePointer(intBuffer));
     }
 
     public void testIsDirect() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java
index 4bcd197..ef017f4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectLongBufferTest.java
@@ -20,11 +20,10 @@
 import java.nio.DirectByteBuffer;
 import java.nio.LongBuffer;
 import java.nio.NIOAccess;
-import libcore.io.SizeOf;
 
 public class DirectLongBufferTest extends LongBufferTest {
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*8).asLongBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Long.BYTES).asLongBuffer();
         loadTestData1(buf);
         baseBuf = buf;
     }
@@ -66,7 +65,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         longBuffer.put(1L);
-        assertEquals(longBufferBasePointer + SizeOf.LONG, NIOAccess.getBasePointer(longBuffer));
+        assertEquals(longBufferBasePointer + Long.BYTES, NIOAccess.getBasePointer(longBuffer));
     }
 
     public void testIsDirect() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java
index e1b91a8..a3ce995 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/DirectShortBufferTest.java
@@ -20,11 +20,10 @@
 import java.nio.DirectByteBuffer;
 import java.nio.NIOAccess;
 import java.nio.ShortBuffer;
-import libcore.io.SizeOf;
 
 public class DirectShortBufferTest extends ShortBufferTest {
     public void setUp(){
-        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asShortBuffer();
+        buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*Short.BYTES).asShortBuffer();
         loadTestData1(buf);
         baseBuf = buf;
     }
@@ -56,7 +55,7 @@
     }
 
     // http://b/28964300
-    public void testJNIAccessByAddress() throws Exception {
+    public void testJNIAccessByAddress() {
         DirectByteBuffer directByteBuffer = (DirectByteBuffer) ByteBuffer.allocateDirect(10);
         directByteBuffer.put((byte)'a');
         ShortBuffer shortBuffer = directByteBuffer.asShortBuffer();
@@ -66,7 +65,7 @@
 
         // Check if the NIOAccess method adds up the current position value.
         shortBuffer.put((short)1);
-        assertEquals(shortBufferBasePointer + SizeOf.SHORT, NIOAccess.getBasePointer(shortBuffer));
+        assertEquals(shortBufferBasePointer + Short.BYTES, NIOAccess.getBasePointer(shortBuffer));
     }
 
     public void testIsDirect() {
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/text/SimpleDateFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
index 7793169..2eb64fe 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
@@ -891,51 +891,76 @@
         assertEquals(f2.toPattern(), f2.toLocalizedPattern());
     }
 
-    public void test_parse_with_spaces() {
-        // Regression for HARMONY-502
-        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
-        df.setLenient(false);
+    // Regression for HARMONY-502
+    public void test_parse_whitespace_within_date() {
+        Date date = new GregorianCalendar(2003, Calendar.APRIL, 5, 9, 7, 6).getTime();
+        parse_whitespace_variants(
+            new SimpleDateFormat("HH:mm:ss dd/MM/yy"),
+            date,
+            new String[] {
+                "%c9:07:06 05/04/03",
+                "%c09:07:06 05/04/03",
+                "09:%c7:06 05/04/03",
+                "09:%c07:06 05/04/03",
+                "09:07:%c6 05/04/03",
+                "09:07:%c06 05/04/03",
+                "09:07:06 %c05/04/03",
+                "09:07:06 %c5/04/03",
+                "09:07:06 05/%c4/03",
+                "09:07:06 05/%c04/03",
+                "09:07:06 05/04/%c03",
+            });
 
-        char allowed_chars[] = { 0x9, 0x20 };
-        String allowed_char_names[] = { "tab", "space" };
-        for (int i = 0; i < allowed_chars.length; i++) {
-            Date expected = new GregorianCalendar(1970, Calendar.JANUARY, 1, 9, 7, 6).getTime();
-            ParsePosition pp = new ParsePosition(0);
-            Date d = df.parse(allowed_chars[i] + "9:07:06", pp);
-            assertNotNull("hour may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
+        parse_whitespace_variants(
+            new SimpleDateFormat("HH:mm:ss dd/MM/yyyy"),
+            date,
+            new String[] {
+                "09:07:06 05/04/%c2003",
+            });
+    }
 
-            pp = new ParsePosition(0);
-            d = df.parse("09:" + allowed_chars[i] + "7:06", pp);
-            assertNotNull("minute may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
-
-            pp = new ParsePosition(0);
-            d = df.parse("09:07:" + allowed_chars[i] + "6", pp);
-            assertNotNull("second may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
-        }
-
-        char not_allowed_chars[] = {
-                // whitespace
+    // Tests valid and invalid whitespace characters are parsed correctly within
+    // a date string. dateFormat and expected are the SimpleDateFormat and expected date.
+    // variants is a list of input variations where %c will be substituted with
+    // the whitespace characters to test.
+    private void parse_whitespace_variants(SimpleDateFormat dateFormat, Date expected,
+        String[] variants) {
+        char validWhitespace[] = { 0x9, 0x20 };
+        char invalidWhitespace[] = {
+                // Whitespace
                 0x1c, 0x1d, 0x1e, 0x1f, 0xa, 0xb, 0xc, 0xd, 0x2001, 0x2002,
                 0x2003, 0x2004, 0x2005, 0x2006, 0x2008, 0x2009, 0x200a, 0x200b,
                 0x2028, 0x2029, 0x3000,
-                // non-breaking space
+                // Non-breaking space
                 0xA0, 0x2007, 0x202F };
 
-        for (int i = 0; i < not_allowed_chars.length; i++) {
-            ParsePosition pp = new ParsePosition(0);
-            Date d = df.parse(not_allowed_chars[i] + "9:07", pp);
-            assertNull(d);
+        dateFormat.setLenient(false);
+        for (String variant: variants) {
+            for (char c : validWhitespace) {
+                String info = String.format("Parsing variant='%s', c=0x%x:", variant, (int) c);
+                String input = String.format(variant, c);
+                Date date = dateFormat.parse(input, new ParsePosition(0));
+                assertEquals(info, expected, date);
+                try {
+                    date = dateFormat.parse(input);
+                } catch (ParseException e) {
+                    fail(info);
+                }
+                assertEquals(info, expected, date);
 
-            pp = new ParsePosition(0);
-            d = df.parse("09:" + not_allowed_chars[i] + "7", pp);
-            assertNull(d);
-
-            pp = new ParsePosition(0);
-            d = df.parse("09:07:" + not_allowed_chars[i] + "6", pp);
-            assertNull(d);
+            }
+            for (char c : invalidWhitespace) {
+                String info = String.format("Parsing variant='%s', c=0x%x:", variant, (int) c);
+                String input = String.format(variant, c);
+                Date date = dateFormat.parse(input, new ParsePosition(0));
+                assertNull(info, date);
+                try {
+                    dateFormat.parse(input);
+                    fail(info);
+                } catch (ParseException e) {
+                    // Expected
+                }
+            }
         }
     }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java
index 7b3d7d0..1959c42 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ArrayListTest.java
@@ -16,10 +16,10 @@
  */
 package org.apache.harmony.tests.java.util;
 
-import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -27,6 +27,7 @@
 import java.util.Set;
 import java.util.Spliterator;
 import java.util.Vector;
+import java.util.function.Supplier;
 
 import libcore.java.util.SpliteratorTester;
 import tests.support.Support_ListTest;
@@ -888,6 +889,23 @@
         list.trimToSize();
     }
 
+    /**
+     * Checks that an element can successfully be added to an ArrayList that
+     * was previously {@link ArrayList#trimToSize() trimmed} to the empty size.
+     */
+    public void test_trimToEmpty_add() {
+        ArrayList<String> list = new ArrayList<>();
+        list.trimToSize(); // empty after construction
+        list.add("element");
+        assertEquals(Arrays.asList("element"), list);
+
+        list.remove("element");
+        assertEquals(Collections.emptyList(), list);
+        list.trimToSize(); // empty after all elements have been removed
+        list.add("element");
+        assertEquals(Arrays.asList("element"), list);
+    }
+
     public void test_addAll() {
         ArrayList list = new ArrayList();
         list.add("one");
@@ -1109,8 +1127,12 @@
     }
 
     public void test_forEachRemaining_iterator() throws Exception {
-        ForEachRemainingTester.runTests(ArrayList.class, new String[] { "foo", "bar", "baz"});
-        ForEachRemainingTester.runTests(ArrayList.class, new String[] { "foo" });
+        ForEachRemainingTester.runTests(ArrayList::new, new String[] { "foo", "bar", "baz"});
+        ForEachRemainingTester.runTests(ArrayList::new, new String[] { "foo" });
+
+        Supplier<List<String>> sublistSupplier = () -> new ArrayList<String>().subList(0, 0);
+        ForEachRemainingTester.runTests(sublistSupplier, new String[] { "foo", "bar", "baz"});
+        ForEachRemainingTester.runTests(sublistSupplier, new String[] { "foo" });
     }
 
     public void test_spliterator() throws Exception {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java
index 2bbcd1e..cadb38f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ConcurrentModificationExceptionTest.java
@@ -91,6 +91,23 @@
         fail("Failed to throw expected ConcurrentModificationException");
     }
 
+    @SuppressWarnings("ThrowableNotThrown")
+    public void test_messageAndCause() {
+        Throwable cause = new Throwable("cause msg");
+        assertMessageAndCause(null, null, new ConcurrentModificationException());
+        assertMessageAndCause("msg", null, new ConcurrentModificationException("msg"));
+        assertMessageAndCause("msg", cause, new ConcurrentModificationException("msg", cause));
+        assertMessageAndCause("msg", null, new ConcurrentModificationException("msg", null));
+        assertMessageAndCause(null, null, new ConcurrentModificationException((Throwable) null));
+        // cause.toString() is something like "java.lang.Throwable: cause msg"
+        assertMessageAndCause(cause.toString(), cause, new ConcurrentModificationException(cause));
+    }
+
+    private static void assertMessageAndCause(String message, Throwable cause, Exception e) {
+        assertEquals(message, e.getMessage());
+        assertEquals(cause, e.getCause());
+    }
+
     /**
      * Sets up the fixture, for example, open a network connection. This method
      * is called before a test is executed.
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java
index fb2cbcb..baaaf71 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumSetTest.java
@@ -17,6 +17,7 @@
 package org.apache.harmony.tests.java.util;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.EnumSet;
 import java.util.Iterator;
@@ -206,7 +207,6 @@
         EnumSet<HugeEnum> anotherHugeSet = EnumSet.allOf(HugeEnum.class);
         assertEquals(hugeEnumSet, anotherHugeSet);
         assertNotSame(hugeEnumSet, anotherHugeSet);
-
     }
 
     /**
@@ -605,16 +605,46 @@
      * java.util.EnumSet#size()
      */
     public void test_size() {
-        Set<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
-        set.add(EnumFoo.a);
-        set.add(EnumFoo.b);
-        assertEquals("Size should be 2", 2, set.size());
+        assertEmpty(EnumSet.noneOf(EnumFoo.class));
+        assertSize(2, EnumSet.of(EnumFoo.a, EnumFoo.b));
 
-        // test enum type with more than 64 elements
-        Set<HugeEnum> hugeSet = EnumSet.noneOf(HugeEnum.class);
-        hugeSet.add(HugeEnum.a);
-        hugeSet.add(HugeEnum.bb);
-        assertEquals("Size should be 2", 2, hugeSet.size());
+        // enum type with more than 64 elements
+        assertEmpty(EnumSet.noneOf(HugeEnum.class));
+        assertSize(2, EnumSet.of(HugeEnum.a, HugeEnum.bb));
+        assertSize(65, EnumSet.allOf(HugeEnum.class));
+    }
+
+    public void test_size_modification_regular() {
+        EnumSet<EnumFoo> set = EnumSet.noneOf(EnumFoo.class);
+        assertEmpty(set);
+        set.addAll(Arrays.asList(EnumFoo.a, EnumFoo.b));
+        assertSize(2, set);
+        set.add(EnumFoo.c);
+        assertSize(3, set);
+        set.remove(EnumFoo.d);
+        assertSize(3, set);
+        set.remove(EnumFoo.b);
+        assertSize(2, set);
+        set.clear();
+        assertEmpty(set);
+    }
+
+    public void test_size_modification_jumbo() {
+        EnumSet<HugeEnum> set = EnumSet.allOf(HugeEnum.class);
+        assertSize(65, set);
+        set.remove(HugeEnum.b);
+        assertSize(64, set);
+        set.clear();
+        assertEmpty(set);
+    }
+
+    private static void assertEmpty(EnumSet<?> set) {
+        assertSize(0, set);
+    }
+
+    private static void assertSize(int expectedSize, Set<?> set) {
+        assertEquals(expectedSize, set.size());
+        assertEquals(expectedSize == 0, set.isEmpty());
     }
 
     /**
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java
index ea829c9..e045161 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LinkedListTest.java
@@ -943,8 +943,8 @@
     }
 
     public void test_forEachRemaining_iterator() throws Exception {
-        ForEachRemainingTester.runTests(LinkedList.class, new String[]{ "foo", "bar", "baz "});
-        ForEachRemainingTester.runTests(LinkedList.class, new String[] { "foo" });
+        ForEachRemainingTester.runTests(LinkedList::new, new String[]{ "foo", "bar", "baz "});
+        ForEachRemainingTester.runTests(LinkedList::new, new String[] { "foo" });
     }
 
     public void test_spliterator() throws Exception {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
index f889c8e..d0b1f2b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/VectorTest.java
@@ -1437,8 +1437,8 @@
     }
 
     public void test_forEachRemaining_iterator() throws Exception {
-        ForEachRemainingTester.runTests(Vector.class, new String[] { "foo", "bar", "baz" });
-        ForEachRemainingTester.runTests(Vector.class, new String[] { "foo" });
+        ForEachRemainingTester.runTests(Vector::new, new String[] { "foo", "bar", "baz" });
+        ForEachRemainingTester.runTests(Vector::new, new String[] { "foo" });
     }
 
     public void test_spliterator() throws Exception {
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/prefs/AbstractPreferencesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java
index 49510e3..c107023 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/AbstractPreferencesTest.java
@@ -38,7 +38,7 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
@@ -88,7 +88,7 @@
 
     @Override
     protected void setUp() throws Exception {
-        File tmpDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new TestPreferencesFactory(tmpDir.getAbsolutePath()));
         root = (AbstractPreferences) Preferences.userRoot();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java
index 352603c..abcf9c9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/FilePreferencesImplTest.java
@@ -20,9 +20,10 @@
 import java.io.IOException;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
-import java.util.prefs.PreferencesFactory;
+
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+
+import libcore.testing.io.TestIoUtils;
 
 public class FilePreferencesImplTest extends TestCase {
 
@@ -31,7 +32,7 @@
 
     @Override
     protected void setUp() throws Exception {
-        File tmpDir = IoUtils.createTemporaryDirectory("FilePreferencesImplTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("FilePreferencesImplTest");
         AbstractPreferencesTest.TestPreferencesFactory factory
                 = new AbstractPreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath());
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java
index 6939248..16bf3ea 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/prefs/PreferencesTest.java
@@ -22,7 +22,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.FileOutputStream;
-import java.net.MalformedURLException;
 import java.nio.charset.StandardCharsets;
 import java.util.prefs.AbstractPreferences;
 import java.util.prefs.BackingStoreException;
@@ -32,7 +31,8 @@
 import java.util.prefs.Preferences;
 import java.util.prefs.PreferencesFactory;
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+
+import libcore.testing.io.TestIoUtils;
 
 /**
  *
@@ -55,7 +55,7 @@
 
     @Override
     protected void setUp() throws Exception {
-        backendDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+        backendDir = TestIoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new AbstractPreferencesTest.TestPreferencesFactory(backendDir.getAbsolutePath()));
 
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..7eab306 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;
@@ -34,6 +36,7 @@
 import javax.net.ssl.SSLEngineResult.Status;
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLSession;
 import junit.framework.TestCase;
 import libcore.java.security.StandardNames;
 import libcore.javax.net.ssl.TestSSLContext;
@@ -62,7 +65,7 @@
         assertEquals(-1, e.getPeerPort());
         String[] suites = e.getSupportedCipherSuites();
         e.setEnabledCipherSuites(suites);
-        assertEquals(e.getEnabledCipherSuites().length, suites.length);
+        assertEquals(suites.length, e.getEnabledCipherSuites().length);
     }
 
     /**
@@ -99,11 +102,20 @@
         assertEquals(e.getPeerPort(), port);
         String[] suites = e.getSupportedCipherSuites();
         e.setEnabledCipherSuites(suites);
-        assertEquals(e.getEnabledCipherSuites().length, suites.length);
+        assertEquals(suites.length, e.getEnabledCipherSuites().length);
         e.setUseClientMode(true);
         assertTrue(e.getUseClientMode());
     }
 
+    // Test constructing a raw engine subclass rather than a functioning implementation.
+    public void test_ConstructorLjava_lang_StringI03() throws Exception {
+        String host = "new host";
+        int port = 8080;
+        SSLEngine e = getRawEngine(host, port);
+        assertEquals(e.getPeerHost(), host);
+        assertEquals(e.getPeerPort(), port);
+    }
+
     /**
      * Test for <code>getPeerHost()</code> method
      */
@@ -176,8 +188,9 @@
         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));
+        List<String> supported = new ArrayList<>(Arrays.asList(st));
+        assertEquals("Incorrect array length", res.length, supported.size());
+        assertEquals("Incorrect array was returned", Arrays.asList(res), supported);
 
         try {
             sse.setEnabledCipherSuites(null);
@@ -1020,18 +1033,49 @@
         }
     }
 
-    private SSLEngine getEngine() throws Exception {
+    private static SSLEngine getEngine() throws Exception {
         SSLContext context = SSLContext.getInstance("TLS");
         context.init(null, null, null);
         return context.createSSLEngine();
     }
 
-    private SSLEngine getEngine(String host, int port) throws Exception {
+    private static SSLEngine getEngine(String host, int port) throws Exception {
         SSLContext context = SSLContext.getInstance("TLS");
         context.init(null, null, null);
         return context.createSSLEngine(host, port);
     }
 
+    private static SSLEngine getRawEngine(String host, int port) throws Exception {
+        return new SSLEngine(host, port) {
+            @Override public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i1,
+                ByteBuffer byteBuffer) throws SSLException { return null; }
+            @Override public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers,
+                int i, int i1) throws SSLException { return null; }
+            @Override public Runnable getDelegatedTask() { return null; }
+            @Override public void closeInbound() throws SSLException {}
+            @Override public boolean isInboundDone() { return false; }
+            @Override public void closeOutbound() {}
+            @Override public boolean isOutboundDone() { return false; }
+            @Override public String[] getSupportedCipherSuites() { return new String[0]; }
+            @Override public String[] getEnabledCipherSuites() { return new String[0]; }
+            @Override public void setEnabledCipherSuites(String[] strings) {}
+            @Override public String[] getSupportedProtocols() { return new String[0]; }
+            @Override public String[] getEnabledProtocols() { return new String[0]; }
+            @Override public void setEnabledProtocols(String[] strings) {}
+            @Override public SSLSession getSession() { return null; }
+            @Override public void beginHandshake() throws SSLException {}
+            @Override public HandshakeStatus getHandshakeStatus() { return null; }
+            @Override public void setUseClientMode(boolean b) {}
+            @Override public boolean getUseClientMode() { return false; }
+            @Override public void setNeedClientAuth(boolean b) {}
+            @Override public boolean getNeedClientAuth() { return false; }
+            @Override public void setWantClientAuth(boolean b) {}
+            @Override public boolean getWantClientAuth() { return false; }
+            @Override public void setEnableSessionCreation(boolean b) {}
+            @Override public boolean getEnableSessionCreation() { return false; }
+        };
+    }
+
     class HandshakeHandler implements Runnable {
 
         private final SSLEngine engine;
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..c61a13b 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,9 @@
         sss.setEnabledCipherSuites(sss.getSupportedCipherSuites());
         String[] res = sss.getEnabledCipherSuites();
         assertNotNull("NULL result", res);
+        List<String> supported = new ArrayList<>(Arrays.asList(sss.getSupportedCipherSuites()));
         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/SSLSessionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
index 978f20b..fe8a772 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
@@ -91,27 +91,6 @@
     }
 
     /**
-     * javax.net.ssl.SSLSession#getCipherSuite()
-     */
-    public void test_getCipherSuite() {
-        // Identify the expected cipher suite from the expected list of cipher suites enabled by
-        // default.
-        // This test class initializes the server with an RSA key. Thus, only cipher suites that
-        // authenticate the server using RSA are expected to be used.
-        String expectedCipherSuite = null;
-        for (String cipherSuite : StandardNames.CIPHER_SUITES_DEFAULT) {
-            if (cipherSuite.contains("_RSA_")) {
-                expectedCipherSuite = cipherSuite;
-                break;
-            }
-        }
-        if (expectedCipherSuite == null) {
-            fail("Failed to identify expected cipher suite");
-        }
-        assertEquals(expectedCipherSuite, clientSession.getCipherSuite());
-    }
-
-    /**
      * javax.net.ssl.SSLSession#getCreationTime()
      */
     public void test_getCreationTime() {
@@ -184,7 +163,7 @@
      * javax.net.ssl.SSLSession#getProtocol()
      */
     public void test_getProtocol() {
-        assertEquals("TLSv1.2", clientSession.getProtocol());
+        assertEquals("TLSv1.3", clientSession.getProtocol());
     }
 
     /**
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..c23b56b 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,9 @@
         ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
         String[] res = ssl.getEnabledCipherSuites();
         assertNotNull("NULL result", res);
+        List<String> supported = new ArrayList<>(Arrays.asList(ssl.getSupportedCipherSuites()));
         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/json/src/main/java/org/json/JSONArray.java b/json/src/main/java/org/json/JSONArray.java
index 996f449..5e758d7 100644
--- a/json/src/main/java/org/json/JSONArray.java
+++ b/json/src/main/java/org/json/JSONArray.java
@@ -16,6 +16,7 @@
 
 package org.json;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -48,6 +49,7 @@
  */
 public class JSONArray {
 
+    @UnsupportedAppUsage
     private final List<Object> values;
 
     /**
@@ -607,6 +609,7 @@
         return stringer.toString();
     }
 
+    @UnsupportedAppUsage
     void writeTo(JSONStringer stringer) throws JSONException {
         stringer.array();
         for (Object value : values) {
diff --git a/json/src/main/java/org/json/JSONObject.java b/json/src/main/java/org/json/JSONObject.java
index 7902389..0565b25 100644
--- a/json/src/main/java/org/json/JSONObject.java
+++ b/json/src/main/java/org/json/JSONObject.java
@@ -16,6 +16,7 @@
 
 package org.json;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -23,6 +24,8 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
@@ -80,6 +83,7 @@
  */
 public class JSONObject {
 
+    @UnsupportedAppUsage
     private static final Double NEGATIVE_ZERO = -0d;
 
     /**
@@ -97,7 +101,7 @@
      * returning true when compared to {@code null}. Its {@link #toString}
      * method returns "null".
      */
-    public static final Object NULL = new Object() {
+    @NonNull public static final Object NULL = new Object() {
         @Override public boolean equals(Object o) {
             return o == this || o == null; // API specifies this broken equals implementation
         }
@@ -108,6 +112,7 @@
         }
     };
 
+    @UnsupportedAppUsage
     private final LinkedHashMap<String, Object> nameValuePairs;
 
     /**
@@ -126,7 +131,7 @@
      * @throws NullPointerException if any of the map's keys are null.
      */
     /* (accept a raw type for API compatibility) */
-    public JSONObject(Map copyFrom) {
+    public JSONObject(@NonNull Map copyFrom) {
         this();
         Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
         for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
@@ -151,7 +156,7 @@
      * @throws JSONException if the parse fails or doesn't yield a
      *     {@code JSONObject}.
      */
-    public JSONObject(JSONTokener readFrom) throws JSONException {
+    public JSONObject(@NonNull JSONTokener readFrom) throws JSONException {
         /*
          * Getting the parser to populate this could get tricky. Instead, just
          * parse to temporary JSONObject and then steal the data from that.
@@ -172,7 +177,7 @@
      * @throws JSONException if the parse fails or doesn't yield a {@code
      *     JSONObject}.
      */
-    public JSONObject(String json) throws JSONException {
+    public JSONObject(@NonNull String json) throws JSONException {
         this(new JSONTokener(json));
     }
 
@@ -181,7 +186,7 @@
      * from the given object. Names that aren't present in {@code copyFrom} will
      * be skipped.
      */
-    public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
+    public JSONObject(@NonNull JSONObject copyFrom, @NonNull String @NonNull [] names) throws JSONException {
         this();
         for (String name : names) {
             Object value = copyFrom.opt(name);
@@ -204,7 +209,7 @@
      *
      * @return this object.
      */
-    public JSONObject put(String name, boolean value) throws JSONException {
+    @NonNull public JSONObject put(@NonNull String name, boolean value) throws JSONException {
         nameValuePairs.put(checkName(name), value);
         return this;
     }
@@ -217,7 +222,7 @@
      *     {@link Double#isInfinite() infinities}.
      * @return this object.
      */
-    public JSONObject put(String name, double value) throws JSONException {
+    @NonNull public JSONObject put(@NonNull String name, double value) throws JSONException {
         nameValuePairs.put(checkName(name), JSON.checkDouble(value));
         return this;
     }
@@ -228,7 +233,7 @@
      *
      * @return this object.
      */
-    public JSONObject put(String name, int value) throws JSONException {
+    @NonNull public JSONObject put(@NonNull String name, int value) throws JSONException {
         nameValuePairs.put(checkName(name), value);
         return this;
     }
@@ -239,7 +244,7 @@
      *
      * @return this object.
      */
-    public JSONObject put(String name, long value) throws JSONException {
+    @NonNull public JSONObject put(@NonNull String name, long value) throws JSONException {
         nameValuePairs.put(checkName(name), value);
         return this;
     }
@@ -255,7 +260,7 @@
      *     infinities}.
      * @return this object.
      */
-    public JSONObject put(String name, Object value) throws JSONException {
+    @NonNull public JSONObject put(@NonNull String name, @Nullable Object value) throws JSONException {
         if (value == null) {
             nameValuePairs.remove(name);
             return this;
@@ -272,7 +277,7 @@
      * Equivalent to {@code put(name, value)} when both parameters are non-null;
      * does nothing otherwise.
      */
-    public JSONObject putOpt(String name, Object value) throws JSONException {
+    @NonNull public JSONObject putOpt(@Nullable String name, @Nullable Object value) throws JSONException {
         if (name == null || value == null) {
             return this;
         }
@@ -299,7 +304,7 @@
      */
     // TODO: Change {@code append) to {@link #append} when append is
     // unhidden.
-    public JSONObject accumulate(String name, Object value) throws JSONException {
+    @NonNull public JSONObject accumulate(@NonNull String name, @Nullable Object value) throws JSONException {
         Object current = nameValuePairs.get(checkName(name));
         if (current == null) {
             return put(name, value);
@@ -328,6 +333,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public JSONObject append(String name, Object value) throws JSONException {
         Object current = nameValuePairs.get(checkName(name));
 
@@ -347,6 +353,7 @@
         return this;
     }
 
+    @UnsupportedAppUsage
     String checkName(String name) throws JSONException {
         if (name == null) {
             throw new JSONException("Names must be non-null");
@@ -360,7 +367,7 @@
      * @return the value previously mapped by {@code name}, or null if there was
      *     no such mapping.
      */
-    public Object remove(String name) {
+    @Nullable public Object remove(@Nullable String name) {
         return nameValuePairs.remove(name);
     }
 
@@ -368,7 +375,7 @@
      * Returns true if this object has no mapping for {@code name} or if it has
      * a mapping whose value is {@link #NULL}.
      */
-    public boolean isNull(String name) {
+    public boolean isNull(@Nullable String name) {
         Object value = nameValuePairs.get(name);
         return value == null || value == NULL;
     }
@@ -377,7 +384,7 @@
      * Returns true if this object has a mapping for {@code name}. The mapping
      * may be {@link #NULL}.
      */
-    public boolean has(String name) {
+    public boolean has(@Nullable String name) {
         return nameValuePairs.containsKey(name);
     }
 
@@ -386,7 +393,7 @@
      *
      * @throws JSONException if no such mapping exists.
      */
-    public Object get(String name) throws JSONException {
+    @NonNull public Object get(@NonNull String name) throws JSONException {
         Object result = nameValuePairs.get(name);
         if (result == null) {
             throw new JSONException("No value for " + name);
@@ -398,7 +405,7 @@
      * Returns the value mapped by {@code name}, or null if no such mapping
      * exists.
      */
-    public Object opt(String name) {
+    @Nullable public Object opt(@Nullable String name) {
         return nameValuePairs.get(name);
     }
 
@@ -409,7 +416,7 @@
      * @throws JSONException if the mapping doesn't exist or cannot be coerced
      *     to a boolean.
      */
-    public boolean getBoolean(String name) throws JSONException {
+    public boolean getBoolean(@NonNull String name) throws JSONException {
         Object object = get(name);
         Boolean result = JSON.toBoolean(object);
         if (result == null) {
@@ -422,7 +429,7 @@
      * Returns the value mapped by {@code name} if it exists and is a boolean or
      * can be coerced to a boolean, or false otherwise.
      */
-    public boolean optBoolean(String name) {
+    public boolean optBoolean(@Nullable String name) {
         return optBoolean(name, false);
     }
 
@@ -430,7 +437,7 @@
      * Returns the value mapped by {@code name} if it exists and is a boolean or
      * can be coerced to a boolean, or {@code fallback} otherwise.
      */
-    public boolean optBoolean(String name, boolean fallback) {
+    public boolean optBoolean(@Nullable String name, boolean fallback) {
         Object object = opt(name);
         Boolean result = JSON.toBoolean(object);
         return result != null ? result : fallback;
@@ -443,7 +450,7 @@
      * @throws JSONException if the mapping doesn't exist or cannot be coerced
      *     to a double.
      */
-    public double getDouble(String name) throws JSONException {
+    public double getDouble(@NonNull String name) throws JSONException {
         Object object = get(name);
         Double result = JSON.toDouble(object);
         if (result == null) {
@@ -456,7 +463,7 @@
      * Returns the value mapped by {@code name} if it exists and is a double or
      * can be coerced to a double, or {@code NaN} otherwise.
      */
-    public double optDouble(String name) {
+    public double optDouble(@Nullable String name) {
         return optDouble(name, Double.NaN);
     }
 
@@ -464,7 +471,7 @@
      * Returns the value mapped by {@code name} if it exists and is a double or
      * can be coerced to a double, or {@code fallback} otherwise.
      */
-    public double optDouble(String name, double fallback) {
+    public double optDouble(@Nullable String name, double fallback) {
         Object object = opt(name);
         Double result = JSON.toDouble(object);
         return result != null ? result : fallback;
@@ -477,7 +484,7 @@
      * @throws JSONException if the mapping doesn't exist or cannot be coerced
      *     to an int.
      */
-    public int getInt(String name) throws JSONException {
+    public int getInt(@NonNull String name) throws JSONException {
         Object object = get(name);
         Integer result = JSON.toInteger(object);
         if (result == null) {
@@ -490,7 +497,7 @@
      * Returns the value mapped by {@code name} if it exists and is an int or
      * can be coerced to an int, or 0 otherwise.
      */
-    public int optInt(String name) {
+    public int optInt(@Nullable String name) {
         return optInt(name, 0);
     }
 
@@ -498,7 +505,7 @@
      * Returns the value mapped by {@code name} if it exists and is an int or
      * can be coerced to an int, or {@code fallback} otherwise.
      */
-    public int optInt(String name, int fallback) {
+    public int optInt(@Nullable String name, int fallback) {
         Object object = opt(name);
         Integer result = JSON.toInteger(object);
         return result != null ? result : fallback;
@@ -513,7 +520,7 @@
      * @throws JSONException if the mapping doesn't exist or cannot be coerced
      *     to a long.
      */
-    public long getLong(String name) throws JSONException {
+    public long getLong(@NonNull String name) throws JSONException {
         Object object = get(name);
         Long result = JSON.toLong(object);
         if (result == null) {
@@ -527,7 +534,7 @@
      * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
      * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
      */
-    public long optLong(String name) {
+    public long optLong(@Nullable String name) {
         return optLong(name, 0L);
     }
 
@@ -537,7 +544,7 @@
      * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
      * numbers via JSON.
      */
-    public long optLong(String name, long fallback) {
+    public long optLong(@Nullable String name, long fallback) {
         Object object = opt(name);
         Long result = JSON.toLong(object);
         return result != null ? result : fallback;
@@ -549,7 +556,7 @@
      *
      * @throws JSONException if no such mapping exists.
      */
-    public String getString(String name) throws JSONException {
+    @NonNull public String getString(@NonNull String name) throws JSONException {
         Object object = get(name);
         String result = JSON.toString(object);
         if (result == null) {
@@ -562,7 +569,7 @@
      * Returns the value mapped by {@code name} if it exists, coercing it if
      * necessary, or the empty string if no such mapping exists.
      */
-    public String optString(String name) {
+    @NonNull public String optString(@Nullable String name) {
         return optString(name, "");
     }
 
@@ -570,7 +577,7 @@
      * Returns the value mapped by {@code name} if it exists, coercing it if
      * necessary, or {@code fallback} if no such mapping exists.
      */
-    public String optString(String name, String fallback) {
+    @NonNull public String optString(@Nullable String name, @NonNull String fallback) {
         Object object = opt(name);
         String result = JSON.toString(object);
         return result != null ? result : fallback;
@@ -583,7 +590,7 @@
      * @throws JSONException if the mapping doesn't exist or is not a {@code
      *     JSONArray}.
      */
-    public JSONArray getJSONArray(String name) throws JSONException {
+    @NonNull public JSONArray getJSONArray(@NonNull String name) throws JSONException {
         Object object = get(name);
         if (object instanceof JSONArray) {
             return (JSONArray) object;
@@ -596,7 +603,7 @@
      * Returns the value mapped by {@code name} if it exists and is a {@code
      * JSONArray}, or null otherwise.
      */
-    public JSONArray optJSONArray(String name) {
+    @Nullable public JSONArray optJSONArray(@Nullable String name) {
         Object object = opt(name);
         return object instanceof JSONArray ? (JSONArray) object : null;
     }
@@ -608,7 +615,7 @@
      * @throws JSONException if the mapping doesn't exist or is not a {@code
      *     JSONObject}.
      */
-    public JSONObject getJSONObject(String name) throws JSONException {
+    @NonNull public JSONObject getJSONObject(@NonNull String name) throws JSONException {
         Object object = get(name);
         if (object instanceof JSONObject) {
             return (JSONObject) object;
@@ -621,7 +628,7 @@
      * Returns the value mapped by {@code name} if it exists and is a {@code
      * JSONObject}, or null otherwise.
      */
-    public JSONObject optJSONObject(String name) {
+    @Nullable public JSONObject optJSONObject(@Nullable String name) {
         Object object = opt(name);
         return object instanceof JSONObject ? (JSONObject) object : null;
     }
@@ -631,7 +638,7 @@
      * array contains null for names that aren't mapped. This method returns
      * null if {@code names} is either null or empty.
      */
-    public JSONArray toJSONArray(JSONArray names) throws JSONException {
+    @Nullable public JSONArray toJSONArray(@Nullable JSONArray names) throws JSONException {
         JSONArray result = new JSONArray();
         if (names == null) {
             return null;
@@ -654,7 +661,7 @@
      * modified after the iterator is returned, the iterator's behavior is
      * undefined. The order of the keys is undefined.
      */
-    public Iterator<String> keys() {
+    @NonNull public Iterator<@NonNull String> keys() {
         return nameValuePairs.keySet().iterator();
     }
 
@@ -668,6 +675,8 @@
      *
      * @hide.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public Set<String> keySet() {
         return nameValuePairs.keySet();
     }
@@ -676,7 +685,7 @@
      * Returns an array containing the string names in this object. This method
      * returns null if this object contains no mappings.
      */
-    public JSONArray names() {
+    @Nullable public JSONArray names() {
         return nameValuePairs.isEmpty()
                 ? null
                 : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
@@ -686,7 +695,7 @@
      * Encodes this object as a compact JSON string, such as:
      * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
      */
-    @Override public String toString() {
+    @Override @NonNull public String toString() {
         try {
             JSONStringer stringer = new JSONStringer();
             writeTo(stringer);
@@ -711,12 +720,13 @@
      * @param indentSpaces the number of spaces to indent for each level of
      *     nesting.
      */
-    public String toString(int indentSpaces) throws JSONException {
+    @NonNull public String toString(int indentSpaces) throws JSONException {
         JSONStringer stringer = new JSONStringer(indentSpaces);
         writeTo(stringer);
         return stringer.toString();
     }
 
+    @UnsupportedAppUsage
     void writeTo(JSONStringer stringer) throws JSONException {
         stringer.object();
         for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
@@ -731,7 +741,7 @@
      * @param number a finite value. May not be {@link Double#isNaN() NaNs} or
      *     {@link Double#isInfinite() infinities}.
      */
-    public static String numberToString(Number number) throws JSONException {
+    @NonNull public static String numberToString(@NonNull Number number) throws JSONException {
         if (number == null) {
             throw new JSONException("Number must be non-null");
         }
@@ -759,7 +769,7 @@
      * @param data the string to encode. Null will be interpreted as an empty
      *     string.
      */
-    public static String quote(String data) {
+    @NonNull public static String quote(@Nullable String data) {
         if (data == null) {
             return "\"\"";
         }
@@ -786,7 +796,7 @@
      * Otherwise if the object is from a {@code java} package, returns the result of {@code toString}.
      * If wrapping fails, returns null.
      */
-    public static Object wrap(Object o) {
+    @Nullable public static Object wrap(@Nullable Object o) {
         if (o == null) {
             return NULL;
         }
diff --git a/json/src/main/java/org/json/JSONStringer.java b/json/src/main/java/org/json/JSONStringer.java
index dd3b2a7..3d1738c 100644
--- a/json/src/main/java/org/json/JSONStringer.java
+++ b/json/src/main/java/org/json/JSONStringer.java
@@ -16,6 +16,7 @@
 
 package org.json;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -61,6 +62,7 @@
 public class JSONStringer {
 
     /** The output data, containing at most one top-level array or object. */
+    @UnsupportedAppUsage
     final StringBuilder out = new StringBuilder();
 
     /**
@@ -111,18 +113,21 @@
      * Unlike the original implementation, this stack isn't limited to 20
      * levels of nesting.
      */
+    @UnsupportedAppUsage
     private final List<Scope> stack = new ArrayList<Scope>();
 
     /**
      * A string containing a full set of spaces for a single level of
      * indentation, or null for no pretty printing.
      */
+    @UnsupportedAppUsage
     private final String indent;
 
     public JSONStringer() {
         indent = null;
     }
 
+    @UnsupportedAppUsage
     JSONStringer(int indentSpaces) {
         char[] indentChars = new char[indentSpaces];
         Arrays.fill(indentChars, ' ');
@@ -171,6 +176,7 @@
      * Enters a new scope by appending any necessary whitespace and the given
      * bracket.
      */
+    @UnsupportedAppUsage
     JSONStringer open(Scope empty, String openBracket) throws JSONException {
         if (stack.isEmpty() && out.length() > 0) {
             throw new JSONException("Nesting problem: multiple top-level roots");
@@ -185,6 +191,7 @@
      * Closes the current scope by appending any necessary whitespace and the
      * given bracket.
      */
+    @UnsupportedAppUsage
     JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
         Scope context = peek();
         if (context != nonempty && context != empty) {
@@ -202,6 +209,7 @@
     /**
      * Returns the value on the top of the stack.
      */
+    @UnsupportedAppUsage
     private Scope peek() throws JSONException {
         if (stack.isEmpty()) {
             throw new JSONException("Nesting problem");
@@ -212,6 +220,7 @@
     /**
      * Replace the value on the top of the stack with the given value.
      */
+    @UnsupportedAppUsage
     private void replaceTop(Scope topOfStack) {
         stack.set(stack.size() - 1, topOfStack);
     }
@@ -299,6 +308,7 @@
         return this;
     }
 
+    @UnsupportedAppUsage
     private void string(String value) {
         out.append("\"");
         for (int i = 0, length = value.length(); i < length; i++) {
@@ -350,6 +360,7 @@
         out.append("\"");
     }
 
+    @UnsupportedAppUsage
     private void newline() {
         if (indent == null) {
             return;
@@ -380,6 +391,7 @@
      * Inserts any necessary separators and whitespace before a name. Also
      * adjusts the stack to expect the key's value.
      */
+    @UnsupportedAppUsage
     private void beforeKey() throws JSONException {
         Scope context = peek();
         if (context == Scope.NONEMPTY_OBJECT) { // first in object
@@ -396,6 +408,7 @@
      * inline array, or inline object. Also adjusts the stack to expect either a
      * closing bracket or another element.
      */
+    @UnsupportedAppUsage
     private void beforeValue() throws JSONException {
         if (stack.isEmpty()) {
             return;
diff --git a/json/src/main/java/org/json/JSONTokener.java b/json/src/main/java/org/json/JSONTokener.java
index 8caecc8..55667b0 100644
--- a/json/src/main/java/org/json/JSONTokener.java
+++ b/json/src/main/java/org/json/JSONTokener.java
@@ -16,6 +16,8 @@
 
 package org.json;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
@@ -62,12 +64,14 @@
 public class JSONTokener {
 
     /** The input JSON. */
+    @UnsupportedAppUsage
     private final String in;
 
     /**
      * The index of the next character to be returned by {@link #next}. When
      * the input is exhausted, this equals the input's length.
      */
+    @UnsupportedAppUsage
     private int pos;
 
     /**
@@ -112,6 +116,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private int nextCleanInternal() throws JSONException {
         while (pos < in.length()) {
             int c = in.charAt(pos++);
@@ -171,6 +176,7 @@
      * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
      * caller.
      */
+    @UnsupportedAppUsage
     private void skipToEndOfLine() {
         for (; pos < in.length(); pos++) {
             char c = in.charAt(pos);
@@ -234,6 +240,7 @@
      * been read. This supports both unicode escapes "u000A" and two-character
      * escapes "\n".
      */
+    @UnsupportedAppUsage
     private char readEscapeCharacter() throws JSONException {
         char escaped = in.charAt(pos++);
         switch (escaped) {
@@ -277,6 +284,7 @@
      * values will be returned as an Integer, Long, or Double, in that order of
      * preference.
      */
+    @UnsupportedAppUsage
     private Object readLiteral() throws JSONException {
         String literal = nextToInternal("{}[]/\\:,=;# \t\f");
 
@@ -331,6 +339,7 @@
      * Returns the string up to but not including any of the given characters or
      * a newline character. This does not consume the excluded character.
      */
+    @UnsupportedAppUsage
     private String nextToInternal(String excluded) {
         int start = pos;
         for (; pos < in.length(); pos++) {
@@ -346,6 +355,7 @@
      * Reads a sequence of key/value pairs and the trailing closing brace '}' of
      * an object. The opening brace '{' should have already been read.
      */
+    @UnsupportedAppUsage
     private JSONObject readObject() throws JSONException {
         JSONObject result = new JSONObject();
 
@@ -401,6 +411,7 @@
      * "[]" yields an empty array, but "[,]" returns a two-element array
      * equivalent to "[null,null]".
      */
+    @UnsupportedAppUsage
     private JSONArray readArray() throws JSONException {
         JSONArray result = new JSONArray();
 
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/libandroidio.map.txt b/libandroidio.map.txt
new file mode 100644
index 0000000..cb6e879
--- /dev/null
+++ b/libandroidio.map.txt
@@ -0,0 +1,11 @@
+LIBANDROIDIO_1 {
+  global:
+    async_close_monitor_create;
+    async_close_monitor_destroy;
+    async_close_monitor_signal_blocked_threads;
+    async_close_monitor_static_init;
+    async_close_monitor_was_signalled;
+
+  local:
+    *;
+};
diff --git a/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java b/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
index dd9606f..0318c83 100644
--- a/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
+++ b/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
@@ -23,6 +23,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public class AnnotatedStackTraceElement {
     /**
      * The traditional StackTraceElement describing the Java stack frame.
@@ -45,14 +46,17 @@
     private AnnotatedStackTraceElement() {
     }
 
+    @libcore.api.CorePlatformApi
     public StackTraceElement getStackTraceElement() {
         return stackTraceElement;
     }
 
+    @libcore.api.CorePlatformApi
     public Object[] getHeldLocks() {
         return heldLocks;
     }
 
+    @libcore.api.CorePlatformApi
     public Object getBlockedOn() {
         return blockedOn;
     }
diff --git a/libart/src/main/java/dalvik/system/ClassExt.java b/libart/src/main/java/dalvik/system/ClassExt.java
index 9c9fa7a..9180d96 100644
--- a/libart/src/main/java/dalvik/system/ClassExt.java
+++ b/libart/src/main/java/dalvik/system/ClassExt.java
@@ -71,6 +71,31 @@
     private Object verifyError;
 
     /**
+     * If set, native pointer to the initial, pre-redefine, dex file associated with the related
+     * class. This is different from the {@code originalDexFile} which is the pre-retransform dex
+     * file, i.e. could contain the bytes of the dex file provided during redefine.
+     *
+     * It is enough to store the native pointer because the pre-redefine dex file is either part
+     * of boot classpath or it is being kept alive by its class loader. Class loaders always keep
+     * dex files alive even if all their classes have been redefined.
+     *
+     * Needed in order to preserve access to dex-level hiddenapi flags after JVMTI redefine.
+     *
+     * This field is a logical part of the 'Class' type.
+     */
+    private long preRedefineDexFilePtr;
+
+    /**
+     * ClassDef index of the related class in the pre-redefine dex file. Set together with
+     * {@code preRedefineDexFilePtr}.
+     *
+     * Needed in order to preserve access to dex-level hiddenapi flags after JVMTI redefine.
+     *
+     * This field is a logical part of the 'Class' type.
+     */
+    private int preRedefineClassDefIndex;
+
+    /**
     * Private constructor.
     *
     * Only created by the runtime.
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 78001fa..7d70680 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -16,8 +16,10 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 import java.lang.ref.FinalizerReference;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Consumer;
@@ -29,6 +31,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class VMRuntime {
 
     /**
@@ -53,17 +56,98 @@
     }
 
     /**
+     * Interface for logging hidden API usage events.
+     */
+    @libcore.api.CorePlatformApi
+    public interface HiddenApiUsageLogger {
+
+        // The following ACCESS_METHOD_ constants must match the values in
+        // art/runtime/hidden_api.h
+        /**
+         * Internal test value that does not correspond to an actual access by the
+         * application. Never logged, added for completeness.
+         */
+        public static final int ACCESS_METHOD_NONE = 0;
+
+        /**
+         *  Used when a method has been accessed via reflection.
+         */
+        public static final int ACCESS_METHOD_REFLECTION = 1;
+
+        /**
+         *  Used when a method has been accessed via JNI.
+         */
+        public static final int ACCESS_METHOD_JNI = 2;
+
+        /**
+         * Used when a method is accessed at link time. Never logged, added only
+         * for completeness.
+         */
+        public static final int ACCESS_METHOD_LINKING = 3;
+
+        /**
+         * Logs hidden API access
+         *
+         * @param sampledValue value that was sampled, to be compared against the
+         *      sampling rate
+         * @param appPackageName package name of the app attempting the access
+         * @param signature signature of the method being called, i.e
+         *      class_name->member_name:type_signature (e.g.
+         *      {@code com.android.app.Activity->mDoReportFullyDrawn:Z}) for fields and
+         *      class_name->method_name_and_signature for methods (e.g
+         *      {@code com.android.app.Activity->finish(I)V})
+         * @param accessType how the accessed was done
+         * @param accessDenied whether the access was allowed or not
+         */
+        public void hiddenApiUsed(int sampledValue, String appPackageName,
+            String signature, int accessType, boolean accessDenied);
+    }
+
+    static HiddenApiUsageLogger hiddenApiUsageLogger;
+
+    /**
+     * Sets the hidden API usage logger {@link #hiddenApiUsageLogger}.
+     * It should only be called if {@link #setHiddenApiAccessLogSamplingRate(int)}
+     * is called with a value > 0
+     */
+    @libcore.api.CorePlatformApi
+    public static void setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger) {
+        VMRuntime.hiddenApiUsageLogger = hiddenApiUsageLogger;
+    }
+
+    /**
+     * Records an attempted hidden API access to
+     * {@link HiddenApiUsageLogger#hiddenApiUsed(int, String, String, int, boolean}
+     * if a logger is registered via {@link #setHiddenApiUsageLogger}.
+     */
+    private static void hiddenApiUsed(int sampledValue, String appPackageName, String signature,
+         int accessType, boolean accessDenied) {
+        if (VMRuntime.hiddenApiUsageLogger != null) {
+            VMRuntime.hiddenApiUsageLogger.hiddenApiUsed(sampledValue, appPackageName,
+                signature, accessType, accessDenied);
+        }
+    }
+
+    /**
      * Magic version number for a current development build, which has not
      * yet turned into an official release. This number must be larger than
      * any released version in {@code android.os.Build.VERSION_CODES}.
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
 
     private static Consumer<String> nonSdkApiUsageConsumer = null;
 
     private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;
 
+    // notifyNativeAllocationsInternal (below) should be called every notifyNativeInterval
+    // allocations. Initialized on demand to allow completely static class initialization.
+    private int notifyNativeInterval;
+
+    // Allocations since last call to native layer. See notifyNativeAllocation().
+    private final AtomicInteger allocationCount = new AtomicInteger(0);
+
     /**
      * Prevents this class from being instantiated.
      */
@@ -76,6 +160,8 @@
      *
      * @return the runtime object
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static VMRuntime getRuntime() {
         return THE_ONE;
     }
@@ -104,22 +190,29 @@
     /**
      * Returns the name of the shared library providing the VM implementation.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public native String vmLibrary();
 
     /**
      * Returns the VM's instruction set.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public native String vmInstructionSet();
 
     /**
      * Returns whether the VM is running in 64-bit mode.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     @FastNative
     public native boolean is64Bit();
 
     /**
      * Returns whether the VM is running with JNI checking enabled.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public native boolean isCheckJniEnabled();
 
@@ -131,9 +224,17 @@
      *
      * @return the current ideal heap utilization
      */
+    @libcore.api.CorePlatformApi
     public native float getTargetHeapUtilization();
 
     /**
+     * Retrieves the finalizer timeout in milliseconds.
+     * Finalizers that fail to terminate in this amount of time cause the
+     * runtime to abort.
+     */
+    public native long getFinalizerTimeoutMs();
+
+    /**
      * Sets the current ideal heap utilization, represented as a number
      * between zero and one.  After a GC happens, the Dalvik heap may
      * be resized so that (size of live objects) / (size of heap) is
@@ -146,14 +247,18 @@
      * @return the previous ideal heap utilization
      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public float setTargetHeapUtilization(float newTarget) {
         if (newTarget <= 0.0f || newTarget >= 1.0f) {
-            throw new IllegalArgumentException(newTarget +
-                    " out of range (0,1)");
+            throw new IllegalArgumentException(newTarget + " out of range (0,1)");
         }
-        /* Synchronize to make sure that only one thread gets
-         * a given "old" value if both update at the same time.
-         * Allows for reliable save-and-restore semantics.
+        /* The native code assumes a value >= 0.1. Clamp it to that. */
+        if (newTarget < 0.1f) {
+            newTarget = 0.1f;
+        }
+        /* Synchronize to make sure that only one thread gets a given "old" value if both
+         * update at the same time.  Allows for reliable save-and-restore semantics.
          */
         synchronized (this) {
             float oldTarget = getTargetHeapUtilization();
@@ -167,6 +272,7 @@
      * app starts to run, because it may change the VM's behavior in
      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
      */
+    @libcore.api.CorePlatformApi
     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
         this.targetSdkVersion = targetSdkVersion;
         setTargetSdkVersionNative(this.targetSdkVersion);
@@ -176,6 +282,7 @@
      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
      * special values.
      */
+    @libcore.api.CorePlatformApi
     public synchronized int getTargetSdkVersion() {
         return targetSdkVersion;
     }
@@ -186,6 +293,7 @@
      * This method exists for binary compatibility.  It was part of a
      * heap sizing API which was removed in Android 3.0 (Honeycomb).
      */
+    @UnsupportedAppUsage
     @Deprecated
     public long getMinimumHeapSize() {
         return 0;
@@ -195,6 +303,7 @@
      * This method exists for binary compatibility.  It was part of a
      * heap sizing API which was removed in Android 3.0 (Honeycomb).
      */
+    @UnsupportedAppUsage
     @Deprecated
     public long setMinimumHeapSize(long size) {
         return 0;
@@ -204,6 +313,7 @@
      * This method exists for binary compatibility.  It used to
      * perform a garbage collection that cleared SoftReferences.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void gcSoftReferences() {}
 
@@ -211,6 +321,7 @@
      * This method exists for binary compatibility.  It is equivalent
      * to {@link System#runFinalization}.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void runFinalizationSync() {
         System.runFinalization();
@@ -228,6 +339,7 @@
      * This method exists for binary compatibility.  It was part of
      * the external allocation API which was removed in Android 3.0 (Honeycomb).
      */
+    @UnsupportedAppUsage
     @Deprecated
     public boolean trackExternalAllocation(long size) {
         return true;
@@ -237,6 +349,7 @@
      * This method exists for binary compatibility.  It was part of
      * the external allocation API which was removed in Android 3.0 (Honeycomb).
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void trackExternalFree(long size) {}
 
@@ -244,6 +357,7 @@
      * This method exists for binary compatibility.  It was part of
      * the external allocation API which was removed in Android 3.0 (Honeycomb).
      */
+    @UnsupportedAppUsage
     @Deprecated
     public long getExternalBytesAllocated() {
         return 0;
@@ -253,21 +367,17 @@
      * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
      * implementation, calling this method should have no effect.
      */
+    @libcore.api.CorePlatformApi
     public native void startJitCompilation();
 
     /**
      * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
      * implementation, calling this method should have no effect.
      */
+    @libcore.api.CorePlatformApi
     public native void disableJitCompilation();
 
     /**
-     * Returns true if the app has accessed a hidden API. This does not include
-     * attempts which have been blocked.
-     */
-    public native boolean hasUsedHiddenApi();
-
-    /**
      * Sets the list of exemptions from hidden API access enforcement.
      *
      * @param signaturePrefixes
@@ -275,6 +385,7 @@
      *         signature of a blacklisted API. All matching APIs are treated as if they were on
      *         the whitelist: access permitted, and no logging..
      */
+    @libcore.api.CorePlatformApi
     public native void setHiddenApiExemptions(String[] signaturePrefixes);
 
     /**
@@ -283,6 +394,7 @@
      * @param rate Proportion of hidden API accesses that will be logged; an integer between
      *                0 and 0x10000 inclusive.
      */
+    @libcore.api.CorePlatformApi
     public native void setHiddenApiAccessLogSamplingRate(int rate);
 
     /**
@@ -290,6 +402,8 @@
      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
      * and Bitmaps.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     @FastNative
     public native Object newNonMovableArray(Class<?> componentType, int length);
 
@@ -298,6 +412,7 @@
      * avoiding any padding after the array. The amount of padding varies depending on the
      * componentType and the memory allocator implementation.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
 
@@ -305,6 +420,8 @@
      * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
      * give you the address of a copy of the array when in forcecopy mode.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     @FastNative
     public native long addressOf(Object array);
 
@@ -312,12 +429,15 @@
      * Removes any growth limits, allowing the application to allocate
      * up to the maximum heap size.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public native void clearGrowthLimit();
 
     /**
      * Make the current growth limit the new non growth limit capacity by releasing pages which
      * are after the growth limit but before the non growth limit capacity.
      */
+    @libcore.api.CorePlatformApi
     public native void clampGrowthLimit();
 
     /**
@@ -329,6 +449,7 @@
     /**
      * Returns true if native debugging is on.
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     public native boolean isNativeDebuggable();
 
@@ -343,14 +464,77 @@
      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
      * watermark, it is determined that the application is registering native allocations at an
      * unusually high rate and a GC is performed inside of the function to prevent memory usage
-     * from excessively increasing.
+     * from excessively increasing. Memory allocated via system malloc() should not be included
+     * in this count. The argument must be the same as that later passed to registerNativeFree(),
+     * but may otherwise be approximate.
      */
-    public native void registerNativeAllocation(int bytes);
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public native void registerNativeAllocation(long bytes);
+
+    /**
+     * Backward compatibility version of registerNativeAllocation. We used to pass an int instead
+     * of a long. The RenderScript support library looks it up via reflection.
+     * @deprecated Use long argument instead.
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    @libcore.api.CorePlatformApi
+    public void registerNativeAllocation(int bytes) {
+        registerNativeAllocation((long) bytes);
+    }
 
     /**
      * Registers a native free by reducing the number of native bytes accounted for.
      */
-    public native void registerNativeFree(int bytes);
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public native void registerNativeFree(long bytes);
+
+    /**
+     * Backward compatibility version of registerNativeFree.
+     * @deprecated Use long argument instead.
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    @libcore.api.CorePlatformApi
+    public void registerNativeFree(int bytes) {
+        registerNativeFree((long) bytes);
+    }
+
+    /**
+     * Return the number of native objects that are reported by a single call to
+     * notifyNativeAllocation().
+     */
+    private static native int getNotifyNativeInterval();
+
+    /**
+     * Report a native malloc()-only allocation to the GC.
+     */
+    public void notifyNativeAllocation() {
+        // Minimize JNI calls by notifying once every notifyNativeInterval allocations.
+        // The native code cannot do anything without calling mallinfo(), which is too
+        // expensive to perform on every allocation. To avoid the JNI overhead on every
+        // allocation, we do the sampling here, rather than in native code.
+        // Initialize notifyNativeInterval carefully. Multiple initializations may race.
+        int myNotifyNativeInterval = notifyNativeInterval;
+        if (myNotifyNativeInterval == 0) {
+            // This can race. By Java rules, that's OK.
+            myNotifyNativeInterval = notifyNativeInterval = getNotifyNativeInterval();
+        }
+        // myNotifyNativeInterval is correct here. If another thread won the initial race,
+        // notifyNativeInterval may not be.
+        if (allocationCount.addAndGet(1) % myNotifyNativeInterval == 0) {
+            notifyNativeAllocationsInternal();
+        }
+    }
+
+    /**
+     * Report to the GC that roughly notifyNativeInterval native malloc()-based
+     * allocations have occurred since the last call to notifyNativeAllocationsInternal().
+     * Hints that we should check whether a GC is required.
+     */
+    public native void notifyNativeAllocationsInternal();
 
     /**
      * Wait for objects to be finalized.
@@ -366,6 +550,7 @@
      * @see #Runtime.runFinalization()
      * @see #wait(long,int)
      */
+    @UnsupportedAppUsage
     public static void runFinalization(long timeout) {
         try {
             FinalizerReference.finalizeAllEnqueued(timeout);
@@ -376,6 +561,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public native void requestConcurrentGC();
     public native void concurrentGC();
     public native void requestHeapTrim();
@@ -388,12 +574,21 @@
      * Let the heap know of the new process state. This can change allocation and garbage collection
      * behavior regarding trimming and compaction.
      */
+    @libcore.api.CorePlatformApi
     public native void updateProcessState(int state);
 
     /**
+     * Let the runtime know that the application startup is completed. This may affect behavior
+     * related to profiling and startup caches.
+     */
+    @libcore.api.CorePlatformApi
+    public native void notifyStartupCompleted();
+
+    /**
      * Fill in dex caches with classes, fields, and methods that are
      * already loaded. Typically used after Zygote preloading.
      */
+    @libcore.api.CorePlatformApi
     public native void preloadDexCaches();
 
     /**
@@ -401,6 +596,7 @@
      * @param profileFile the path of the file where the profile information should be stored.
      * @param codePaths the code paths that should be profiled.
      */
+    @libcore.api.CorePlatformApi
     public static native void registerAppInfo(String profileFile, String[] codePaths);
 
     /**
@@ -410,6 +606,8 @@
      *
      * This influences the compilation of the applications classes.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static String getInstructionSet(String abi) {
         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
         if (instructionSet == null) {
@@ -419,12 +617,15 @@
         return instructionSet;
     }
 
+    @libcore.api.CorePlatformApi
     public static boolean is64BitInstructionSet(String instructionSet) {
         return "arm64".equals(instructionSet) ||
                 "x86_64".equals(instructionSet) ||
                 "mips64".equals(instructionSet);
     }
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static boolean is64BitAbi(String abi) {
         return is64BitInstructionSet(getInstructionSet(abi));
     }
@@ -434,11 +635,24 @@
      * set mapped from disk storage, versus being interpretted from
      * dirty pages in memory.
      */
+    @libcore.api.CorePlatformApi
     public static native boolean isBootClassPathOnDisk(String instructionSet);
 
     /**
+     * Returns whether the runtime is using a boot image.
+     *
+     * <p>While isBootClassPathOnDisk checks for the existence of an image file on disk,
+     * this method queries the runtime whether it is <em>using</em> an image.
+     */
+    @libcore.api.CorePlatformApi
+    @FastNative
+    public static native boolean hasBootImageSpaces();
+
+    /**
      * Returns the instruction set of the current runtime.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static native String getCurrentInstructionSet();
 
     /**
@@ -446,12 +660,14 @@
      * various reasons, e.g., after an OTA. The return value is for the current instruction
      * set.
      */
+    @libcore.api.CorePlatformApi
     public static native boolean didPruneDalvikCache();
 
     /**
      * Register the current execution thread to the runtime as sensitive thread.
      * Should be called just once. Subsequent calls are ignored.
      */
+    @libcore.api.CorePlatformApi
     public static native void registerSensitiveThread();
 
     /**
@@ -462,6 +678,7 @@
     /**
      * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
      */
+    @libcore.api.CorePlatformApi
     public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
         nonSdkApiUsageConsumer = consumer;
     }
@@ -471,10 +688,18 @@
      * If deduping is enabled, only the first usage of each API will be detected. The default
      * behaviour is to dedupe.
      */
+    @libcore.api.CorePlatformApi
     public static native void setDedupeHiddenApiWarnings(boolean dedupe);
 
     /**
      * Sets the package name of the app running in this process.
      */
+    @libcore.api.CorePlatformApi
     public static native void setProcessPackageName(String packageName);
+
+    /**
+     * Sets the full path to data directory of the app running in this process.
+     */
+    @libcore.api.CorePlatformApi
+    public static native void setProcessDataDirectory(String dataDir);
 }
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
index ca29579..d84fef6 100644
--- a/libart/src/main/java/dalvik/system/VMStack.java
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -16,6 +16,7 @@
 
 package dalvik.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 
 /**
@@ -24,21 +25,33 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class VMStack {
+
+    private VMStack() {
+    }
+
     /**
      * Returns the defining class loader of the caller's caller.
      *
      * @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.
      */
+    @UnsupportedAppUsage
     @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();
     }
@@ -48,6 +61,7 @@
      *
      * @return the requested class, or {@code null}.
      */
+    @UnsupportedAppUsage
     @FastNative
     native public static Class<?> getStackClass2();
 
@@ -66,6 +80,7 @@
      * @return an array of stack trace elements, or null if the thread
      *      doesn't have a stack trace (e.g. because it exited)
      */
+    @UnsupportedAppUsage
     @FastNative
     native public static StackTraceElement[] getThreadStackTrace(Thread t);
 
@@ -77,6 +92,7 @@
      * @return an array of annotated stack frames, or null if the thread
      *      doesn't have a stack trace (e.g. because it exited)
      */
+    @libcore.api.CorePlatformApi
     @FastNative
     native public static AnnotatedStackTraceElement[]
             getAnnotatedThreadStackTrace(Thread t);
@@ -92,6 +108,7 @@
      *      desired. Unused elements will be filled with null values.
      * @return the number of elements filled
      */
+    @UnsupportedAppUsage
     @FastNative
     native public static int fillStackTraceElements(Thread t,
         StackTraceElement[] stackTraceElements);
diff --git a/libart/src/main/java/java/lang/AndroidHardcodedSystemProperties.java b/libart/src/main/java/java/lang/AndroidHardcodedSystemProperties.java
index 87c3096..931994f 100644
--- a/libart/src/main/java/java/lang/AndroidHardcodedSystemProperties.java
+++ b/libart/src/main/java/java/lang/AndroidHardcodedSystemProperties.java
@@ -96,10 +96,6 @@
         { "http.keepAliveDuration", null },
         { "http.maxConnections", null },
 
-        // Hardcode "os.name" to "Linux." Aids compile-time initialization, checked in System.
-        // b/28174137
-        { "os.name", "Linux" },
-
         // Turn off javax.net debugging. This allows compile-time initialization of a range
         // of classes. b/28174137
         { "javax.net.debug", null },
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index f25c78c..7d0eca2 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -18,12 +18,14 @@
 
 import android.system.Os;
 import android.system.OsConstants;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.system.VMRuntime;
 import java.lang.ref.FinalizerReference;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeoutException;
 import libcore.util.EmptyArray;
 
@@ -36,28 +38,54 @@
  */
 public final class Daemons {
     private static final int NANOS_PER_MILLI = 1000 * 1000;
-    private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
-    private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;
 
+    // This used to be final. IT IS NOW ONLY WRITTEN. We now update it when we look at the command
+    // line argument, for the benefit of mis-behaved apps that might read it.  SLATED FOR REMOVAL.
+    // There is no reason to use this: Finalizers should not rely on the value. If a finalizer takes
+    // appreciable time, the work should be done elsewhere.  Based on disassembly of Daemons.class,
+    // the value is effectively inlined, so changing the field never did have an effect.
+    // DO NOT USE. FOR ANYTHING. THIS WILL BE REMOVED SHORTLY.
+    @UnsupportedAppUsage
+    private static long MAX_FINALIZE_NANOS = 10L * 1000 * NANOS_PER_MILLI;
+
+    private static final Daemon[] DAEMONS = new Daemon[] {
+            HeapTaskDaemon.INSTANCE,
+            ReferenceQueueDaemon.INSTANCE,
+            FinalizerDaemon.INSTANCE,
+            FinalizerWatchdogDaemon.INSTANCE,
+    };
+    private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+    private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+
+    private static boolean postZygoteFork = false;
+
+    @UnsupportedAppUsage
     public static void start() {
-        ReferenceQueueDaemon.INSTANCE.start();
-        FinalizerDaemon.INSTANCE.start();
-        FinalizerWatchdogDaemon.INSTANCE.start();
-        HeapTaskDaemon.INSTANCE.start();
+        for (Daemon daemon : DAEMONS) {
+            daemon.start();
+        }
     }
 
     public static void startPostZygoteFork() {
-        ReferenceQueueDaemon.INSTANCE.startPostZygoteFork();
-        FinalizerDaemon.INSTANCE.startPostZygoteFork();
-        FinalizerWatchdogDaemon.INSTANCE.startPostZygoteFork();
-        HeapTaskDaemon.INSTANCE.startPostZygoteFork();
+        postZygoteFork = true;
+        for (Daemon daemon : DAEMONS) {
+            daemon.startPostZygoteFork();
+        }
     }
 
+    @UnsupportedAppUsage
     public static void stop() {
-        HeapTaskDaemon.INSTANCE.stop();
-        ReferenceQueueDaemon.INSTANCE.stop();
-        FinalizerDaemon.INSTANCE.stop();
-        FinalizerWatchdogDaemon.INSTANCE.stop();
+        for (Daemon daemon : DAEMONS) {
+            daemon.stop();
+        }
+    }
+
+    private static void waitForDaemonStart() throws Exception {
+        if (postZygoteFork) {
+            POST_ZYGOTE_START_LATCH.await();
+        } else {
+            PRE_ZYGOTE_START_LATCH.await();
+        }
     }
 
     /**
@@ -66,6 +94,7 @@
      * single-threaded process when it forks.
      */
     private static abstract class Daemon implements Runnable {
+        @UnsupportedAppUsage
         private Thread thread;
         private String name;
         private boolean postZygoteFork;
@@ -74,6 +103,7 @@
             this.name = name;
         }
 
+        @UnsupportedAppUsage
         public synchronized void start() {
             startInternal();
         }
@@ -89,16 +119,20 @@
             }
             thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
             thread.setDaemon(true);
+            thread.setSystemDaemon(true);
             thread.start();
         }
 
-        public void run() {
+        public final void run() {
             if (postZygoteFork) {
                 // We don't set the priority before the Thread.start() call above because
                 // Thread.start() will call SetNativePriority and overwrite the desired native
                 // priority. We (may) use a native priority that doesn't have a corresponding
                 // java.lang.Thread-level priority (native priorities are more coarse-grained.)
                 VMRuntime.getRuntime().setSystemDaemonThreadPriority();
+                POST_ZYGOTE_START_LATCH.countDown();
+            } else {
+                PRE_ZYGOTE_START_LATCH.countDown();
             }
             runInternal();
         }
@@ -109,6 +143,7 @@
          * Returns true while the current thread should continue to run; false
          * when it should return.
          */
+        @UnsupportedAppUsage
         protected synchronized boolean isRunning() {
             return thread != null;
         }
@@ -128,6 +163,7 @@
          * Waits for the runtime thread to stop. This interrupts the thread
          * currently running the runnable and then waits for it to exit.
          */
+        @UnsupportedAppUsage
         public void stop() {
             Thread threadToStop;
             synchronized (this) {
@@ -163,6 +199,7 @@
      * pending list to the managed reference queue.
      */
     private static class ReferenceQueueDaemon extends Daemon {
+        @UnsupportedAppUsage
         private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
 
         ReferenceQueueDaemon() {
@@ -191,10 +228,12 @@
     }
 
     private static class FinalizerDaemon extends Daemon {
+        @UnsupportedAppUsage
         private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
         private final ReferenceQueue<Object> queue = FinalizerReference.queue;
         private final AtomicInteger progressCounter = new AtomicInteger(0);
         // Object (not reference!) being finalized. Accesses may race!
+        @UnsupportedAppUsage
         private Object finalizingObject = null;
 
         FinalizerDaemon() {
@@ -264,10 +303,13 @@
      * on one instance.
      */
     private static class FinalizerWatchdogDaemon extends Daemon {
+        @UnsupportedAppUsage
         private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
 
         private boolean needToWork = true;  // Only accessed in synchronized methods.
 
+        private long finalizerTimeoutMs = 0;  // Lazily initialized.
+
         FinalizerWatchdogDaemon() {
             super("FinalizerWatchdogDaemon");
         }
@@ -326,20 +368,19 @@
         }
 
         /**
-         * Sleep for the given number of nanoseconds.
+         * Sleep for the given number of milliseconds.
          * @return false if we were interrupted.
          */
-        private boolean sleepFor(long durationNanos) {
-            long startNanos = System.nanoTime();
+        private boolean sleepForMillis(long durationMillis) {
+            long startMillis = System.currentTimeMillis();
             while (true) {
-                long elapsedNanos = System.nanoTime() - startNanos;
-                long sleepNanos = durationNanos - elapsedNanos;
-                long sleepMills = sleepNanos / NANOS_PER_MILLI;
-                if (sleepMills <= 0) {
+                long elapsedMillis = System.currentTimeMillis() - startMillis;
+                long sleepMillis = durationMillis - elapsedMillis;
+                if (sleepMillis <= 0) {
                     return true;
                 }
                 try {
-                    Thread.sleep(sleepMills);
+                    Thread.sleep(sleepMillis);
                 } catch (InterruptedException e) {
                     if (!isRunning()) {
                         return false;
@@ -355,19 +396,25 @@
 
         /**
          * Return an object that took too long to finalize or return null.
-         * Wait MAX_FINALIZE_NANOS.  If the FinalizerDaemon took essentially the whole time
-         * processing a single reference, return that reference.  Otherwise return null.
+         * Wait VMRuntime.getFinalizerTimeoutMs.  If the FinalizerDaemon took essentially the
+         * whole time processing a single reference, return that reference.  Otherwise return
+         * null.  Only called from a single thread.
          */
         private Object waitForFinalization() {
+            if (finalizerTimeoutMs == 0) {
+                finalizerTimeoutMs = VMRuntime.getRuntime().getFinalizerTimeoutMs();
+                // Temporary app backward compatibility. Remove eventually.
+                MAX_FINALIZE_NANOS = NANOS_PER_MILLI * finalizerTimeoutMs;
+            }
             long startCount = FinalizerDaemon.INSTANCE.progressCounter.get();
             // Avoid remembering object being finalized, so as not to keep it alive.
-            if (!sleepFor(MAX_FINALIZE_NANOS)) {
+            if (!sleepForMillis(finalizerTimeoutMs)) {
                 // Don't report possibly spurious timeout if we are interrupted.
                 return null;
             }
             if (getNeedToWork() && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
                 // We assume that only remove() and doFinalize() may take time comparable to
-                // MAX_FINALIZE_NANOS.
+                // the finalizer timeout.
                 // We observed neither the effect of the gotoSleep() nor the increment preceding a
                 // later wakeUp. Any remove() call by the FinalizerDaemon during our sleep
                 // interval must have been followed by a wakeUp call before we checked needToWork.
@@ -375,14 +422,14 @@
                 // been such a remove() call.
                 // The FinalizerDaemon must not have progressed (from either the beginning or the
                 // last progressCounter increment) to either the next increment or gotoSleep()
-                // call.  Thus we must have taken essentially the whole MAX_FINALIZE_NANOS in a
+                // call.  Thus we must have taken essentially the whole finalizerTimeoutMs in a
                 // single doFinalize() call.  Thus it's OK to time out.  finalizingObject was set
                 // just before the counter increment, which preceded the doFinalize call.  Thus we
                 // are guaranteed to get the correct finalizing value below, unless doFinalize()
                 // just finished as we were timing out, in which case we may get null or a later
                 // one.  In this last case, we are very likely to discard it below.
                 Object finalizing = FinalizerDaemon.INSTANCE.finalizingObject;
-                sleepFor(NANOS_PER_SECOND / 2);
+                sleepForMillis(500);
                 // Recheck to make it even less likely we report the wrong finalizing object in
                 // the case which a very slow finalization just finished as we were timing out.
                 if (getNeedToWork()
@@ -396,7 +443,7 @@
         private static void finalizerTimedOut(Object object) {
             // The current object has exceeded the finalization deadline; abort!
             String message = object.getClass().getName() + ".finalize() timed out after "
-                    + (MAX_FINALIZE_NANOS / NANOS_PER_SECOND) + " seconds";
+                    + VMRuntime.getRuntime().getFinalizerTimeoutMs() / 1000 + " seconds";
             Exception syntheticException = new TimeoutException(message);
             // We use the stack from where finalize() was running to show where it was stuck.
             syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
@@ -439,6 +486,7 @@
 
     // Adds a heap trim task to the heap event processor, not called from java. Left for
     // compatibility purposes due to reflection.
+    @UnsupportedAppUsage
     public static void requestHeapTrim() {
         VMRuntime.getRuntime().requestHeapTrim();
     }
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 864196d..7c4a6ed 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -32,6 +32,7 @@
 
 package java.lang;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 
 /**
@@ -42,9 +43,15 @@
     private String location;
 
     /** Holds C pointer to dexFile. */
+    @UnsupportedAppUsage
     private long dexFile;
 
     /**
+     * References to pre resolved strings.
+     */
+    private long preResolvedStrings;
+
+    /**
      * References to CallSite (C array pointer) as they become resolved following
      * interpreter semantics.
      */
@@ -81,6 +88,11 @@
     private long strings;
 
     /**
+     * The number of elements in the native pre resolved strings array.
+     */
+    private int numPreResolvedStrings;
+
+    /**
      * The number of elements in the native call sites array.
      */
     private int numResolvedCallSites;
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/ErrnoException.java b/luni/src/main/java/android/system/ErrnoException.java
index e60ac8f..02a529f 100644
--- a/luni/src/main/java/android/system/ErrnoException.java
+++ b/luni/src/main/java/android/system/ErrnoException.java
@@ -67,6 +67,7 @@
     /**
      * @hide - internal use only.
      */
+    @libcore.api.CorePlatformApi
     public IOException rethrowAsIOException() throws IOException {
         IOException newException = new IOException(getMessage());
         newException.initCause(this);
@@ -76,6 +77,8 @@
     /**
      * @hide - internal use only.
      */
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public SocketException rethrowAsSocketException() throws SocketException {
         throw new SocketException(getMessage(), this);
     }
diff --git a/luni/src/main/java/android/system/Int32Ref.java b/luni/src/main/java/android/system/Int32Ref.java
index 9f8bbe5..8f4a949 100644
--- a/luni/src/main/java/android/system/Int32Ref.java
+++ b/luni/src/main/java/android/system/Int32Ref.java
@@ -16,13 +16,19 @@
 
 package android.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * @hide
  * A signed 32bit integer reference suitable for passing to lower-level system calls.
  */
+@libcore.api.CorePlatformApi
 public class Int32Ref {
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public int value;
 
+    @libcore.api.CorePlatformApi
     public Int32Ref(int value) {
         this.value = value;
     }
diff --git a/luni/src/main/java/android/system/NetlinkSocketAddress.java b/luni/src/main/java/android/system/NetlinkSocketAddress.java
index af78cd0..64b0eab 100644
--- a/luni/src/main/java/android/system/NetlinkSocketAddress.java
+++ b/luni/src/main/java/android/system/NetlinkSocketAddress.java
@@ -16,6 +16,7 @@
 
 package android.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import libcore.util.Objects;
 import java.net.SocketAddress;
 
@@ -27,6 +28,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class NetlinkSocketAddress extends SocketAddress {
     /** port ID */
     private final int nlPortId;
@@ -42,15 +44,19 @@
         this(nlPortId, 0);
     }
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public NetlinkSocketAddress(int nlPortId, int nlGroupsMask) {
         this.nlPortId = nlPortId;
         this.nlGroupsMask = nlGroupsMask;
     }
 
+    @libcore.api.CorePlatformApi
     public int getPortId() {
         return nlPortId;
     }
 
+    @libcore.api.CorePlatformApi
     public int getGroupsMask() {
         return nlGroupsMask;
     }
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index 6301ff9..ded3b1c 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -16,6 +16,12 @@
 
 package android.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+import libcore.io.Libcore;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
@@ -23,7 +29,6 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
-import libcore.io.Libcore;
 
 /**
  * Access to low-level system functionality. Most of these are system calls. Most users will want
@@ -35,13 +40,15 @@
 public final class Os {
     private Os() {}
 
+    // Ideally we'd just have the version that accepts SocketAddress but we're stuck with
+    // this one for legacy reasons. http://b/123568439
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/accept.2.html">accept(2)</a>.
      */
-    public static FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return Libcore.os.accept(fd, peerAddress); }
+    public static FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return accept(fd, (SocketAddress) peerAddress); }
 
     /**
-     * TODO Change the public API by removing the overload above and unhiding this version.
+     * See <a href="http://man7.org/linux/man-pages/man2/accept.2.html">accept(2)</a>.
      * @hide
      */
     public static FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { return Libcore.os.accept(fd, peerAddress); }
@@ -51,20 +58,25 @@
      */
     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); }
+    /**
+     * See <a href="http://man7.org/linux/man-pages/man2/bind.2.html">bind(2)</a>.
+     */
+    public static void bind(@NonNull FileDescriptor fd, @NonNull 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>.
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
         return Libcore.os.capget(hdr);
     }
@@ -74,6 +86,7 @@
      *
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static void capset(StructCapUserHeader hdr, StructCapUserData[] data)
             throws ErrnoException {
         Libcore.os.capset(hdr, data);
@@ -99,7 +112,10 @@
      */
     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); }
+    /**
+     * See <a href="http://man7.org/linux/man-pages/man2/connect.2.html">connect(2)</a>.
+     */
+    public static void connect(@NonNull FileDescriptor fd, @NonNull 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 +152,15 @@
      */
     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 */
+    @libcore.api.CorePlatformApi
+    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 +214,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 +228,10 @@
 
     /**
      * 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); }
+    @libcore.api.CorePlatformApi
+    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 +243,46 @@
      */
     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 */
+    @libcore.api.CorePlatformApi
+    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 */
+    @libcore.api.CorePlatformApi
+    public static int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptInt(fd, level, option); }
+
+    /** @hide */
+    @libcore.api.CorePlatformApi
+    public static StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException { return Libcore.os.getsockoptLinger(fd, level, option); }
+
+    /**
+     * See <a href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">getsockopt(2)</a>.
+     *
+     * <p>Only for use with {@code option} values that return a {@code struct timeval} such as
+     * {@link OsConstants#SO_RCVTIMEO} and {@link OsConstants#SO_SNDTIMEO}. Use with other
+     * options may throw an {@code IllegalArgumentException} or return junk values.
+     */
+    public static @NonNull StructTimeval getsockoptTimeval(@NonNull 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 +314,13 @@
      */
     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 */
+    @libcore.api.CorePlatformApi
+    public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
         return Libcore.os.ioctlInt(fd, cmd, arg);
     }
 
@@ -362,7 +414,9 @@
      */
     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 */
+    @libcore.api.CorePlatformApi
+    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 +474,10 @@
 
     /**
      * 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); }
+    @libcore.api.CorePlatformApi
+    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>.
@@ -473,11 +529,13 @@
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
      */
-    /** @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(@NonNull FileDescriptor fd, @NonNull byte[] bytes, int byteOffset, int byteCount, int flags, @Nullable 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>.
+     * @deprecated Android Applications do not have sufficient privileges to call this method.
      */
+    @Deprecated
     public static void setegid(int egid) throws ErrnoException { Libcore.os.setegid(egid); }
 
     /**
@@ -487,50 +545,81 @@
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/seteuid.2.html">seteuid(2)</a>.
+     * @deprecated Android Applications do not have sufficient privileges to call this method.
      */
+    @Deprecated
     public static void seteuid(int euid) throws ErrnoException { Libcore.os.seteuid(euid); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/setgid.2.html">setgid(2)</a>.
+     * @deprecated Android Applications do not have sufficient privileges to call this method.
      */
+    @Deprecated
     public static void setgid(int gid) throws ErrnoException { Libcore.os.setgid(gid); }
 
     /**
      * 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); }
+    @libcore.api.CorePlatformApi
+    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); }
+    @libcore.api.CorePlatformApi
+    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); }
+    @libcore.api.CorePlatformApi
+    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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 */
+    @libcore.api.CorePlatformApi
+    public static void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { Libcore.os.setsockoptLinger(fd, level, option, value); }
+
+    /**
+     * See <a href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">setsockopt(2)</a>.
+     *
+     * <p>Only for use with {@code option} values that take a {@code struct timeval} such as
+     * {@link OsConstants#SO_RCVTIMEO} and {@link OsConstants#SO_SNDTIMEO}. Use with other
+     * options is likely to cause incorrect behavior.
+     */
+    public static void setsockoptTimeval(@NonNull FileDescriptor fd, int level, int option, @NonNull 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>.
+     * @deprecated Android Applications do not have sufficient privileges to call this method.
      */
+    @Deprecated
     public static void setuid(int uid) throws ErrnoException { Libcore.os.setuid(uid); }
 
     /**
@@ -557,6 +646,7 @@
      * See <a href="http://man7.org/linux/man-pages/man2/splice.2.html">splice(2)</a>.
      * @hide
      */
+    @libcore.api.CorePlatformApi
     public static long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException { return Libcore.os.splice(fdIn, offIn, fdOut, offOut, len, flags); }
 
     /**
@@ -612,6 +702,7 @@
     /**
      * @hide See <a href="http://man7.org/linux/man-pages/man2/unlink.2.html">unlink(2)</a>.
      */
+    @libcore.api.CorePlatformApi
     public static void unlink(String pathname) throws ErrnoException { Libcore.os.unlink(pathname); }
 
     /**
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1b8c2ff..a119ec7 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -16,10 +16,13 @@
 
 package android.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * Constants and helper functions for use with {@link Os}.
  */
 public final class OsConstants {
+    @UnsupportedAppUsage
     private OsConstants() {
     }
 
@@ -28,6 +31,8 @@
      * in.
      * @hide
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static int CAP_TO_INDEX(int x) { return x >>> 5; }
 
     /**
@@ -35,6 +40,8 @@
      * element, the index of which can be retrieved with CAP_TO_INDEX.
      * @hide
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static int CAP_TO_MASK(int x) { return 1 << (x & 31); }
 
     /**
@@ -109,8 +116,8 @@
 
     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();
+    public static final int AF_NETLINK = placeholder();
+    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 +127,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();
+    public static final int ARPHRD_ETHER = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    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 +230,10 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +258,17 @@
     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();
+    public static final int ETH_P_ALL = placeholder();
+    public static final int ETH_P_ARP = placeholder();
+    public static final int ETH_P_IP = placeholder();
+    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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +293,10 @@
     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();
+    public static final int ICMP_ECHO = placeholder();
+    public static final int ICMP_ECHOREPLY = placeholder();
+    public static final int ICMP6_ECHO_REQUEST = placeholder();
+    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 +342,26 @@
     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 */
+    @UnsupportedAppUsage
+    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 */
+    @UnsupportedAppUsage
+    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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +382,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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int NETLINK_NETFILTER = placeholder();
+    public static final int NETLINK_ROUTE = placeholder();
+    /**
+     * SELinux enforces that only system_server and netd may use this netlink socket type.
+     */
+    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 +400,10 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +424,14 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int PR_CAP_AMBIENT = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +440,53 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int RTMGRP_IPV4_IFADDR = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV4_MROUTE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV4_ROUTE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV4_RULE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV6_IFADDR = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV6_IFINFO = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV6_MROUTE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV6_PREFIX = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_IPV6_ROUTE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_LINK = placeholder();
+    public static final int RTMGRP_NEIGH = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int RTMGRP_NOTIFY = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    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();
@@ -461,7 +530,32 @@
     public static final int SIOCGIFBRDADDR = placeholder();
     public static final int SIOCGIFDSTADDR = placeholder();
     public static final int SIOCGIFNETMASK = placeholder();
+
+    /**
+     * Set the close-on-exec ({@code FD_CLOEXEC}) flag on the new file
+     * descriptor created by {@link Os#socket(int,int,int)} or
+     * {@link Os#socketpair(int,int,int,java.io.FileDescriptor,java.io.FileDescriptor)}.
+     * See the description of the O_CLOEXEC flag in
+     * <a href="http://man7.org/linux/man-pages/man2/open.2.html">open(2)</a>
+     * for reasons why this may be useful.
+     *
+     * <p>Applications wishing to make use of this flag on older API versions
+     * may use {@link #O_CLOEXEC} instead. On Android, {@code O_CLOEXEC} and
+     * {@code SOCK_CLOEXEC} are the same value.
+     */
+    public static final int SOCK_CLOEXEC = placeholder();
     public static final int SOCK_DGRAM = placeholder();
+
+    /**
+     * Set the O_NONBLOCK file status flag on the file descriptor
+     * created by {@link Os#socket(int,int,int)} or
+     * {@link Os#socketpair(int,int,int,java.io.FileDescriptor,java.io.FileDescriptor)}.
+     *
+     * <p>Applications wishing to make use of this flag on older API versions
+     * may use {@link #O_NONBLOCK} instead. On Android, {@code O_NONBLOCK}
+     * and {@code SOCK_NONBLOCK} are the same value.
+     */
+    public static final int SOCK_NONBLOCK = placeholder();
     public static final int SOCK_RAW = placeholder();
     public static final int SOCK_SEQPACKET = placeholder();
     public static final int SOCK_STREAM = placeholder();
@@ -469,7 +563,9 @@
     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 */
+    @UnsupportedAppUsage
+    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 +573,9 @@
     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 */
+    @UnsupportedAppUsage
+    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 +584,17 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int SPLICE_F_MOVE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int SPLICE_F_NONBLOCK = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    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 +632,24 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int TIOCOUTQ = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int UDP_ENCAP = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int UDP_ENCAP_ESPINUDP = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    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 +657,13 @@
     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 */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static final int XATTR_CREATE = placeholder();
+    /** @hide */
+    @UnsupportedAppUsage
+    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();
@@ -918,9 +1042,11 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     private static native void initConstants();
 
     // A hack to avoid these constants being inlined by javac...
+    @UnsupportedAppUsage
     private static int placeholder() { return 0; }
     // ...because we want to initialize them at runtime.
     static {
diff --git a/luni/src/main/java/android/system/PacketSocketAddress.java b/luni/src/main/java/android/system/PacketSocketAddress.java
index 510771c..d375226 100644
--- a/luni/src/main/java/android/system/PacketSocketAddress.java
+++ b/luni/src/main/java/android/system/PacketSocketAddress.java
@@ -16,6 +16,7 @@
 
 package android.system;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import libcore.util.Objects;
 import java.net.SocketAddress;
 
@@ -26,6 +27,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class PacketSocketAddress extends SocketAddress {
     /** Protocol. An Ethernet protocol type, e.g., {@code ETH_P_IPV6}. */
     public short sll_protocol;
@@ -53,11 +55,15 @@
     }
 
     /** Constructs a new PacketSocketAddress suitable for binding to. */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public PacketSocketAddress(short sll_protocol, int sll_ifindex) {
         this(sll_protocol, sll_ifindex, (short) 0, (byte) 0, null);
     }
 
     /** Constructs a new PacketSocketAddress suitable for sending to. */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public PacketSocketAddress(int sll_ifindex, byte[] sll_addr) {
         this((short) 0, sll_ifindex, (short) 0, (byte) 0, sll_addr);
     }
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructCapUserData.java
index 331e2ea..c175898 100644
--- a/luni/src/main/java/android/system/StructCapUserData.java
+++ b/luni/src/main/java/android/system/StructCapUserData.java
@@ -23,19 +23,24 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class StructCapUserData {
     /** Effective capability mask. */
+    @libcore.api.CorePlatformApi
     public final int effective; /* __u32 */
 
     /** Permitted capability mask. */
+    @libcore.api.CorePlatformApi
     public final int permitted; /* __u32 */
 
     /** Inheritable capability mask. */
+    @libcore.api.CorePlatformApi
     public final int inheritable; /* __u32 */
 
     /**
      * Constructs an instance with the given field values.
      */
+    @libcore.api.CorePlatformApi
     public StructCapUserData(int effective, int permitted, int inheritable) {
         this.effective = effective;
         this.permitted = permitted;
diff --git a/luni/src/main/java/android/system/StructCapUserHeader.java b/luni/src/main/java/android/system/StructCapUserHeader.java
index fb03aa8..aa1f876 100644
--- a/luni/src/main/java/android/system/StructCapUserHeader.java
+++ b/luni/src/main/java/android/system/StructCapUserHeader.java
@@ -23,6 +23,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class StructCapUserHeader {
     /**
      * Version of the header. Note this is not final as capget() may mutate the field when an
@@ -37,6 +38,7 @@
     /**
      * Constructs an instance with the given field values.
      */
+    @libcore.api.CorePlatformApi
     public StructCapUserHeader(int version, int pid) {
         this.version = version;
         this.pid = pid;
diff --git a/luni/src/main/java/android/system/StructLinger.java b/luni/src/main/java/android/system/StructLinger.java
index 46d4132..bf030a8 100644
--- a/luni/src/main/java/android/system/StructLinger.java
+++ b/luni/src/main/java/android/system/StructLinger.java
@@ -24,18 +24,22 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class StructLinger {
     /** Whether or not linger is enabled. Non-zero is on. */
     public final int l_onoff;
 
     /** Linger time in seconds. */
+    @libcore.api.CorePlatformApi
     public final int l_linger;
 
+    @libcore.api.CorePlatformApi
     public StructLinger(int l_onoff, int l_linger) {
         this.l_onoff = l_onoff;
         this.l_linger = l_linger;
     }
 
+    @libcore.api.CorePlatformApi
     public boolean isOn() {
         return l_onoff != 0;
     }
diff --git a/luni/src/main/java/android/system/StructRlimit.java b/luni/src/main/java/android/system/StructRlimit.java
index 007757f..e1f3437 100644
--- a/luni/src/main/java/android/system/StructRlimit.java
+++ b/luni/src/main/java/android/system/StructRlimit.java
@@ -24,7 +24,9 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class StructRlimit {
+    @libcore.api.CorePlatformApi
     public final long rlim_cur;
     public final long rlim_max;
 
diff --git a/luni/src/main/java/android/system/StructTimeval.java b/luni/src/main/java/android/system/StructTimeval.java
index 91a6f2a..559056a 100644
--- a/luni/src/main/java/android/system/StructTimeval.java
+++ b/luni/src/main/java/android/system/StructTimeval.java
@@ -16,13 +16,11 @@
 
 package android.system;
 
+import libcore.util.NonNull;
 import libcore.util.Objects;
 
 /**
- * Corresponds to C's {@code struct timeval} from
- * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html">&lt;sys/time.h&gt;</a>
- *
- * @hide
+ * Corresponds to C's {@code struct timeval} from {@code sys/time.h}.
  */
 public final class StructTimeval {
     /** Seconds. */
@@ -34,11 +32,22 @@
     private StructTimeval(long tv_sec, long tv_usec) {
         this.tv_sec = tv_sec;
         this.tv_usec = tv_usec;
+        if (tv_usec < 0 || tv_usec > 999_999) {
+            throw new IllegalArgumentException(
+                    "tv_usec value " + tv_usec + " is not in [0, 999999]");
+        }
     }
 
-    public static StructTimeval fromMillis(long millis) {
+    public static @NonNull StructTimeval fromMillis(long millis) {
+        // tv_sec can be positive or negative. tv_usec can only be positive. Negative numbers are
+        // represented by rounding down to the nearest whole second <= the one we need
+        // (i.e. floor()) and adding the necessary micro seconds.
         long tv_sec = millis / 1000;
         long tv_usec = (millis - (tv_sec * 1000)) * 1000;
+        if (millis < 0) {
+            tv_sec -= 1;
+            tv_usec += 1_000_000;
+        }
         return new StructTimeval(tv_sec, tv_usec);
     }
 
@@ -46,7 +55,26 @@
         return (tv_sec * 1000) + (tv_usec / 1000);
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return Objects.toString(this);
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        StructTimeval that = (StructTimeval) o;
+        return tv_sec == that.tv_sec &&
+                tv_usec == that.tv_usec;
+    }
+
+    @Override
+    public int hashCode() {
+        return java.util.Objects.hash(tv_sec, tv_usec);
+    }
 }
diff --git a/luni/src/main/java/android/system/UnixSocketAddress.java b/luni/src/main/java/android/system/UnixSocketAddress.java
index e0ade78..be689b3 100644
--- a/luni/src/main/java/android/system/UnixSocketAddress.java
+++ b/luni/src/main/java/android/system/UnixSocketAddress.java
@@ -25,6 +25,7 @@
  *
  * @hide
  */
+@libcore.api.CorePlatformApi
 public final class UnixSocketAddress extends SocketAddress {
 
     private static final int NAMED_PATH_LENGTH = OsConstants.UNIX_PATH_MAX;
@@ -67,6 +68,7 @@
     /**
      * Creates a named, filesystem AF_UNIX socket address.
      */
+    @libcore.api.CorePlatformApi
     public static UnixSocketAddress createFileSystem(String pathName) {
         byte[] pathNameBytes = pathName.getBytes(StandardCharsets.UTF_8);
         // File system sockets have a path that ends with (byte) 0.
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index d7e803e..9589a9d 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -16,6 +16,7 @@
 
 package java.lang.ref;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 
 /**
@@ -23,6 +24,7 @@
  */
 public final class FinalizerReference<T> extends Reference<T> {
     // This queue contains those objects eligible for finalization.
+    @UnsupportedAppUsage
     public static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
 
     // Guards the list (not the queue).
@@ -30,10 +32,12 @@
 
     // This list contains a FinalizerReference for every finalizable object in the heap.
     // Objects in this list may or may not be eligible for finalization yet.
+    @UnsupportedAppUsage
     private static FinalizerReference<?> head = null;
 
     // The links used to construct the list.
     private FinalizerReference<?> prev;
+    @UnsupportedAppUsage
     private FinalizerReference<?> next;
 
     // When the GC wants something finalized, it moves it from the 'referent' field to
@@ -52,6 +56,7 @@
         zombie = null;
     }
 
+    @UnsupportedAppUsage
     public static void add(Object referent) {
         FinalizerReference<?> reference = new FinalizerReference<Object>(referent, queue);
         synchronized (LIST_LOCK) {
@@ -64,6 +69,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static void remove(FinalizerReference<?> reference) {
         synchronized (LIST_LOCK) {
             FinalizerReference<?> next = reference.next;
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/java/math/BigInt.java b/luni/src/main/java/java/math/BigInt.java
index 9faac81..4448ce1 100644
--- a/luni/src/main/java/java/math/BigInt.java
+++ b/luni/src/main/java/java/math/BigInt.java
@@ -26,8 +26,8 @@
  */
 final class BigInt {
 
-    private static NativeAllocationRegistry registry = new NativeAllocationRegistry(
-            BigInt.class.getClassLoader(), NativeBN.getNativeFinalizer(), NativeBN.size());
+    private static NativeAllocationRegistry registry = NativeAllocationRegistry.createMalloced(
+            BigInt.class.getClassLoader(), NativeBN.getNativeFinalizer());
 
     /* Fields used for the internal representation. */
     @ReachabilitySensitive
diff --git a/luni/src/main/java/java/math/BigInteger.java b/luni/src/main/java/java/math/BigInteger.java
index 1353344..f7c0be2 100644
--- a/luni/src/main/java/java/math/BigInteger.java
+++ b/luni/src/main/java/java/math/BigInteger.java
@@ -22,6 +22,8 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Random;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 
 /**
  * An immutable arbitrary-precision signed integer.
@@ -63,13 +65,13 @@
     transient int sign;
 
     /** The {@code BigInteger} constant 0. */
-    public static final BigInteger ZERO = new BigInteger(0, 0);
+    @NonNull public static final BigInteger ZERO = new BigInteger(0, 0);
 
     /** The {@code BigInteger} constant 1. */
-    public static final BigInteger ONE = new BigInteger(1, 1);
+    @NonNull public static final BigInteger ONE = new BigInteger(1, 1);
 
     /** The {@code BigInteger} constant 10. */
-    public static final BigInteger TEN = new BigInteger(1, 10);
+    @NonNull public static final BigInteger TEN = new BigInteger(1, 10);
 
     /** The {@code BigInteger} constant -1. */
     static final BigInteger MINUS_ONE = new BigInteger(-1, 1);
@@ -124,7 +126,7 @@
      * @param random is the random number generator to be used.
      * @throws IllegalArgumentException if {@code numBits} < 0.
      */
-    public BigInteger(int numBits, Random random) {
+    public BigInteger(int numBits, @NonNull Random random) {
         if (numBits < 0) {
             throw new IllegalArgumentException("numBits < 0: " + numBits);
         }
@@ -160,7 +162,7 @@
      * @see <a href="http://www.openssl.org/docs/crypto/BN_rand.html">
      *      Specification of random generator used from OpenSSL library</a>
      */
-    public BigInteger(int bitLength, int certainty, Random random) {
+    public BigInteger(int bitLength, int certainty, @NonNull Random random) {
         if (bitLength < 2) {
             throw new ArithmeticException("bitLength < 2: " + bitLength);
         }
@@ -212,7 +214,7 @@
      * @throws NumberFormatException if {@code value} is not a valid
      *     representation of a {@code BigInteger}.
      */
-    public BigInteger(String value) {
+    public BigInteger(@NonNull String value) {
         BigInt bigInt = new BigInt();
         bigInt.putDecString(value);
         setBigInt(bigInt);
@@ -231,7 +233,7 @@
      *     representation of a {@code BigInteger} or if {@code radix <
      *     Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}.
      */
-    public BigInteger(String value, int radix) {
+    public BigInteger(@NonNull String value, int radix) {
         if (value == null) {
             throw new NullPointerException("value == null");
         }
@@ -266,7 +268,7 @@
      * @throws NumberFormatException if the sign is not one of -1, 0, 1 or if
      *     the sign is zero and the magnitude contains non-zero entries.
      */
-    public BigInteger(int signum, byte[] magnitude) {
+    public BigInteger(int signum, byte @NonNull [] magnitude) {
         if (magnitude == null) {
             throw new NullPointerException("magnitude == null");
         }
@@ -296,7 +298,7 @@
      * @throws NullPointerException if {@code value == null}.
      * @throws NumberFormatException if the length of {@code value} is zero.
      */
-    public BigInteger(byte[] value) {
+    public BigInteger(byte @NonNull [] value) {
         if (value.length == 0) {
             throw new NumberFormatException("value.length == 0");
         }
@@ -361,7 +363,7 @@
     }
 
     /** Returns a {@code BigInteger} whose value is equal to {@code value}. */
-    public static BigInteger valueOf(long value) {
+    @NonNull public static BigInteger valueOf(long value) {
         if (value < 0) {
             if (value != -1) {
                 return new BigInteger(-1, -value);
@@ -378,7 +380,7 @@
      * Returns the two's complement representation of this {@code BigInteger} in
      * a byte array.
      */
-    public byte[] toByteArray() {
+    public byte @NonNull [] toByteArray() {
         return twosComplement();
     }
 
@@ -386,7 +388,7 @@
      * Returns a {@code BigInteger} whose value is the absolute value of {@code
      * this}.
      */
-    public BigInteger abs() {
+    @NonNull public BigInteger abs() {
         BigInt bigInt = getBigInt();
         if (bigInt.sign() >= 0) {
             return this;
@@ -399,7 +401,7 @@
     /**
      * Returns a {@code BigInteger} whose value is the {@code -this}.
      */
-    public BigInteger negate() {
+    @NonNull public BigInteger negate() {
         BigInt bigInt = getBigInt();
         int sign = bigInt.sign();
         if (sign == 0) {
@@ -413,7 +415,7 @@
     /**
      * Returns a {@code BigInteger} whose value is {@code this + value}.
      */
-    public BigInteger add(BigInteger value) {
+    @NonNull public BigInteger add(@NonNull BigInteger value) {
         BigInt lhs = getBigInt();
         BigInt rhs = value.getBigInt();
         if (rhs.sign() == 0) {
@@ -428,7 +430,7 @@
     /**
      * Returns a {@code BigInteger} whose value is {@code this - value}.
      */
-    public BigInteger subtract(BigInteger value) {
+    @NonNull public BigInteger subtract(@NonNull BigInteger value) {
         BigInt lhs = getBigInt();
         BigInt rhs = value.getBigInt();
         if (rhs.sign() == 0) {
@@ -462,7 +464,7 @@
      * @return {@code this >> n} if {@code n >= 0}; {@code this << (-n)}
      *     otherwise
      */
-    public BigInteger shiftRight(int n) {
+    @NonNull public BigInteger shiftRight(int n) {
         return shiftLeft(-n);
     }
 
@@ -479,7 +481,7 @@
      * @return {@code this << n} if {@code n >= 0}; {@code this >> (-n)}.
      *     otherwise
      */
-    public BigInteger shiftLeft(int n) {
+    @NonNull public BigInteger shiftLeft(int n) {
         if (n == 0) {
             return this;
         }
@@ -579,7 +581,7 @@
      * @param n position where the bit in {@code this} has to be set.
      * @throws ArithmeticException if {@code n < 0}.
      */
-    public BigInteger setBit(int n) {
+    @NonNull public BigInteger setBit(int n) {
         prepareJavaRepresentation();
         if (!testBit(n)) {
             return BitLevel.flipBit(this, n);
@@ -599,7 +601,7 @@
      * @param n position where the bit in {@code this} has to be cleared.
      * @throws ArithmeticException if {@code n < 0}.
      */
-    public BigInteger clearBit(int n) {
+    @NonNull public BigInteger clearBit(int n) {
         prepareJavaRepresentation();
         if (testBit(n)) {
             return BitLevel.flipBit(this, n);
@@ -619,7 +621,7 @@
      * @param n position where the bit in {@code this} has to be flipped.
      * @throws ArithmeticException if {@code n < 0}.
      */
-    public BigInteger flipBit(int n) {
+    @NonNull public BigInteger flipBit(int n) {
         prepareJavaRepresentation();
         if (n < 0) {
             throw new ArithmeticException("n < 0: " + n);
@@ -669,7 +671,7 @@
      * <p><b>Implementation Note:</b> Usage of this method is not recommended as
      * the current implementation is not efficient.
      */
-    public BigInteger not() {
+    @NonNull public BigInteger not() {
         this.prepareJavaRepresentation();
         return Logical.not(this);
     }
@@ -683,7 +685,7 @@
      * @param value value to be and'ed with {@code this}.
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger and(BigInteger value) {
+    @NonNull public BigInteger and(@NonNull BigInteger value) {
         this.prepareJavaRepresentation();
         value.prepareJavaRepresentation();
         return Logical.and(this, value);
@@ -698,7 +700,7 @@
      * @param value value to be or'ed with {@code this}.
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger or(BigInteger value) {
+    @NonNull public BigInteger or(@NonNull BigInteger value) {
         this.prepareJavaRepresentation();
         value.prepareJavaRepresentation();
         return Logical.or(this, value);
@@ -713,7 +715,7 @@
      * @param value value to be xor'ed with {@code this}
      * @throws NullPointerException if {@code value == null}
      */
-    public BigInteger xor(BigInteger value) {
+    @NonNull public BigInteger xor(@NonNull BigInteger value) {
         this.prepareJavaRepresentation();
         value.prepareJavaRepresentation();
         return Logical.xor(this, value);
@@ -730,7 +732,7 @@
      * @param value value to be not'ed and then and'ed with {@code this}.
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger andNot(BigInteger value) {
+    @NonNull public BigInteger andNot(@NonNull BigInteger value) {
         this.prepareJavaRepresentation();
         value.prepareJavaRepresentation();
         return Logical.andNot(this, value);
@@ -799,7 +801,7 @@
      * @param value value to be compared with {@code this}.
      * @throws NullPointerException if {@code value == null}.
      */
-    public int compareTo(BigInteger value) {
+    public int compareTo(@NonNull BigInteger value) {
         return BigInt.cmp(getBigInt(), value.getBigInt());
     }
 
@@ -809,7 +811,7 @@
      * @param value value to be used to compute the minimum with {@code this}.
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger min(BigInteger value) {
+    @NonNull public BigInteger min(@NonNull BigInteger value) {
         return this.compareTo(value) == -1 ? this : value;
     }
 
@@ -819,7 +821,7 @@
      * @param value value to be used to compute the maximum with {@code this}
      * @throws NullPointerException if {@code value == null}
      */
-    public BigInteger max(BigInteger value) {
+    @NonNull public BigInteger max(@NonNull BigInteger value) {
         return this.compareTo(value) == 1 ? this : value;
     }
 
@@ -837,7 +839,7 @@
     }
 
     @Override
-    public boolean equals(Object x) {
+    public boolean equals(@Nullable Object x) {
         if (this == x) {
             return true;
         }
@@ -852,7 +854,7 @@
      * form.
      */
     @Override
-    public String toString() {
+    @NonNull public String toString() {
         return getBigInt().decString();
     }
 
@@ -865,7 +867,7 @@
      *
      * @param radix base to be used for the string representation.
      */
-    public String toString(int radix) {
+    @NonNull public String toString(int radix) {
         if (radix == 10) {
             return getBigInt().decString();
         } else {
@@ -882,7 +884,7 @@
      * @param value value with which the greatest common divisor is computed.
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger gcd(BigInteger value) {
+    @NonNull public BigInteger gcd(@NonNull BigInteger value) {
         return new BigInteger(BigInt.gcd(getBigInt(), value.getBigInt()));
     }
 
@@ -891,7 +893,7 @@
      *
      * @throws NullPointerException if {@code value == null}.
      */
-    public BigInteger multiply(BigInteger value) {
+    @NonNull public BigInteger multiply(@NonNull BigInteger value) {
         return new BigInteger(BigInt.product(getBigInt(), value.getBigInt()));
     }
 
@@ -900,7 +902,7 @@
      *
      * @throws ArithmeticException if {@code exp < 0}.
      */
-    public BigInteger pow(int exp) {
+    @NonNull public BigInteger pow(int exp) {
         if (exp < 0) {
             throw new ArithmeticException("exp < 0: " + exp);
         }
@@ -917,7 +919,7 @@
      * @see #divide
      * @see #remainder
      */
-    public BigInteger[] divideAndRemainder(BigInteger divisor) {
+    public @NonNull BigInteger @NonNull [] divideAndRemainder(@NonNull BigInteger divisor) {
         BigInt divisorBigInt = divisor.getBigInt();
         BigInt quotient = new BigInt();
         BigInt remainder = new BigInt();
@@ -933,7 +935,7 @@
      * @throws NullPointerException if {@code divisor == null}.
      * @throws ArithmeticException if {@code divisor == 0}.
      */
-    public BigInteger divide(BigInteger divisor) {
+    @NonNull public BigInteger divide(@NonNull BigInteger divisor) {
         BigInt quotient = new BigInt();
         BigInt.division(getBigInt(), divisor.getBigInt(), quotient, null);
         return new BigInteger(quotient);
@@ -948,7 +950,7 @@
      * @throws NullPointerException if {@code divisor == null}.
      * @throws ArithmeticException if {@code divisor == 0}.
      */
-    public BigInteger remainder(BigInteger divisor) {
+    @NonNull public BigInteger remainder(@NonNull BigInteger divisor) {
         BigInt remainder = new BigInt();
         BigInt.division(getBigInt(), divisor.getBigInt(), null, remainder);
         return new BigInteger(remainder);
@@ -965,7 +967,7 @@
      * @throws ArithmeticException if {@code m < 0 or} if {@code this} is not
      *     relatively prime to {@code m}
      */
-    public BigInteger modInverse(BigInteger m) {
+    @NonNull public BigInteger modInverse(@NonNull BigInteger m) {
         if (m.signum() <= 0) {
             throw new ArithmeticException("modulus not positive");
         }
@@ -985,7 +987,7 @@
      * @throws ArithmeticException if {@code modulus < 0} or if {@code exponent < 0} and
      *     not relatively prime to {@code modulus}.
      */
-    public BigInteger modPow(BigInteger exponent, BigInteger modulus) {
+    @NonNull public BigInteger modPow(@NonNull BigInteger exponent, @NonNull BigInteger modulus) {
         if (modulus.signum() <= 0) {
             throw new ArithmeticException("modulus.signum() <= 0");
         }
@@ -1009,7 +1011,7 @@
      * @throws NullPointerException if {@code m == null}.
      * @throws ArithmeticException if {@code m < 0}.
      */
-    public BigInteger mod(BigInteger m) {
+    @NonNull public BigInteger mod(@NonNull BigInteger m) {
         if (m.signum() <= 0) {
             throw new ArithmeticException("m.signum() <= 0");
         }
@@ -1042,7 +1044,7 @@
      * @return smallest integer > {@code this} which is probably prime.
      * @throws ArithmeticException if {@code this < 0}.
      */
-    public BigInteger nextProbablePrime() {
+    @NonNull public BigInteger nextProbablePrime() {
         if (sign < 0) {
             throw new ArithmeticException("sign < 0");
         }
@@ -1058,7 +1060,7 @@
      * @return probably prime random {@code BigInteger} instance.
      * @throws IllegalArgumentException if {@code bitLength < 2}.
      */
-    public static BigInteger probablePrime(int bitLength, Random random) {
+    @NonNull public static BigInteger probablePrime(int bitLength, @NonNull Random random) {
         return new BigInteger(bitLength, 100, random);
     }
 
diff --git a/luni/src/main/java/java/math/NativeBN.java b/luni/src/main/java/java/math/NativeBN.java
index d269f2e..ab9b2e0 100644
--- a/luni/src/main/java/java/math/NativeBN.java
+++ b/luni/src/main/java/java/math/NativeBN.java
@@ -133,10 +133,4 @@
     public static native long getNativeFinalizer();
     // &BN_free
 
-    /** Returns the expected size of the native allocation for a BIGNUM.
-     */
-    public static long size() {
-        // 36 bytes is an empirically determined approximation.
-        return 36;
-    }
 }
diff --git a/luni/src/main/java/java/net/AddressCache.java b/luni/src/main/java/java/net/AddressCache.java
index 2aba78b..ac5a029 100644
--- a/luni/src/main/java/java/net/AddressCache.java
+++ b/luni/src/main/java/java/net/AddressCache.java
@@ -16,6 +16,7 @@
 
 package java.net;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import libcore.util.BasicLruCache;
 
 /**
@@ -37,10 +38,12 @@
     private static final long TTL_NANOS = 2 * 1000000000L;
 
     // The actual cache.
+    @UnsupportedAppUsage
     private final BasicLruCache<AddressCacheKey, AddressCacheEntry> cache
             = new BasicLruCache<AddressCacheKey, AddressCacheEntry>(MAX_ENTRIES);
 
     static class AddressCacheKey {
+        @UnsupportedAppUsage
         private final String mHostname;
         private final int mNetId;
 
@@ -71,6 +74,7 @@
     static class AddressCacheEntry {
         // Either an InetAddress[] for a positive entry,
         // or a String detail message for a negative entry.
+        @UnsupportedAppUsage
         final Object value;
 
         /**
@@ -79,8 +83,10 @@
          *
          * We don't need to worry about overflow with a TTL_NANOS of 2s.
          */
+        @UnsupportedAppUsage
         final long expiryNanos;
 
+        @UnsupportedAppUsage
         AddressCacheEntry(Object value) {
             this.value = value;
             this.expiryNanos = System.nanoTime() + TTL_NANOS;
diff --git a/luni/src/main/java/java/nio/NIOAccess.java b/luni/src/main/java/java/nio/NIOAccess.java
index 4094ef8..7a07e3d 100644
--- a/luni/src/main/java/java/nio/NIOAccess.java
+++ b/luni/src/main/java/java/nio/NIOAccess.java
@@ -16,6 +16,8 @@
 
 package java.nio;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * This class is used via JNI by code in frameworks/base/.
  * @hide
@@ -30,6 +32,7 @@
      * @hide
      */
     // @VisibleForTesting : was default
+    @UnsupportedAppUsage
     public static long getBasePointer(Buffer b) {
         long address = b.address;
         if (address == 0L) {
@@ -42,6 +45,7 @@
      * Returns the underlying Java array containing the data of the
      * given Buffer, or null if the Buffer is not backed by a Java array.
      */
+    @UnsupportedAppUsage
     static Object getBaseArray(Buffer b) {
         return b.hasArray() ? b.array() : null;
     }
@@ -53,6 +57,7 @@
      * account the Buffer's current position. This method is only
      * meaningful if getBaseArray() returns non-null.
      */
+    @UnsupportedAppUsage
     static int getBaseArrayOffset(Buffer b) {
         return b.hasArray() ? ((b.arrayOffset() + b.position) << b._elementSizeShift) : 0;
     }
diff --git a/luni/src/main/java/java/nio/NioUtils.java b/luni/src/main/java/java/nio/NioUtils.java
index 140c00f..678382d 100644
--- a/luni/src/main/java/java/nio/NioUtils.java
+++ b/luni/src/main/java/java/nio/NioUtils.java
@@ -24,6 +24,7 @@
 import java.util.Set;
 
 import static android.system.OsConstants.*;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import sun.misc.Cleaner;
 import sun.nio.ch.DirectBuffer;
 import sun.nio.ch.FileChannelImpl;
@@ -31,10 +32,13 @@
 /**
  * @hide internal use only
  */
+@libcore.api.CorePlatformApi
 public final class NioUtils {
     private NioUtils() {
     }
 
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void freeDirectBuffer(ByteBuffer buffer) {
         if (buffer == null) {
             return;
@@ -70,6 +74,8 @@
      * Exposes the array backing a non-direct ByteBuffer, even if the ByteBuffer is read-only.
      * Normally, attempting to access the array backing a read-only buffer throws.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static byte[] unsafeArray(ByteBuffer b) {
         return b.array();
     }
@@ -78,6 +84,8 @@
      * Exposes the array offset for the array backing a non-direct ByteBuffer,
      * even if the ByteBuffer is read-only.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static int unsafeArrayOffset(ByteBuffer b) {
         return b.arrayOffset();
     }
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..99f1679
--- /dev/null
+++ b/luni/src/main/java/libcore/api/CorePlatformApi.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 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
+ */
+@IntraCoreApi
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface CorePlatformApi {
+}
diff --git a/luni/src/main/java/libcore/api/Hide.java b/luni/src/main/java/libcore/api/Hide.java
new file mode 100644
index 0000000..f87ff11
--- /dev/null
+++ b/luni/src/main/java/libcore/api/Hide.java
@@ -0,0 +1,47 @@
+/*
+ * 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 that an API is hidden by default, in a similar fashion to the
+ * <pre>@hide</pre> javadoc tag.
+ *
+ * <p>Note that, in order for this to work, metalava has to be invoked with
+ * the flag {@code --hide-annotation libcore.api.Hide}.
+ *
+ * <p>This annotation should be used in {@code .annotated.java} stub files which
+ * contain API inclusion information about {@code libcore/ojluni} classes, to
+ * avoid patching the source files with <pre>@hide</pre> javadoc tags. All
+ * build targets which consume these stub files should also apply the above
+ * metalava flag.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface Hide {
+}
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/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
index 472d99b..9a4f9a0 100644
--- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java
+++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
@@ -19,6 +19,7 @@
 import android.icu.util.Calendar;
 import android.icu.util.ULocale;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.text.FieldPosition;
 import java.util.TimeZone;
 import libcore.util.BasicLruCache;
@@ -27,7 +28,10 @@
 
 /**
  * Exposes icu4j's DateIntervalFormat.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class DateIntervalFormat {
 
   private static final BasicLruCache<String, android.icu.text.DateIntervalFormat> CACHED_FORMATTERS
@@ -37,6 +41,8 @@
   }
 
   // This is public DateUtils API in frameworks/base.
+  @UnsupportedAppUsage
+  @libcore.api.CorePlatformApi
   public static String formatDateRange(long startMs, long endMs, int flags, String olsonId) {
     if ((flags & FORMAT_UTC) != 0) {
       olsonId = "UTC";
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index 71fe99b..d8d878d 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -16,6 +16,7 @@
 
 package libcore.icu;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -28,8 +29,12 @@
 
 /**
  * Makes ICU data accessible to Java.
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class ICU {
+
+  @UnsupportedAppUsage
   private static final BasicLruCache<String, String> CACHED_PATTERNS =
       new BasicLruCache<String, String>(8);
 
@@ -39,6 +44,9 @@
 
   private static String[] isoLanguages;
 
+  private ICU() {
+  }
+
   /**
    * Returns an array of two-letter ISO 639-1 language codes, either from ICU or our cache.
    */
@@ -286,6 +294,8 @@
     return localesFromStrings(getAvailableNumberFormatLocalesNative());
   }
 
+  @UnsupportedAppUsage
+  @libcore.api.CorePlatformApi
   public static String getBestDateTimePattern(String skeleton, Locale locale) {
     String languageTag = locale.toLanguageTag();
     String key = skeleton + "\t" + languageTag;
@@ -299,8 +309,11 @@
     }
   }
 
+  @UnsupportedAppUsage
   private static native String getBestDateTimePatternNative(String skeleton, String languageTag);
 
+  @UnsupportedAppUsage
+  @libcore.api.CorePlatformApi
   public static char[] getDateFormatOrder(String pattern) {
     char[] result = new char[3];
     int resultIndex = 0;
@@ -439,6 +452,8 @@
 
   public static native String getISO3Language(String languageTag);
 
+  @UnsupportedAppUsage
+  @libcore.api.CorePlatformApi
   public static Locale addLikelySubtags(Locale locale) {
       return Locale.forLanguageTag(addLikelySubtags(locale.toLanguageTag()).replace('_', '-'));
   }
@@ -446,6 +461,7 @@
   /**
    * @deprecated use {@link #addLikelySubtags(java.util.Locale)} instead.
    */
+  @UnsupportedAppUsage
   @Deprecated
   public static native String addLikelySubtags(String locale);
 
@@ -453,6 +469,7 @@
    * @deprecated use {@link java.util.Locale#getScript()} instead. This has been kept
    *     around only for the support library.
    */
+  @UnsupportedAppUsage
   @Deprecated
   public static native String getScript(String locale);
 
@@ -472,5 +489,6 @@
   public static native String getDefaultLocale();
 
   /** Returns the TZData version as reported by ICU4C. */
+  @libcore.api.CorePlatformApi
   public static native String getTZDataVersion();
 }
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index 154ea68..cf3fec0 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -16,9 +16,15 @@
 
 package libcore.icu;
 
+import android.icu.impl.ICUData;
+import android.icu.impl.ICUResourceBundle;
+import android.icu.text.NumberingSystem;
+import android.icu.util.UResourceBundle;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.text.DateFormat;
 import java.util.HashMap;
 import java.util.Locale;
+import java.util.MissingResourceException;
 import libcore.util.Objects;
 
 /**
@@ -27,7 +33,9 @@
  * Note that you share these; you must not alter any of the fields, nor their array elements
  * in the case of arrays. If you ever expose any of these things to user code, you must give
  * them a clone rather than the original.
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class LocaleData {
     // A cache for the locale-specific data.
     private static final HashMap<String, LocaleData> localeDataCache = new HashMap<String, LocaleData>();
@@ -42,30 +50,54 @@
     }
 
     // Used by Calendar.
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public Integer firstDayOfWeek;
+    @UnsupportedAppUsage
     public Integer minimalDaysInFirstWeek;
 
     // Used by DateFormatSymbols.
+    @libcore.api.CorePlatformApi
     public String[] amPm; // "AM", "PM".
     public String[] eras; // "BC", "AD".
 
+    @libcore.api.CorePlatformApi
     public String[] longMonthNames; // "January", ...
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String[] shortMonthNames; // "Jan", ...
+    @libcore.api.CorePlatformApi
     public String[] tinyMonthNames; // "J", ...
+    @libcore.api.CorePlatformApi
     public String[] longStandAloneMonthNames; // "January", ...
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String[] shortStandAloneMonthNames; // "Jan", ...
+    @libcore.api.CorePlatformApi
     public String[] tinyStandAloneMonthNames; // "J", ...
 
+    @libcore.api.CorePlatformApi
     public String[] longWeekdayNames; // "Sunday", ...
+    @libcore.api.CorePlatformApi
     public String[] shortWeekdayNames; // "Sun", ...
+    @libcore.api.CorePlatformApi
     public String[] tinyWeekdayNames; // "S", ...
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String[] longStandAloneWeekdayNames; // "Sunday", ...
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String[] shortStandAloneWeekdayNames; // "Sun", ...
+    @libcore.api.CorePlatformApi
     public String[] tinyStandAloneWeekdayNames; // "S", ...
 
     // Used by frameworks/base DateSorter and DateUtils.
+    @libcore.api.CorePlatformApi
     public String yesterday; // "Yesterday".
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String today; // "Today".
+    @UnsupportedAppUsage
     public String tomorrow; // "Tomorrow".
 
     public String fullTimeFormat;
@@ -79,17 +111,27 @@
     public String shortDateFormat;
 
     // Used by TimePicker. Not currently used by UTS#35.
+    @libcore.api.CorePlatformApi
     public String narrowAm; // "a".
+    @libcore.api.CorePlatformApi
     public String narrowPm; // "p".
 
     // Used by DateFormat to implement 12- and 24-hour SHORT and MEDIUM.
-    // The first two are also used directly by frameworks code.
+    // They are also used directly by frameworks code.
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String timeFormat_hm;
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public String timeFormat_Hm;
+    @libcore.api.CorePlatformApi
     public String timeFormat_hms;
+    @libcore.api.CorePlatformApi
     public String timeFormat_Hms;
 
     // Used by DecimalFormatSymbols.
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public char zeroDigit;
     public char decimalSeparator;
     public char groupingSeparator;
@@ -114,6 +156,7 @@
     private LocaleData() {
     }
 
+    @UnsupportedAppUsage
     public static Locale mapInvalidAndNullLocales(Locale locale) {
         if (locale == null) {
             return Locale.getDefault();
@@ -129,6 +172,8 @@
     /**
      * Returns a shared LocaleData for the given locale.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static LocaleData get(Locale locale) {
         if (locale == null) {
             throw new NullPointerException("locale == null");
@@ -156,6 +201,7 @@
         return Objects.toString(this);
     }
 
+    @libcore.api.CorePlatformApi
     public String getDateFormat(int style) {
         switch (style) {
         case DateFormat.SHORT:
@@ -200,6 +246,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 +275,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/icu/RelativeDateTimeFormatter.java b/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
index a9ead7a..0a53ef3 100644
--- a/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
+++ b/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
@@ -34,7 +34,10 @@
 
 /**
  * Exposes icu4j's RelativeDateTimeFormatter.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class RelativeDateTimeFormatter {
 
   public static final long SECOND_IN_MILLIS = 1000;
@@ -88,6 +91,7 @@
    * always // returns a string like '0 seconds/minutes/... ago' according to
    * minResolution.
    */
+  @libcore.api.CorePlatformApi
   public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time,
       long now, long minResolution, int flags) {
     // Android has been inconsistent about capitalization in the past. e.g. bug http://b/20247811.
@@ -257,6 +261,7 @@
    * now - 2 hours, now, HOUR_IN_MILLIS, DAY_IN_MILLIS, 0), instead of '2
    * hours ago, 11:30 PM' even with minResolution being HOUR_IN_MILLIS.
    */
+  @libcore.api.CorePlatformApi
   public static String getRelativeDateTimeString(Locale locale, java.util.TimeZone tz, long time,
       long now, long minResolution, long transitionResolution, int flags) {
 
diff --git a/luni/src/main/java/libcore/icu/TimeZoneNames.java b/luni/src/main/java/libcore/icu/TimeZoneNames.java
index aea4483..caeaefd 100644
--- a/luni/src/main/java/libcore/icu/TimeZoneNames.java
+++ b/luni/src/main/java/libcore/icu/TimeZoneNames.java
@@ -24,10 +24,11 @@
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
 import libcore.util.BasicLruCache;
-import libcore.util.ZoneInfoDB;
+import libcore.timezone.ZoneInfoDB;
 
 /**
  * Provides access to ICU's time zone name data.
+ * @hide
  */
 public final class TimeZoneNames {
     private static final String[] availableTimeZoneIds = TimeZone.getAvailableIDs();
@@ -44,6 +45,7 @@
 
     private static final ZoneStringsCache cachedZoneStrings = new ZoneStringsCache();
 
+    /** @hide */
     public static class ZoneStringsCache extends BasicLruCache<Locale, String[][]> {
         public ZoneStringsCache() {
             super(5); // Room for a handful of locales.
@@ -152,28 +154,5 @@
         return cachedZoneStrings.get(locale);
     }
 
-    /**
-     * Returns an array containing the time zone ids in use in the country corresponding to
-     * the given locale. This is not necessary for Java API, but is used by telephony as a
-     * fallback. We retrieve these strings from zone.tab rather than icu4c because the latter
-     * supplies them in alphabetical order where zone.tab has them in a kind of "importance"
-     * order (as defined in the zone.tab header).
-     */
-    public static String[] forLocale(Locale locale) {
-        String countryCode = locale.getCountry();
-        ArrayList<String> ids = new ArrayList<String>();
-        for (String line : ZoneInfoDB.getInstance().getZoneTab().split("\n")) {
-            if (line.startsWith(countryCode)) {
-                int olsonIdStart = line.indexOf('\t', 4) + 1;
-                int olsonIdEnd = line.indexOf('\t', olsonIdStart);
-                if (olsonIdEnd == -1) {
-                    olsonIdEnd = line.length(); // Not all zone.tab lines have a comment.
-                }
-                ids.add(line.substring(olsonIdStart, olsonIdEnd));
-            }
-        }
-        return ids.toArray(new String[ids.size()]);
-    }
-
     private static native void fillZoneStrings(String locale, String[][] result);
 }
diff --git a/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
new file mode 100644
index 0000000..7e201d0
--- /dev/null
+++ b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
@@ -0,0 +1,85 @@
+/*
+ * 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.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Proof of concept / dummy code whose only purpose is to demonstrate that Java 9
+ * language features are supported in libcore.
+ */
+public class Java9LanguageFeatures {
+
+    public interface Person {
+        String name();
+
+        default boolean isPalindrome() {
+            return name().equals(reverse(name()));
+        }
+
+        default boolean isPalindromeIgnoreCase() {
+            return name().equalsIgnoreCase(reverse(name()));
+        }
+
+        // Language feature: private interface method
+        private String reverse(String s) {
+            return new StringBuilder(s).reverse().toString();
+        }
+    }
+
+    @SafeVarargs
+    public static<T> String toListString(T... values) {
+        return toString(values).toString();
+    }
+
+    // Language feature: @SafeVarargs on private methods
+    @SafeVarargs
+    private static<T> List<String> toString(T... values) {
+        List<String> result = new ArrayList<>();
+        for (T value : values) {
+            result.add(value.toString());
+        }
+        return result;
+    }
+
+    public <T> AtomicReference<T> createReference(T content) {
+        // Language feature: <> on anonymous class
+        return new AtomicReference<>(content) { };
+    }
+
+    public static byte[] copy(byte[] bytes) throws IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        InputStream inputStream = new ByteArrayInputStream(bytes);
+        try (inputStream) { // Language feature: try on effectively-final variable
+            int value;
+            while ((value = inputStream.read()) != -1) {
+                byteArrayOutputStream.write(value);
+            }
+        }
+        return byteArrayOutputStream.toByteArray();
+    }
+
+
+}
diff --git a/luni/src/main/java/libcore/internal/StringPool.java b/luni/src/main/java/libcore/internal/StringPool.java
index 9fe38f5..546a404 100644
--- a/luni/src/main/java/libcore/internal/StringPool.java
+++ b/luni/src/main/java/libcore/internal/StringPool.java
@@ -20,11 +20,18 @@
  * A pool of string instances. Unlike the {@link String#intern() VM's
  * interned strings}, this pool provides no guarantee of reference equality.
  * It is intended only to save allocations. This class is not thread safe.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class StringPool {
 
     private final String[] pool = new String[512];
 
+    @libcore.api.CorePlatformApi
+    public StringPool() {
+    }
+
     private static boolean contentEquals(String s, char[] chars, int start, int length) {
         if (s.length() != length) {
             return false;
@@ -40,6 +47,7 @@
     /**
      * Returns a string equal to {@code new String(array, start, length)}.
      */
+    @libcore.api.CorePlatformApi
     public String get(char[] array, int start, int length) {
         // Compute an arbitrary hash of the content
         int hashCode = 0;
diff --git a/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java b/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java
index 62eec24..76ef5e4 100644
--- a/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java
+++ b/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java
@@ -16,11 +16,13 @@
 
 package libcore.io;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 
 public final class AsynchronousCloseMonitor {
     private AsynchronousCloseMonitor() {
     }
 
+    @UnsupportedAppUsage
     public static native void signalBlockedThreads(FileDescriptor fd);
 }
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index 9b1ebe9..bd95a93 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -25,6 +25,7 @@
 import android.system.StructPollfd;
 import android.system.StructStat;
 import android.system.StructStatVfs;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.system.BlockGuard;
 import dalvik.system.SocketTagger;
 import java.io.FileDescriptor;
@@ -41,6 +42,7 @@
  * Informs BlockGuard of any activity it should be aware of.
  */
 public class BlockGuardOs extends ForwardingOs {
+    @UnsupportedAppUsage
     public BlockGuardOs(Os os) {
         super(os);
     }
@@ -56,7 +58,7 @@
 
     @Override public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
-        final FileDescriptor acceptFd = os.accept(fd, peerAddress);
+        final FileDescriptor acceptFd = super.accept(fd, peerAddress);
         if (isInetSocket(acceptFd)) {
             tagSocket(acceptFd);
         }
@@ -65,19 +67,25 @@
 
     @Override public boolean access(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.access(path, mode);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        return super.access(path, mode);
     }
 
+    @UnsupportedAppUsage
     @Override public void chmod(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.chmod(path, mode);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.chmod(path, mode);
     }
 
+    @UnsupportedAppUsage
     @Override public void chown(String path, int uid, int gid) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.chown(path, uid, gid);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.chown(path, uid, gid);
     }
 
+    @UnsupportedAppUsage
     @Override public void close(FileDescriptor fd) throws ErrnoException {
         try {
             // The usual case is that this _isn't_ a socket, so the getsockopt(2) call in
@@ -97,7 +105,7 @@
             // already-closed socket. Also, the passed-in FileDescriptor isn't necessarily
             // a socket at all.
         }
-        os.close(fd);
+        super.close(fd);
     }
 
     private static boolean isInetSocket(FileDescriptor fd) throws ErrnoException{
@@ -113,52 +121,72 @@
         return linger.isOn() && linger.l_linger > 0;
     }
 
-    @Override public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException {
-        BlockGuard.getThreadPolicy().onNetwork();
-        os.connect(fd, address, port);
+    private static boolean isUdpSocket(FileDescriptor fd) throws ErrnoException {
+        return Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) == IPPROTO_UDP;
+    }
+
+    @Override public void connect(FileDescriptor fd, InetAddress address, int port)
+            throws ErrnoException, SocketException {
+        boolean skipGuard = false;
+        try {
+            skipGuard = isUdpSocket(fd);
+        } catch (ErrnoException ignored) {
+        }
+        if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork();
+        super.connect(fd, address, port);
     }
 
     @Override public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException,
             SocketException {
-        BlockGuard.getThreadPolicy().onNetwork();
-        os.connect(fd, address);
+        boolean skipGuard = false;
+        try {
+            skipGuard = isUdpSocket(fd);
+        } catch (ErrnoException ignored) {
+        }
+        if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork();
+        super.connect(fd, address);
     }
 
+    @UnsupportedAppUsage
     @Override public void fchmod(FileDescriptor fd, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.fchmod(fd, mode);
+        super.fchmod(fd, mode);
     }
 
+    @UnsupportedAppUsage
     @Override public void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.fchown(fd, uid, gid);
+        super.fchown(fd, uid, gid);
     }
 
     // TODO: Untag newFd when needed for dup2(FileDescriptor oldFd, int newFd)
 
+    @UnsupportedAppUsage
     @Override public void fdatasync(FileDescriptor fd) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.fdatasync(fd);
+        super.fdatasync(fd);
     }
 
+    @UnsupportedAppUsage
     @Override public StructStat fstat(FileDescriptor fd) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.fstat(fd);
+        return super.fstat(fd);
     }
 
+    @UnsupportedAppUsage
     @Override public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.fstatvfs(fd);
+        return super.fstatvfs(fd);
     }
 
     @Override public void fsync(FileDescriptor fd) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.fsync(fd);
+        super.fsync(fd);
     }
 
     @Override public void ftruncate(FileDescriptor fd, long length) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.ftruncate(fd, length);
+        super.ftruncate(fd, length);
     }
 
     @Override public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException {
@@ -169,45 +197,59 @@
         if (!isNumericHost) {
             BlockGuard.getThreadPolicy().onNetwork();
         }
-        return os.android_getaddrinfo(node, hints, netId);
+        return super.android_getaddrinfo(node, hints, netId);
     }
 
+    @UnsupportedAppUsage
     @Override public void lchown(String path, int uid, int gid) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.lchown(path, uid, gid);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.lchown(path, uid, gid);
     }
 
+    @UnsupportedAppUsage
     @Override public void link(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.link(oldPath, newPath);
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
+        super.link(oldPath, newPath);
     }
 
+    @UnsupportedAppUsage
     @Override public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.lseek(fd, offset, whence);
+        return super.lseek(fd, offset, whence);
     }
 
+    @UnsupportedAppUsage
     @Override public StructStat lstat(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.lstat(path);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        return super.lstat(path);
     }
 
+    @UnsupportedAppUsage
     @Override public void mkdir(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.mkdir(path, mode);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.mkdir(path, mode);
     }
 
+    @UnsupportedAppUsage
     @Override public void mkfifo(String path, int mode) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.mkfifo(path, mode);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.mkfifo(path, mode);
     }
 
+    @UnsupportedAppUsage
     @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();
         }
-        return os.open(path, flags, mode);
+        return super.open(path, flags, mode);
     }
 
     @Override public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException {
@@ -216,87 +258,104 @@
         if (timeoutMs != 0) {
             BlockGuard.getThreadPolicy().onNetwork();
         }
-        return os.poll(fds, timeoutMs);
+        return super.poll(fds, timeoutMs);
     }
 
+    @UnsupportedAppUsage
     @Override public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.posix_fallocate(fd, offset, length);
+        super.posix_fallocate(fd, offset, length);
     }
 
+    @UnsupportedAppUsage
     @Override public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.pread(fd, buffer, offset);
+        return super.pread(fd, buffer, offset);
     }
 
+    @UnsupportedAppUsage
     @Override public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.pread(fd, bytes, byteOffset, byteCount, offset);
+        return super.pread(fd, bytes, byteOffset, byteCount, offset);
     }
 
+    @UnsupportedAppUsage
     @Override public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.pwrite(fd, buffer, offset);
+        return super.pwrite(fd, buffer, offset);
     }
 
+    @UnsupportedAppUsage
     @Override public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.pwrite(fd, bytes, byteOffset, byteCount, offset);
+        return super.pwrite(fd, bytes, byteOffset, byteCount, offset);
     }
 
+    @UnsupportedAppUsage
     @Override public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.read(fd, buffer);
+        return super.read(fd, buffer);
     }
 
+    @UnsupportedAppUsage
     @Override public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.read(fd, bytes, byteOffset, byteCount);
+        return super.read(fd, bytes, byteOffset, byteCount);
     }
 
+    @UnsupportedAppUsage
     @Override public String readlink(String path) throws ErrnoException {
       BlockGuard.getThreadPolicy().onReadFromDisk();
-      return os.readlink(path);
+      BlockGuard.getVmPolicy().onPathAccess(path);
+      return super.readlink(path);
     }
 
+    @UnsupportedAppUsage
     @Override public String realpath(String path) throws ErrnoException {
       BlockGuard.getThreadPolicy().onReadFromDisk();
-      return os.realpath(path);
+      BlockGuard.getVmPolicy().onPathAccess(path);
+      return super.realpath(path);
     }
 
+    @UnsupportedAppUsage
     @Override public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.readv(fd, buffers, offsets, byteCounts);
+        return super.readv(fd, buffers, offsets, byteCounts);
     }
 
     @Override public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
-        return os.recvfrom(fd, buffer, flags, srcAddress);
+        return super.recvfrom(fd, buffer, flags, srcAddress);
     }
 
     @Override public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
-        return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress);
+        return super.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress);
     }
 
+    @UnsupportedAppUsage
     @Override public void remove(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.remove(path);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.remove(path);
     }
 
+    @UnsupportedAppUsage
     @Override public void rename(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.rename(oldPath, newPath);
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
+        super.rename(oldPath, newPath);
     }
 
     @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.sendfile(outFd, inFd, offset, byteCount);
+        return super.sendfile(outFd, inFd, offset, byteCount);
     }
 
     @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
-        return os.sendto(fd, buffer, flags, inetAddress, port);
+        return super.sendto(fd, buffer, flags, inetAddress, port);
     }
 
     @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
@@ -304,11 +363,11 @@
         if (inetAddress != null) {
             BlockGuard.getThreadPolicy().onNetwork();
         }
-        return os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port);
+        return super.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port);
     }
 
     @Override public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException {
-        final FileDescriptor fd = os.socket(domain, type, protocol);
+        final FileDescriptor fd = super.socket(domain, type, protocol);
         if (isInetDomain(domain)) {
             tagSocket(fd);
         }
@@ -316,86 +375,102 @@
     }
 
     @Override public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException {
-        os.socketpair(domain, type, protocol, fd1, fd2);
+        super.socketpair(domain, type, protocol, fd1, fd2);
         if (isInetDomain(domain)) {
             tagSocket(fd1);
             tagSocket(fd2);
         }
     }
 
+    @UnsupportedAppUsage
     @Override public StructStat stat(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.stat(path);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        return super.stat(path);
     }
 
+    @UnsupportedAppUsage
     @Override public StructStatVfs statvfs(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.statvfs(path);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        return super.statvfs(path);
     }
 
+    @UnsupportedAppUsage
     @Override public void symlink(String oldPath, String newPath) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.symlink(oldPath, newPath);
+        BlockGuard.getVmPolicy().onPathAccess(oldPath);
+        BlockGuard.getVmPolicy().onPathAccess(newPath);
+        super.symlink(oldPath, newPath);
     }
 
+    @UnsupportedAppUsage
     @Override public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.write(fd, buffer);
+        return super.write(fd, buffer);
     }
 
+    @UnsupportedAppUsage
     @Override public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.write(fd, bytes, byteOffset, byteCount);
+        return super.write(fd, bytes, byteOffset, byteCount);
     }
 
+    @UnsupportedAppUsage
     @Override public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        return os.writev(fd, buffers, offsets, byteCounts);
+        return super.writev(fd, buffers, offsets, byteCounts);
     }
 
     @Override public void execv(String filename, String[] argv) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        os.execv(filename, argv);
+        BlockGuard.getVmPolicy().onPathAccess(filename);
+        super.execv(filename, argv);
     }
 
     @Override public void execve(String filename, String[] argv, String[] envp)
             throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        os.execve(filename, argv, envp);
+        BlockGuard.getVmPolicy().onPathAccess(filename);
+        super.execve(filename, argv, envp);
     }
 
     @Override public byte[] getxattr(String path, String name) throws ErrnoException {
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.getxattr(path, name);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        return super.getxattr(path, name);
     }
 
     @Override public void msync(long address, long byteCount, int flags) throws ErrnoException {
         if ((flags & OsConstants.MS_SYNC) != 0) {
             BlockGuard.getThreadPolicy().onWriteToDisk();
         }
-        os.msync(address, byteCount, flags);
+        super.msync(address, byteCount, flags);
     }
 
     @Override public void removexattr(String path, String name) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.removexattr(path, name);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.removexattr(path, name);
     }
 
     @Override public void setxattr(String path, String name, byte[] value, int flags)
             throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.setxattr(path, name, value, flags);
+        BlockGuard.getVmPolicy().onPathAccess(path);
+        super.setxattr(path, name, value, flags);
     }
 
     @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount,
             int flags, SocketAddress address) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
-        return os.sendto(fd, bytes, byteOffset, byteCount, flags, address);
+        return super.sendto(fd, bytes, byteOffset, byteCount, flags, address);
     }
 
     @Override public void unlink(String pathname) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
-        os.unlink(pathname);
+        BlockGuard.getVmPolicy().onPathAccess(pathname);
+        super.unlink(pathname);
     }
 
     @Override public long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException {
@@ -403,6 +478,6 @@
         // So, signal both read and write.
         BlockGuard.getThreadPolicy().onWriteToDisk();
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        return os.splice(fdIn, offIn, fdOut, offOut, len, flags);
+        return super.splice(fdIn, offIn, fdOut, offOut, len, flags);
     }
 }
diff --git a/luni/src/main/java/libcore/io/BufferIterator.java b/luni/src/main/java/libcore/io/BufferIterator.java
index 0d167e3..b7c5b38 100644
--- a/luni/src/main/java/libcore/io/BufferIterator.java
+++ b/luni/src/main/java/libcore/io/BufferIterator.java
@@ -16,6 +16,8 @@
 
 package libcore.io;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * Iterates over big- or little-endian bytes. See {@link MemoryMappedFile#bigEndianIterator} and
  * {@link MemoryMappedFile#littleEndianIterator}.
@@ -27,11 +29,13 @@
      * Seeks to the absolute position {@code offset}, measured in bytes from the start of the
      * buffer.
      */
+    @UnsupportedAppUsage
     public abstract void seek(int offset);
 
     /**
      * Skips forwards or backwards {@code byteCount} bytes from the current position.
      */
+    @UnsupportedAppUsage
     public abstract void skip(int byteCount);
 
     /**
@@ -45,6 +49,7 @@
      *
      * @throws IndexOutOfBoundsException if the read / write would be outside of the buffer / array
      */
+    @UnsupportedAppUsage
     public abstract void readByteArray(byte[] dst, int dstOffset, int byteCount);
 
     /**
@@ -52,6 +57,7 @@
      *
      * @throws IndexOutOfBoundsException if the read would be outside of the buffer
      */
+    @UnsupportedAppUsage
     public abstract byte readByte();
 
     /**
@@ -59,6 +65,7 @@
      *
      * @throws IndexOutOfBoundsException if the read would be outside of the buffer
      */
+    @UnsupportedAppUsage
     public abstract int readInt();
 
     /**
@@ -67,6 +74,7 @@
      *
      * @throws IndexOutOfBoundsException if the read / write would be outside of the buffer / array
      */
+    @UnsupportedAppUsage
     public abstract void readIntArray(int[] dst, int dstOffset, int intCount);
 
     /**
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/DropBox.java b/luni/src/main/java/libcore/io/DropBox.java
deleted file mode 100644
index 4180a2a..0000000
--- a/luni/src/main/java/libcore/io/DropBox.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 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.io;
-
-import java.util.Base64;
-
-public final class DropBox {
-
-    /**
-     * Hook for customizing how events are reported.
-     */
-    private static volatile Reporter REPORTER = new DefaultReporter();
-
-    /**
-     * Used to replace default Reporter for logging events. Must be non-null.
-     */
-    public static void setReporter(Reporter reporter) {
-        if (reporter == null) {
-            throw new NullPointerException("reporter == null");
-        }
-        REPORTER = reporter;
-    }
-
-    /**
-     * Returns non-null Reporter.
-     */
-    public static Reporter getReporter() {
-        return REPORTER;
-    }
-
-    /**
-     * Interface to allow customization of reporting behavior.
-     */
-    public static interface Reporter {
-        public void addData(String tag, byte[] data, int flags);
-        public void addText(String tag, String data);
-    }
-
-    /**
-     * Default Reporter which reports events to the log.
-     */
-    private static final class DefaultReporter implements Reporter {
-
-        public void addData(String tag, byte[] data, int flags) {
-            System.out.println(tag + ": " + Base64.getEncoder().encodeToString(data));
-        }
-
-        public void addText(String tag, String data) {
-            System.out.println(tag + ": " + data);
-        }
-    }
-
-    public static void addData(String tag, byte[] data, int flags) {
-        getReporter().addData(tag, data, flags);
-    }
-
-    public static void addText(String tag, String data) {
-        getReporter().addText(tag, data);
-    }
-}
diff --git a/luni/src/main/java/libcore/io/EventLogger.java b/luni/src/main/java/libcore/io/EventLogger.java
deleted file mode 100644
index 9709cc9..0000000
--- a/luni/src/main/java/libcore/io/EventLogger.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 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.io;
-
-public final class EventLogger {
-
-    /**
-     * Hook for customizing how events are reported.
-     */
-    private static volatile Reporter REPORTER = new DefaultReporter();
-
-    /**
-     * Used to replace default Reporter for logging events. Must be non-null.
-     */
-    public static void setReporter(Reporter reporter) {
-        if (reporter == null) {
-            throw new NullPointerException("reporter == null");
-        }
-        REPORTER = reporter;
-    }
-
-    /**
-     * Returns non-null Reporter.
-     */
-    public static Reporter getReporter() {
-        return REPORTER;
-    }
-
-    /**
-     * Interface to allow customization of reporting behavior.
-     */
-    public static interface Reporter {
-        public void report (int code, Object... list);
-    }
-
-    /**
-     * Default Reporter which reports events to the log.
-     */
-    private static final class DefaultReporter implements Reporter {
-        @Override
-        public void report (int code, Object... list) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(code);
-            for (Object o : list) {
-                sb.append(",");
-                sb.append(o.toString());
-            }
-            System.out.println(sb);
-        }
-    }
-
-    public static void writeEvent(int code, Object... list) {
-        getReporter().report(code, list);
-    }
-}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index f141694..1c1dec2 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -36,6 +36,7 @@
 import android.system.StructUcred;
 import android.system.StructUtsname;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
@@ -43,18 +44,32 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
+import java.util.Objects;
 
 /**
  * Subclass this if you want to override some {@link Os} methods but otherwise delegate.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class ForwardingOs implements Os {
-    protected final Os os;
+    @UnsupportedAppUsage
+    private final Os os;
 
-    public ForwardingOs(Os os) {
-        this.os = os;
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    protected ForwardingOs(Os os) {
+        this.os = Objects.requireNonNull(os);
+    }
+
+    /** @return the delegate object passed to the constructor. */
+    protected final Os delegate() {
+        return os;
     }
 
     public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
     public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
     public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
@@ -67,9 +82,16 @@
     public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException {
         os.capset(hdr, data);
     }
+    @UnsupportedAppUsage
     public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
+    @UnsupportedAppUsage
     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); }
@@ -91,6 +113,7 @@
     public int getegid() { return os.getegid(); }
     public int geteuid() { return os.geteuid(); }
     public int getgid() { return os.getgid(); }
+    @UnsupportedAppUsage
     public String getenv(String name) { return os.getenv(name); }
     public String getnameinfo(InetAddress address, int flags) throws GaiException { return os.getnameinfo(address, flags); }
     public SocketAddress getpeername(FileDescriptor fd) throws ErrnoException { return os.getpeername(fd); }
@@ -120,20 +143,27 @@
     public int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException { return os.ioctlMTU(fd, interfaceName); };
     public boolean isatty(FileDescriptor fd) { return os.isatty(fd); }
     public void kill(int pid, int signal) throws ErrnoException { os.kill(pid, signal); }
+    @UnsupportedAppUsage
     public void lchown(String path, int uid, int gid) throws ErrnoException { os.lchown(path, uid, gid); }
+    @UnsupportedAppUsage
     public void link(String oldPath, String newPath) throws ErrnoException { os.link(oldPath, newPath); }
     public void listen(FileDescriptor fd, int backlog) throws ErrnoException { os.listen(fd, backlog); }
     public String[] listxattr(String path) throws ErrnoException { return os.listxattr(path); }
     public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return os.lseek(fd, offset, whence); }
+    @UnsupportedAppUsage
     public StructStat lstat(String path) throws ErrnoException { return os.lstat(path); }
     public void mincore(long address, long byteCount, byte[] vector) throws ErrnoException { os.mincore(address, byteCount, vector); }
+    @UnsupportedAppUsage
     public void mkdir(String path, int mode) throws ErrnoException { os.mkdir(path, mode); }
+    @UnsupportedAppUsage
     public void mkfifo(String path, int mode) throws ErrnoException { os.mkfifo(path, mode); }
     public void mlock(long address, long byteCount) throws ErrnoException { os.mlock(address, byteCount); }
     public long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException { return os.mmap(address, byteCount, prot, flags, fd, offset); }
     public void msync(long address, long byteCount, int flags) throws ErrnoException { os.msync(address, byteCount, flags); }
     public void munlock(long address, long byteCount) throws ErrnoException { os.munlock(address, byteCount); }
     public void munmap(long address, long byteCount) throws ErrnoException { os.munmap(address, byteCount); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { return os.open(path, flags, mode); }
     public FileDescriptor[] pipe2(int flags) throws ErrnoException { return os.pipe2(flags); }
     public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException { return os.poll(fds, timeoutMs); }
@@ -145,19 +175,26 @@
     public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { return os.pwrite(fd, bytes, byteOffset, byteCount, offset); }
     public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.read(fd, buffer); }
     public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return os.read(fd, bytes, byteOffset, byteCount); }
+    @UnsupportedAppUsage
     public String readlink(String path) throws ErrnoException { return os.readlink(path); }
     public String realpath(String path) throws ErrnoException { return os.realpath(path); }
     public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return os.readv(fd, buffers, offsets, byteCounts); }
     public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, buffer, flags, srcAddress); }
     public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public void remove(String path) throws ErrnoException { os.remove(path); }
+    @UnsupportedAppUsage
     public void removexattr(String path, String name) throws ErrnoException { os.removexattr(path, name); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); }
     public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, offset, byteCount); }
     public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, buffer, flags, inetAddress, port); }
     public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); }
     public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
     public void setegid(int egid) throws ErrnoException { os.setegid(egid); }
+    @UnsupportedAppUsage
     public void setenv(String name, String value, boolean overwrite) throws ErrnoException { os.setenv(name, value, overwrite); }
     public void seteuid(int euid) throws ErrnoException { os.seteuid(euid); }
     public void setgid(int gid) throws ErrnoException { os.setgid(gid); }
@@ -171,27 +208,38 @@
     public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptIpMreqn(fd, level, option, value); }
     public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { os.setsockoptGroupReq(fd, level, option, value); }
     public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { os.setsockoptLinger(fd, level, option, value); }
+    @UnsupportedAppUsage
     public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { os.setsockoptTimeval(fd, level, option, value); }
     public void setuid(int uid) throws ErrnoException { os.setuid(uid); }
+    @UnsupportedAppUsage
     public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException { os.setxattr(path, name, value, flags); }
     public void shutdown(FileDescriptor fd, int how) throws ErrnoException { os.shutdown(fd, how); }
     public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { return os.socket(domain, type, protocol); }
     public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { os.socketpair(domain, type, protocol, fd1, fd2); }
     public long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException { return os.splice(fdIn, offIn, fdOut, offOut, len, flags); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public StructStat stat(String path) throws ErrnoException { return os.stat(path); }
+    @UnsupportedAppUsage
     public StructStatVfs statvfs(String path) throws ErrnoException { return os.statvfs(path); }
     public String strerror(int errno) { return os.strerror(errno); }
     public String strsignal(int signal) { return os.strsignal(signal); }
+    @UnsupportedAppUsage
     public void symlink(String oldPath, String newPath) throws ErrnoException { os.symlink(oldPath, newPath); }
+    @UnsupportedAppUsage
     public long sysconf(int name) { return os.sysconf(name); }
     public void tcdrain(FileDescriptor fd) throws ErrnoException { os.tcdrain(fd); }
     public void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException { os.tcsendbreak(fd, duration); }
     public int umask(int mask) { return os.umask(mask); }
     public StructUtsname uname() { return os.uname(); }
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public void unlink(String pathname) throws ErrnoException { os.unlink(pathname); }
     public void unsetenv(String name) throws ErrnoException { os.unsetenv(name); }
     public int waitpid(int pid, Int32Ref status, int options) throws ErrnoException { return os.waitpid(pid, status, options); }
     public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.write(fd, buffer); }
     public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { return os.write(fd, bytes, byteOffset, byteCount); }
     public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { return os.writev(fd, buffers, offsets, byteCounts); }
+
+    public String toString() { return "ForwardingOs{os=" + os + "}"; }
 }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index a950bf5..0631176 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -22,6 +22,10 @@
 import android.system.StructLinger;
 import android.system.StructPollfd;
 import android.system.StructTimeval;
+
+import libcore.util.ArrayUtils;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -41,14 +45,16 @@
 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.*;
 
 /**
  * Implements java.io/java.net/java.nio semantics in terms of the underlying POSIX system calls.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class IoBridge {
 
     private IoBridge() {
@@ -227,28 +233,30 @@
     }
 
     /**
-     * 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.
      */
+    @libcore.api.CorePlatformApi
     public static void closeAndSignalBlockedThreads(FileDescriptor fd) throws IOException {
         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();
         }
     }
 
+    @UnsupportedAppUsage
     public static boolean isConnected(FileDescriptor fd, InetAddress inetAddress, int port,
             int timeoutMs, int remainingTimeoutMs) throws IOException {
         ErrnoException cause;
@@ -273,7 +281,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);
     }
@@ -463,6 +473,7 @@
      * directories: POSIX says read-only is okay, but java.io doesn't even allow that. We also
      * have an Android-specific hack to alter the default permissions.
      */
+    @libcore.api.CorePlatformApi
     public static FileDescriptor open(String path, int flags) throws FileNotFoundException {
         FileDescriptor fd = null;
         try {
@@ -478,7 +489,7 @@
         } catch (ErrnoException errnoException) {
             try {
                 if (fd != null) {
-                    IoUtils.close(fd);
+                    closeAndSignalBlockedThreads(fd);
                 }
             } catch (IOException ignored) {
             }
@@ -492,8 +503,9 @@
      * java.io thinks that a read at EOF is an error and should return -1, contrary to traditional
      * Unix practice where you'd read until you got 0 bytes (and any future read would return -1).
      */
+    @libcore.api.CorePlatformApi
     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;
         }
@@ -516,8 +528,9 @@
      * java.io always writes every byte it's asked to, or fails with an error. (That is, unlike
      * Unix it never just writes as many bytes as happens to be convenient.)
      */
+    @libcore.api.CorePlatformApi
     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;
         }
@@ -532,6 +545,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws IOException {
         boolean isDatagram = (inetAddress != null);
         if (!isDatagram && byteCount <= 0) {
@@ -576,6 +590,7 @@
         throw errnoException.rethrowAsIOException();
     }
 
+    @libcore.api.CorePlatformApi
     public static int recvfrom(boolean isRead, FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, DatagramPacket packet, boolean isConnected) throws IOException {
         int result;
         try {
@@ -627,13 +642,16 @@
             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();
             }
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static FileDescriptor socket(int domain, int type, int protocol) throws SocketException {
         FileDescriptor fd;
         try {
@@ -671,6 +689,7 @@
     /**
      * @throws SocketException if fd is not currently bound to an InetSocketAddress
      */
+    @libcore.api.CorePlatformApi
     public static InetSocketAddress getLocalInetSocketAddress(FileDescriptor fd)
             throws SocketException {
         try {
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index b01759d..564393b 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -26,30 +26,139 @@
 import java.net.Socket;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
-import java.util.Random;
+import java.util.Objects;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import libcore.util.NonNull;
 import static android.system.OsConstants.*;
 
+/** @hide */
+@libcore.api.CorePlatformApi
 public final class IoUtils {
     private IoUtils() {
     }
 
     /**
+     * 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
+     */
+    @libcore.api.CorePlatformApi
+    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
+     */
+    @libcore.api.CorePlatformApi
+    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.
      */
+    @libcore.api.CorePlatformApi
     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);
     }
 
     /**
      * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void closeQuietly(AutoCloseable closeable) {
         if (closeable != null) {
             try {
@@ -64,6 +173,8 @@
     /**
      * Closes 'fd', ignoring any exceptions. Does nothing if 'fd' is null or invalid.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void closeQuietly(FileDescriptor fd) {
         try {
             IoUtils.close(fd);
@@ -74,6 +185,8 @@
     /**
      * Closes 'socket', ignoring any exceptions. Does nothing if 'socket' is null.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void closeQuietly(Socket socket) {
         if (socket != null) {
             try {
@@ -86,6 +199,8 @@
     /**
      * Sets 'fd' to be blocking or non-blocking, according to the state of 'blocking'.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void setBlocking(FileDescriptor fd, boolean blocking) throws IOException {
         try {
             int flags = Libcore.os.fcntlVoid(fd, F_GETFL);
@@ -103,6 +218,8 @@
     /**
      * Returns the contents of 'path' as a byte array.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static byte[] readFileAsByteArray(String absolutePath) throws IOException {
         return new FileReader(absolutePath).readFully().toByteArray();
     }
@@ -110,6 +227,8 @@
     /**
      * Returns the contents of 'path' as a string. The contents are assumed to be UTF-8.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static String readFileAsString(String absolutePath) throws IOException {
         return new FileReader(absolutePath).readFully().toString(StandardCharsets.UTF_8);
     }
@@ -121,8 +240,10 @@
      * Deliberately ignores errors, on the assumption that test cleanup is only
      * supposed to be best-effort.
      *
-     * @deprecated Use {@link #createTemporaryDirectory} instead.
+     * @deprecated Use {@link TestIoUtils#createTemporaryDirectory} instead.
      */
+    @libcore.api.CorePlatformApi
+    @Deprecated
     public static void deleteContents(File dir) throws IOException {
         File[] files = dir.listFiles();
         if (files != null) {
@@ -137,7 +258,11 @@
 
     /**
      * Creates a unique new temporary directory under "java.io.tmpdir".
+     *
+     * @deprecated Use {@link TestIoUtils#createTemporaryDirectory} instead.
      */
+    @libcore.api.CorePlatformApi
+    @Deprecated
     public static File createTemporaryDirectory(String prefix) {
         while (true) {
             String candidateName = prefix + Math.randomIntInternal();
diff --git a/luni/src/main/java/libcore/io/Libcore.java b/luni/src/main/java/libcore/io/Libcore.java
index cbc5a55..823d866 100644
--- a/luni/src/main/java/libcore/io/Libcore.java
+++ b/luni/src/main/java/libcore/io/Libcore.java
@@ -16,6 +16,10 @@
 
 package libcore.io;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import java.util.Objects;
+
+/** @hide */
 public final class Libcore {
     private Libcore() { }
 
@@ -24,10 +28,35 @@
      * unless it has a strong reason to bypass the helpful checks/guards that it
      * provides.
      */
-    public static Os rawOs = new Linux();
+    public static final Os rawOs = new Linux();
 
     /**
      * Access to syscalls with helpful checks/guards.
+     * For read access only; the only supported way to update this field is via
+     * {@link #compareAndSetOs}.
      */
-    public static Os os = new BlockGuardOs(rawOs);
+    @UnsupportedAppUsage
+    public static volatile Os os = new BlockGuardOs(rawOs);
+
+    public static Os getOs() {
+        return os;
+    }
+
+    /**
+     * Updates {@link #os} if {@code os == expect}. The update is atomic with
+     * respect to other invocations of this method.
+     */
+    public static boolean compareAndSetOs(Os expect, Os update) {
+        Objects.requireNonNull(update);
+        if (os != expect) {
+            return false;
+        }
+        synchronized (Libcore.class) {
+            boolean result = (os == expect);
+            if (result) {
+                os = update;
+            }
+            return result;
+        }
+    }
 }
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/Memory.java b/luni/src/main/java/libcore/io/Memory.java
index ba7398d..4042300 100644
--- a/luni/src/main/java/libcore/io/Memory.java
+++ b/luni/src/main/java/libcore/io/Memory.java
@@ -17,6 +17,7 @@
 
 package libcore.io;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.FastNative;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -25,7 +26,10 @@
 
 /**
  * Unsafe access to memory.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class Memory {
     private Memory() { }
 
@@ -43,6 +47,7 @@
     public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount,
             Object src, int srcOffset, int sizeofElements, boolean swap);
 
+    @libcore.api.CorePlatformApi
     public static int peekInt(byte[] src, int offset, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             return (((src[offset++] & 0xff) << 24) |
@@ -81,6 +86,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static short peekShort(byte[] src, int offset, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff));
@@ -89,6 +95,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             dst[offset++] = (byte) ((value >> 24) & 0xff);
@@ -103,6 +110,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             int i = (int) (value >> 32);
@@ -129,6 +137,7 @@
         }
     }
 
+    @libcore.api.CorePlatformApi
     public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             dst[offset++] = (byte) ((value >> 8) & 0xff);
@@ -149,11 +158,14 @@
      *
      * @hide make type-safe before making public?
      */
+    @libcore.api.CorePlatformApi
     public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount);
 
+    @UnsupportedAppUsage
     @FastNative
     public static native byte peekByte(long address);
 
+    @UnsupportedAppUsage
     public static int peekInt(long address, boolean swap) {
         int result = peekIntNative(address);
         if (swap) {
@@ -164,6 +176,7 @@
     @FastNative
     private static native int peekIntNative(long address);
 
+    @UnsupportedAppUsage
     public static long peekLong(long address, boolean swap) {
         long result = peekLongNative(address);
         if (swap) {
@@ -184,6 +197,7 @@
     @FastNative
     private static native short peekShortNative(long address);
 
+    @UnsupportedAppUsage
     public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount);
     public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap);
     public static native void peekDoubleArray(long address, double[] dst, int dstOffset, int doubleCount, boolean swap);
@@ -192,9 +206,11 @@
     public static native void peekLongArray(long address, long[] dst, int dstOffset, int longCount, boolean swap);
     public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap);
 
+    @UnsupportedAppUsage
     @FastNative
     public static native void pokeByte(long address, byte value);
 
+    @UnsupportedAppUsage
     public static void pokeInt(long address, int value, boolean swap) {
         if (swap) {
             value = Integer.reverseBytes(value);
@@ -204,6 +220,7 @@
     @FastNative
     private static native void pokeIntNative(long address, int value);
 
+    @UnsupportedAppUsage
     public static void pokeLong(long address, long value, boolean swap) {
         if (swap) {
             value = Long.reverseBytes(value);
@@ -222,6 +239,7 @@
     @FastNative
     private static native void pokeShortNative(long address, short value);
 
+    @UnsupportedAppUsage
     public static native void pokeByteArray(long address, byte[] src, int offset, int count);
     public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap);
     public static native void pokeDoubleArray(long address, double[] src, int offset, int count, boolean swap);
diff --git a/luni/src/main/java/libcore/io/MemoryMappedFile.java b/luni/src/main/java/libcore/io/MemoryMappedFile.java
index 4c73683..20b08e5 100644
--- a/luni/src/main/java/libcore/io/MemoryMappedFile.java
+++ b/luni/src/main/java/libcore/io/MemoryMappedFile.java
@@ -17,6 +17,7 @@
 package libcore.io;
 
 import android.system.ErrnoException;
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.RandomAccessFile;
@@ -50,6 +51,7 @@
     /**
      * Use this to mmap the whole file read-only.
      */
+    @UnsupportedAppUsage
     public static MemoryMappedFile mmapRO(String path) throws ErrnoException {
         FileDescriptor fd = Libcore.os.open(path, O_RDONLY, 0);
         try {
@@ -83,6 +85,7 @@
     /**
      * Returns a new iterator that treats the mapped data as big-endian.
      */
+    @UnsupportedAppUsage
     public BufferIterator bigEndianIterator() {
         return new NioBufferIterator(
                 this, address, size, ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN);
diff --git a/luni/src/main/java/libcore/io/NioBufferIterator.java b/luni/src/main/java/libcore/io/NioBufferIterator.java
index 0f3f920..263666d 100644
--- a/luni/src/main/java/libcore/io/NioBufferIterator.java
+++ b/luni/src/main/java/libcore/io/NioBufferIterator.java
@@ -81,16 +81,16 @@
 
     public int readInt() {
         file.checkNotClosed();
-        checkReadBounds(position, length, SizeOf.INT);
+        checkReadBounds(position, length, Integer.BYTES);
         int result = Memory.peekInt(address + position, swap);
-        position += SizeOf.INT;
+        position += Integer.BYTES;
         return result;
     }
 
     public void readIntArray(int[] dst, int dstOffset, int intCount) {
         checkDstBounds(dstOffset, dst.length, intCount);
         file.checkNotClosed();
-        final int byteCount = SizeOf.INT * intCount;
+        final int byteCount = Integer.BYTES * intCount;
         checkReadBounds(position, length, byteCount);
         Memory.peekIntArray(address + position, dst, dstOffset, intCount, swap);
         position += byteCount;
@@ -98,9 +98,9 @@
 
     public short readShort() {
         file.checkNotClosed();
-        checkReadBounds(position, length, SizeOf.SHORT);
+        checkReadBounds(position, length, Short.BYTES);
         short result = Memory.peekShort(address + position, swap);
-        position += SizeOf.SHORT;
+        position += Short.BYTES;
         return result;
     }
 
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 61584b4..e1ffa48 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -36,6 +36,7 @@
 import android.system.StructUcred;
 import android.system.StructUtsname;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
@@ -44,6 +45,8 @@
 import java.net.SocketException;
 import java.nio.ByteBuffer;
 
+/** @hide */
+@libcore.api.CorePlatformApi
 public interface Os {
     public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
     public boolean access(String path, int mode) throws ErrnoException;
@@ -52,9 +55,18 @@
     public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
     public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
     public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
+    @UnsupportedAppUsage
     public void chmod(String path, int mode) throws ErrnoException;
     public void chown(String path, int uid, int gid) throws ErrnoException;
+
+    @UnsupportedAppUsage
     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);
+
+    @UnsupportedAppUsage
     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;
@@ -72,6 +84,7 @@
     public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException;
     public void fsync(FileDescriptor fd) throws ErrnoException;
     public void ftruncate(FileDescriptor fd, long length) throws ErrnoException;
+    @UnsupportedAppUsage
     public String gai_strerror(int error);
     public int getegid();
     public int geteuid();
@@ -116,10 +129,13 @@
     public void mkdir(String path, int mode) throws ErrnoException;
     public void mkfifo(String path, int mode) throws ErrnoException;
     public void mlock(long address, long byteCount) throws ErrnoException;
+    @UnsupportedAppUsage
     public long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException;
     public void msync(long address, long byteCount, int flags) throws ErrnoException;
     public void munlock(long address, long byteCount) throws ErrnoException;
+    @UnsupportedAppUsage
     public void munmap(long address, long byteCount) throws ErrnoException;
+    @UnsupportedAppUsage
     public FileDescriptor open(String path, int flags, int mode) throws ErrnoException;
     public FileDescriptor[] pipe2(int flags) throws ErrnoException;
     /* TODO: if we used the non-standard ppoll(2) behind the scenes, we could take a long timeout. */
@@ -131,12 +147,14 @@
     public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException;
     public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException;
     public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
+    @UnsupportedAppUsage
     public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException;
     public String readlink(String path) throws ErrnoException;
     public String realpath(String path) throws ErrnoException;
     public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
     public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
     public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
+    @UnsupportedAppUsage
     public void remove(String path) throws ErrnoException;
     public void removexattr(String path, String name) throws ErrnoException;
     public void rename(String oldPath, String newPath) throws ErrnoException;
@@ -145,6 +163,7 @@
     public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException;
     public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException;
     public void setegid(int egid) throws ErrnoException;
+    @UnsupportedAppUsage
     public void setenv(String name, String value, boolean overwrite) throws ErrnoException;
     public void seteuid(int euid) throws ErrnoException;
     public void setgid(int gid) throws ErrnoException;
@@ -158,6 +177,7 @@
     public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
     public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException;
     public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
+    @UnsupportedAppUsage
     public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
     public void setuid(int uid) throws ErrnoException;
     public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException;
@@ -165,11 +185,14 @@
     public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException;
     public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException;
     public long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException;
+    @UnsupportedAppUsage
     public StructStat stat(String path) throws ErrnoException;
     public StructStatVfs statvfs(String path) throws ErrnoException;
+    @UnsupportedAppUsage
     public String strerror(int errno);
     public String strsignal(int signal);
     public void symlink(String oldPath, String newPath) throws ErrnoException;
+    @UnsupportedAppUsage
     public long sysconf(int name);
     public void tcdrain(FileDescriptor fd) throws ErrnoException;
     public void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException;
@@ -181,4 +204,25 @@
     public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
     public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException;
     public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException;
+
+    /**
+     * Atomically sets the system's default {@link Os} implementation to be
+     * {@code update} if the current value {@code == expect}.
+     *
+     * @param expect the expected value.
+     * @param update the new value to set; must not be null.
+     * @return whether the update was successful.
+     */
+    @libcore.api.CorePlatformApi
+    public static boolean compareAndSetDefault(Os expect, Os update) {
+        return Libcore.compareAndSetOs(expect, update);
+    }
+
+    /**
+     * @return the system's default {@link Os} implementation currently in use.
+     */
+    @libcore.api.CorePlatformApi
+    public static Os getDefault() {
+        return Libcore.getOs();
+    }
 }
diff --git a/luni/src/main/java/libcore/io/SizeOf.java b/luni/src/main/java/libcore/io/SizeOf.java
deleted file mode 100644
index 728fbfc..0000000
--- a/luni/src/main/java/libcore/io/SizeOf.java
+++ /dev/null
@@ -1,29 +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.io;
-
-public final class SizeOf {
-    public static final int CHAR = 2;
-    public static final int DOUBLE = 8;
-    public static final int FLOAT = 4;
-    public static final int INT = 4;
-    public static final int LONG = 8;
-    public static final int SHORT = 2;
-
-    private SizeOf() {
-    }
-}
diff --git a/luni/src/main/java/libcore/io/Streams.java b/luni/src/main/java/libcore/io/Streams.java
index 1f78edd..4274399 100644
--- a/luni/src/main/java/libcore/io/Streams.java
+++ b/luni/src/main/java/libcore/io/Streams.java
@@ -16,6 +16,9 @@
 
 package libcore.io;
 
+import libcore.util.ArrayUtils;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
@@ -23,9 +26,10 @@
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.StringWriter;
-import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicReference;
 
+/** @hide */
+@libcore.api.CorePlatformApi
 public final class Streams {
     private static AtomicReference<byte[]> skipBuffer = new AtomicReference<byte[]>();
 
@@ -36,6 +40,8 @@
      * InputStream assumes that you implement InputStream.read(int) and provides default
      * implementations of the others, but often the opposite is more efficient.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static int readSingleByte(InputStream in) throws IOException {
         byte[] buffer = new byte[1];
         int result = in.read(buffer, 0, 1);
@@ -47,6 +53,8 @@
      * OutputStream assumes that you implement OutputStream.write(int) and provides default
      * implementations of the others, but often the opposite is more efficient.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void writeSingleByte(OutputStream out, int b) throws IOException {
         byte[] buffer = new byte[1];
         buffer[0] = (byte) (b & 0xff);
@@ -56,6 +64,8 @@
     /**
      * Fills 'dst' with bytes from 'in', throwing EOFException if insufficient bytes are available.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static void readFully(InputStream in, byte[] dst) throws IOException {
         readFully(in, dst, 0, dst.length);
     }
@@ -76,7 +86,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) {
@@ -90,6 +100,8 @@
     /**
      * Returns a byte[] containing the remainder of 'in', closing it when done.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static byte[] readFully(InputStream in) throws IOException {
         try {
             return readFullyNoClose(in);
@@ -101,6 +113,7 @@
     /**
      * Returns a byte[] containing the remainder of 'in'.
      */
+    @libcore.api.CorePlatformApi
     public static byte[] readFullyNoClose(InputStream in) throws IOException {
         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
@@ -114,6 +127,7 @@
     /**
      * Returns the remainder of 'reader' as a string, closing it when done.
      */
+    @libcore.api.CorePlatformApi
     public static String readFully(Reader reader) throws IOException {
         try {
             StringWriter writer = new StringWriter();
@@ -128,6 +142,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static void skipAll(InputStream in) throws IOException {
         do {
             in.skip(Long.MAX_VALUE);
@@ -146,6 +161,7 @@
      * streams may call other streams in their skip() method, also clobbering the
      * buffer.
      */
+    @libcore.api.CorePlatformApi
     public static long skipByReading(InputStream in, long byteCount) throws IOException {
         // acquire the shared skip buffer.
         byte[] buffer = skipBuffer.getAndSet(null);
@@ -176,6 +192,8 @@
      * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
      * Returns the total number of bytes transferred.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static int copy(InputStream in, OutputStream out) throws IOException {
         int total = 0;
         byte[] buffer = new byte[8192];
@@ -194,6 +212,7 @@
      * @throws java.io.EOFException if the stream is exhausted before the next newline
      *     character.
      */
+    @UnsupportedAppUsage
     public static String readAsciiLine(InputStream in) throws IOException {
         // TODO: support UTF-8 here instead
 
diff --git a/luni/src/main/java/libcore/net/InetAddressUtils.java b/luni/src/main/java/libcore/net/InetAddressUtils.java
new file mode 100644
index 0000000..9da4a70
--- /dev/null
+++ b/luni/src/main/java/libcore/net/InetAddressUtils.java
@@ -0,0 +1,106 @@
+/*
+ * 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.net;
+
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import libcore.io.Libcore;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AI_NUMERICHOST;
+
+/**
+ * Android specific utility methods for {@link InetAddress} instances.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public class InetAddressUtils {
+
+    private static final int NETID_UNSET = 0;
+
+    private InetAddressUtils() {
+    }
+
+    /**
+     * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or
+     * {@code "2001:db8::1:2"}).
+     *
+     * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an
+     * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or
+     * do not have exactly 4 numbers are not treated as numeric.
+     *
+     * <p>This method will never do a DNS lookup.
+     *
+     * @param address the address to parse.
+     * @return true if the supplied address is numeric, false otherwise.
+     */
+    @libcore.api.CorePlatformApi
+    public static boolean isNumericAddress(String address) {
+        return parseNumericAddressNoThrow(address) != null;
+    }
+
+    /**
+     * Returns an InetAddress corresponding to the given numeric address (such
+     * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
+     *
+     * <p>See {@link #isNumericAddress(String)} for a definition as to what constitutes a numeric
+     * address.
+     *
+     * <p>This method will never do a DNS lookup.
+     *
+     * @param address the address to parse, must be numeric.
+     * @return an {@link InetAddress} instance corresponding to the address.
+     * @throws IllegalArgumentException if {@code address} is not a numeric address.
+     */
+    @libcore.api.CorePlatformApi
+    public static InetAddress parseNumericAddress(String address) {
+        InetAddress result = parseNumericAddressNoThrow(address);
+        if (result == null) {
+            throw new IllegalArgumentException("Not a numeric address: " + address);
+        }
+        return result;
+    }
+
+    public static InetAddress parseNumericAddressNoThrow(String address) {
+        StructAddrinfo hints = new StructAddrinfo();
+        hints.ai_flags = AI_NUMERICHOST;
+        InetAddress[] addresses = null;
+        try {
+            addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);
+        } catch (GaiException ignored) {
+        }
+        if (addresses == null) {
+            return null;
+        }
+        return addresses[0];
+    }
+
+    /**
+     * Like {@link #parseNumericAddressNoThrow(String)}}, but strips optional []
+     * around a numeric IPv6 address.
+     */
+    public static InetAddress parseNumericAddressNoThrowStripOptionalBrackets(String address) {
+        // Accept IPv6 addresses (only) in square brackets for compatibility.
+        if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
+            address = address.substring(1, address.length() - 1);
+        }
+        return InetAddressUtils.parseNumericAddressNoThrow(address);
+    }
+}
diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java
index 3ab4300..8cd0147 100644
--- a/luni/src/main/java/libcore/net/MimeUtils.java
+++ b/luni/src/main/java/libcore/net/MimeUtils.java
@@ -16,397 +16,92 @@
 
 package libcore.net;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+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.
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public final class MimeUtils {
-    private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<String, String>();
 
-    private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
+    private static final Pattern splitPattern = Pattern.compile("\\s+");
+
+    /**
+     * Note: These maps only contain lowercase keys/values, regarded as the
+     * {@link #canonicalize(String) canonical form}.
+     *
+     * <p>This is the case for both extensions and MIME types. The mime.types
+     * data file contains examples of mixed-case MIME types, but some applications
+     * use the lowercase version of these same types. RFC 2045 section 2 states
+     * that MIME types are case insensitive.
+     */
+    private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<>();
+    private static final Map<String, String> extensionToMimeTypeMap = new HashMap<>();
 
     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;
+                }
+
+                final String[] split = splitPattern.split(line);
+                final String mimeType = canonicalize(split[0]);
+                if (!allowedInMap(mimeType)) {
+                    throw new IllegalArgumentException(
+                            "Invalid mimeType " + mimeType + " in: " + line);
+                }
+                for (int i = 1; i < split.length; i++) {
+                    String extension = canonicalize(split[i]);
+                    if (!allowedInMap(extension)) {
+                        throw new IllegalArgumentException(
+                                "Invalid extension " + extension + " in: " + line);
+                    }
+
+                    // 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);
         }
     }
 
@@ -414,11 +109,27 @@
     }
 
     /**
+     * Returns the canonical (lowercase) form of the given extension or MIME type.
+     */
+    private static String canonicalize(String s) {
+        return s.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Checks whether the given extension or MIME type might be valid and
+     * therefore may appear in the mimeType <-> extension maps.
+     */
+    private static boolean allowedInMap(String s) {
+        return s != null && !s.isEmpty();
+    }
+
+    /**
      * Returns true if the given case insensitive MIME type has an entry in the map.
      * @param mimeType A MIME type (i.e. text/plain)
      * @return True if a extension has been registered for
      * the given case insensitive MIME type.
      */
+    @libcore.api.CorePlatformApi
     public static boolean hasMimeType(String mimeType) {
         return (guessExtensionFromMimeType(mimeType) != null);
     }
@@ -429,11 +140,13 @@
      * @return The MIME type has been registered for
      * the given case insensitive file extension or null if there is none.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static String guessMimeTypeFromExtension(String extension) {
-        if (extension == null || extension.isEmpty()) {
+        if (!allowedInMap(extension)) {
             return null;
         }
-        extension = extension.toLowerCase(Locale.US);
+        extension = canonicalize(extension);
         return extensionToMimeTypeMap.get(extension);
     }
 
@@ -443,6 +156,7 @@
      * @return True if a MIME type has been registered for
      * the given case insensitive file extension.
      */
+    @libcore.api.CorePlatformApi
     public static boolean hasExtension(String extension) {
         return (guessMimeTypeFromExtension(extension) != null);
     }
@@ -455,11 +169,13 @@
      * @return The extension has been registered for
      * the given case insensitive MIME type or null if there is none.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static String guessExtensionFromMimeType(String mimeType) {
-        if (mimeType == null || mimeType.isEmpty()) {
+        if (!allowedInMap(mimeType)) {
             return null;
         }
-        mimeType = mimeType.toLowerCase(Locale.US);
+        mimeType = canonicalize(mimeType);
         return mimeTypeToExtensionMap.get(mimeType);
     }
 }
diff --git a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
index d9c87a4..3a3a5d9 100644
--- a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -16,6 +16,8 @@
 
 package libcore.net;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * Network security policy for this process/application.
  *
@@ -25,15 +27,27 @@
  *
  * <p>The policy currently consists of a single flag: whether cleartext network traffic is
  * permitted. See {@link #isCleartextTrafficPermitted()}.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
 public abstract class NetworkSecurityPolicy {
 
     private static volatile NetworkSecurityPolicy instance = new DefaultNetworkSecurityPolicy();
 
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
+    public NetworkSecurityPolicy() {
+    }
+
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public static NetworkSecurityPolicy getInstance() {
         return instance;
     }
 
+    @libcore.api.CorePlatformApi
     public static void setInstance(NetworkSecurityPolicy policy) {
         if (policy == null) {
             throw new NullPointerException("policy == null");
@@ -60,6 +74,8 @@
      * this flag from day one, and well-established third-party network stacks will eventually
      * honor it.
      */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public abstract boolean isCleartextTrafficPermitted();
 
     /**
@@ -69,6 +85,7 @@
      *
      * <p>See {@link #isCleartextTrafficPermitted} for more details.
      */
+    @libcore.api.CorePlatformApi
     public abstract boolean isCleartextTrafficPermitted(String hostname);
 
     /**
@@ -77,6 +94,8 @@
      *
      * <p>See RFC6962 section 3.3 for more details.
      */
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
     public abstract boolean isCertificateTransparencyVerificationRequired(String hostname);
 
     public static final class DefaultNetworkSecurityPolicy extends NetworkSecurityPolicy {
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..6332489
--- /dev/null
+++ b/luni/src/main/java/libcore/net/android.mime.types
@@ -0,0 +1,99 @@
+
+###############################################################################
+#
+#  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
+# Note: We rely here on the fact that we're declaring this mapping before the
+# line "text/xml xml" below, because we don't want to change the mapping from
+# extension "xml" back to MIME type "text/xml".
+application/x-wifi-config xml
+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/MP2T m2ts MTS
+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 m4r
+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/vnd.youtube.yt yt
+video/x-matroska mkv!
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
index d1c7c21..5399e89 100644
--- a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
+++ b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
@@ -16,12 +16,16 @@
 
 package libcore.net.event;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * A singleton used to dispatch network events to registered listeners.
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class NetworkEventDispatcher {
 
   private static final NetworkEventDispatcher instance = new NetworkEventDispatcher();
@@ -32,6 +36,8 @@
   /**
    * Returns the shared {@link NetworkEventDispatcher} instance.
    */
+  @UnsupportedAppUsage
+  @libcore.api.CorePlatformApi
   public static NetworkEventDispatcher getInstance() {
     return instance;
   }
@@ -44,6 +50,7 @@
    * Registers a listener to be notified when network events occur.
    * It can be deregistered using {@link #removeListener(NetworkEventListener)}
    */
+  @UnsupportedAppUsage
   public void addListener(NetworkEventListener toAdd) {
     if (toAdd == null) {
       throw new NullPointerException("toAdd == null");
@@ -67,6 +74,7 @@
   /**
    * Notifies registered listeners of a network configuration change.
    */
+  @libcore.api.CorePlatformApi
   public void onNetworkConfigurationChanged() {
     for (NetworkEventListener listener : listeners) {
       try {
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventListener.java b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
index 73b9f88..d7d011b 100644
--- a/luni/src/main/java/libcore/net/event/NetworkEventListener.java
+++ b/luni/src/main/java/libcore/net/event/NetworkEventListener.java
@@ -16,11 +16,17 @@
 
 package libcore.net.event;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * A base class for objects interested in network events.
  */
 public class NetworkEventListener {
 
+  @UnsupportedAppUsage
+  public NetworkEventListener() {
+  }
+
   public void onNetworkConfigurationChanged() {
     // no-op
   }
diff --git a/luni/src/main/java/libcore/net/http/HttpDate.java b/luni/src/main/java/libcore/net/http/HttpDate.java
index a41cf81..c295503 100644
--- a/luni/src/main/java/libcore/net/http/HttpDate.java
+++ b/luni/src/main/java/libcore/net/http/HttpDate.java
@@ -16,6 +16,7 @@
 
 package libcore.net.http;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -68,6 +69,7 @@
      * Returns the date for {@code value}. Returns null if the value couldn't be
      * parsed.
      */
+    @UnsupportedAppUsage
     public static Date parse(String value) {
         try {
             return STANDARD_DATE_FORMAT.get().parse(value);
@@ -85,6 +87,7 @@
     /**
      * Returns the string for {@code value}.
      */
+    @UnsupportedAppUsage
     public static String format(Date value) {
         return STANDARD_DATE_FORMAT.get().format(value);
     }
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/timezone/CountryTimeZones.java b/luni/src/main/java/libcore/timezone/CountryTimeZones.java
new file mode 100644
index 0000000..66119d7
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/CountryTimeZones.java
@@ -0,0 +1,503 @@
+/*
+ * 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.timezone;
+
+import android.icu.util.TimeZone;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * Information about a country's time zones.
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public final class CountryTimeZones {
+
+    /**
+     * The result of lookup up a time zone using offset information (and possibly more).
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    public final static class OffsetResult {
+
+        /** A zone that matches the supplied criteria. See also {@link #mOneMatch}. */
+        @libcore.api.CorePlatformApi
+        public final TimeZone mTimeZone;
+
+        /** True if there is one match for the supplied criteria */
+        @libcore.api.CorePlatformApi
+        public final boolean mOneMatch;
+
+        public OffsetResult(TimeZone timeZone, boolean oneMatch) {
+            mTimeZone = java.util.Objects.requireNonNull(timeZone);
+            mOneMatch = oneMatch;
+        }
+
+        @Override
+        public String toString() {
+            return "Result{" +
+                    "mTimeZone='" + mTimeZone + '\'' +
+                    ", mOneMatch=" + mOneMatch +
+                    '}';
+        }
+    }
+
+    /**
+     * A mapping to a time zone ID with some associated metadata.
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    public final static class TimeZoneMapping {
+        @libcore.api.CorePlatformApi
+        public final String timeZoneId;
+        @libcore.api.CorePlatformApi
+        public final boolean showInPicker;
+        @libcore.api.CorePlatformApi
+        public final Long notUsedAfter;
+
+        TimeZoneMapping(String timeZoneId, boolean showInPicker, Long notUsedAfter) {
+            this.timeZoneId = timeZoneId;
+            this.showInPicker = showInPicker;
+            this.notUsedAfter = notUsedAfter;
+        }
+
+        // VisibleForTesting
+        @libcore.api.CorePlatformApi
+        public static TimeZoneMapping createForTests(
+                String timeZoneId, boolean showInPicker, Long notUsedAfter) {
+            return new TimeZoneMapping(timeZoneId, showInPicker, notUsedAfter);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            TimeZoneMapping that = (TimeZoneMapping) o;
+            return showInPicker == that.showInPicker &&
+                    Objects.equals(timeZoneId, that.timeZoneId) &&
+                    Objects.equals(notUsedAfter, that.notUsedAfter);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(timeZoneId, showInPicker, notUsedAfter);
+        }
+
+        @Override
+        public String toString() {
+            return "TimeZoneMapping{"
+                    + "timeZoneId='" + timeZoneId + '\''
+                    + ", showInPicker=" + showInPicker
+                    + ", notUsedAfter=" + notUsedAfter
+                    + '}';
+        }
+
+        /**
+         * Returns {@code true} if one of the supplied {@link TimeZoneMapping} objects is for the
+         * specified time zone ID.
+         */
+        public static boolean containsTimeZoneId(
+                List<TimeZoneMapping> timeZoneMappings, String timeZoneId) {
+            for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
+                if (timeZoneMapping.timeZoneId.equals(timeZoneId)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private final String countryIso;
+    private final String defaultTimeZoneId;
+    private final List<TimeZoneMapping> timeZoneMappings;
+    private final boolean everUsesUtc;
+
+    // Memoized frozen ICU TimeZone object for the default.
+    private TimeZone icuDefaultTimeZone;
+    // Memoized frozen ICU TimeZone objects for the timeZoneIds.
+    private List<TimeZone> icuTimeZones;
+
+    private CountryTimeZones(String countryIso, String defaultTimeZoneId, boolean everUsesUtc,
+            List<TimeZoneMapping> timeZoneMappings) {
+        this.countryIso = java.util.Objects.requireNonNull(countryIso);
+        this.defaultTimeZoneId = defaultTimeZoneId;
+        this.everUsesUtc = everUsesUtc;
+        // Create a defensive copy of the mapping list.
+        this.timeZoneMappings = Collections.unmodifiableList(new ArrayList<>(timeZoneMappings));
+    }
+
+    /**
+     * Creates a {@link CountryTimeZones} object containing only known time zone IDs.
+     */
+    public static CountryTimeZones createValidated(String countryIso, String defaultTimeZoneId,
+            boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo) {
+
+        // We rely on ZoneInfoDB to tell us what the known valid time zone IDs are. ICU may
+        // recognize more but we want to be sure that zone IDs can be used with java.util as well as
+        // android.icu and ICU is expected to have a superset.
+        String[] validTimeZoneIdsArray = ZoneInfoDB.getInstance().getAvailableIDs();
+        HashSet<String> validTimeZoneIdsSet = new HashSet<>(Arrays.asList(validTimeZoneIdsArray));
+        List<TimeZoneMapping> validCountryTimeZoneMappings = new ArrayList<>();
+        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
+            String timeZoneId = timeZoneMapping.timeZoneId;
+            if (!validTimeZoneIdsSet.contains(timeZoneId)) {
+                System.logW("Skipping invalid zone: " + timeZoneId + " at " + debugInfo);
+            } else {
+                validCountryTimeZoneMappings.add(timeZoneMapping);
+            }
+        }
+
+        // We don't get too strict at runtime about whether the defaultTimeZoneId must be
+        // one of the country's time zones because this is the data we have to use (we also
+        // assume the data was validated by earlier steps). The default time zone ID must just
+        // be a recognized zone ID: if it's not valid we leave it null.
+        if (!validTimeZoneIdsSet.contains(defaultTimeZoneId)) {
+            System.logW("Invalid default time zone ID: " + defaultTimeZoneId
+                    + " at " + debugInfo);
+            defaultTimeZoneId = null;
+        }
+
+        String normalizedCountryIso = normalizeCountryIso(countryIso);
+        return new CountryTimeZones(
+                normalizedCountryIso, defaultTimeZoneId, everUsesUtc, validCountryTimeZoneMappings);
+    }
+
+    /**
+     * Returns the ISO code for the country.
+     */
+    @libcore.api.CorePlatformApi
+    public String getCountryIso() {
+        return countryIso;
+    }
+
+    /**
+     * Returns true if the ISO code for the country is a match for the one specified.
+     */
+    @libcore.api.CorePlatformApi
+    public boolean isForCountryCode(String countryIso) {
+        return this.countryIso.equals(normalizeCountryIso(countryIso));
+    }
+
+    /**
+     * Returns the default time zone ID for the country. Can return null in cases when no data is
+     * available or the time zone ID provided to
+     * {@link #createValidated(String, String, boolean, List, String)} was not recognized.
+     */
+    public synchronized TimeZone getDefaultTimeZone() {
+        if (icuDefaultTimeZone == null) {
+            TimeZone defaultTimeZone;
+            if (defaultTimeZoneId == null) {
+                defaultTimeZone = null;
+            } else {
+                defaultTimeZone = getValidFrozenTimeZoneOrNull(defaultTimeZoneId);
+            }
+            icuDefaultTimeZone = defaultTimeZone;
+        }
+        return icuDefaultTimeZone;
+    }
+
+    /**
+     * Returns the default time zone ID for the country. Can return null in cases when no data is
+     * available or the time zone ID provided to
+     * {@link #createValidated(String, String, boolean, List, String)} was not recognized.
+     */
+    @libcore.api.CorePlatformApi
+    public String getDefaultTimeZoneId() {
+        return defaultTimeZoneId;
+    }
+
+    /**
+     * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
+     * "priority" order. The list can be empty if there were no zones configured or the configured
+     * zone IDs were not recognized.
+     */
+    @libcore.api.CorePlatformApi
+    public List<TimeZoneMapping> getTimeZoneMappings() {
+        return timeZoneMappings;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        CountryTimeZones that = (CountryTimeZones) o;
+
+        if (everUsesUtc != that.everUsesUtc) {
+            return false;
+        }
+        if (!countryIso.equals(that.countryIso)) {
+            return false;
+        }
+        if (defaultTimeZoneId != null ? !defaultTimeZoneId.equals(that.defaultTimeZoneId)
+                : that.defaultTimeZoneId != null) {
+            return false;
+        }
+        return timeZoneMappings.equals(that.timeZoneMappings);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = countryIso.hashCode();
+        result = 31 * result + (defaultTimeZoneId != null ? defaultTimeZoneId.hashCode() : 0);
+        result = 31 * result + timeZoneMappings.hashCode();
+        result = 31 * result + (everUsesUtc ? 1 : 0);
+        return result;
+    }
+
+    /**
+     * Returns an ordered list of time zones for the country in an undefined but "priority"
+     * order for a country. The list can be empty if there were no zones configured or the
+     * configured zone IDs were not recognized.
+     */
+    public synchronized List<TimeZone> getIcuTimeZones() {
+        if (icuTimeZones == null) {
+            ArrayList<TimeZone> mutableList = new ArrayList<>(timeZoneMappings.size());
+            for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
+                String timeZoneId = timeZoneMapping.timeZoneId;
+                TimeZone timeZone;
+                if (timeZoneId.equals(defaultTimeZoneId)) {
+                    timeZone = getDefaultTimeZone();
+                } else {
+                    timeZone = getValidFrozenTimeZoneOrNull(timeZoneId);
+                }
+                // This shouldn't happen given the validation that takes place in
+                // createValidatedCountryTimeZones().
+                if (timeZone == null) {
+                    System.logW("Skipping invalid zone: " + timeZoneId);
+                    continue;
+                }
+                mutableList.add(timeZone);
+            }
+            icuTimeZones = Collections.unmodifiableList(mutableList);
+        }
+        return icuTimeZones;
+    }
+
+    /**
+     * Returns true if the country has at least one zone that is the same as UTC at the given time.
+     */
+    @libcore.api.CorePlatformApi
+    public boolean hasUtcZone(long whenMillis) {
+        // If the data tells us the country never uses UTC we don't have to check anything.
+        if (!everUsesUtc) {
+            return false;
+        }
+
+        for (TimeZone zone : getIcuTimeZones()) {
+            if (zone.getOffset(whenMillis) == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if the default time zone for the country is either the only zone used or
+     * if it has the same offsets as all other zones used by the country <em>at the specified time
+     * </em> making the default equivalent to all other zones used by the country <em>at that time
+     * </em>.
+     */
+    @libcore.api.CorePlatformApi
+    public boolean isDefaultOkForCountryTimeZoneDetection(long whenMillis) {
+        if (timeZoneMappings.isEmpty()) {
+            // Should never happen unless there's been an error loading the data.
+            return false;
+        } else if (timeZoneMappings.size() == 1) {
+            // The default is the only zone so it's a good candidate.
+            return true;
+        } else {
+            TimeZone countryDefault = getDefaultTimeZone();
+            if (countryDefault == null) {
+                return false;
+            }
+
+            int countryDefaultOffset = countryDefault.getOffset(whenMillis);
+            List<TimeZone> candidates = getIcuTimeZones();
+            for (TimeZone candidate : candidates) {
+                if (candidate == countryDefault) {
+                    continue;
+                }
+
+                int candidateOffset = candidate.getOffset(whenMillis);
+                if (countryDefaultOffset != candidateOffset) {
+                    // Multiple different offsets means the default should not be used.
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Returns a time zone for the country, if there is one, that has the desired properties. If
+     * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
+     * an arbitrary match is returned based on the {@link #getTimeZoneMappings()} ordering.
+     *
+     * @param offsetMillis the offset from UTC at {@code whenMillis}
+     * @param isDst whether the zone is in DST
+     * @param whenMillis the UTC time to match against
+     * @param bias the time zone to prefer, can be null
+     * @deprecated Use {@link #lookupByOffsetWithBias(int, Integer, long, TimeZone)} instead
+     */
+    @libcore.api.CorePlatformApi
+    @Deprecated
+    public OffsetResult lookupByOffsetWithBias(int offsetMillis, boolean isDst, long whenMillis,
+            TimeZone bias) {
+        if (timeZoneMappings == null || timeZoneMappings.isEmpty()) {
+            return null;
+        }
+
+        List<TimeZone> candidates = getIcuTimeZones();
+
+        TimeZone firstMatch = null;
+        boolean biasMatched = false;
+        boolean oneMatch = true;
+        for (TimeZone match : candidates) {
+            if (!offsetMatchesAtTime(match, offsetMillis, isDst, whenMillis)) {
+                continue;
+            }
+
+            if (firstMatch == null) {
+                firstMatch = match;
+            } else {
+                oneMatch = false;
+            }
+            if (bias != null && match.getID().equals(bias.getID())) {
+                biasMatched = true;
+            }
+            if (firstMatch != null && !oneMatch && (bias == null || biasMatched)) {
+                break;
+            }
+        }
+        if (firstMatch == null) {
+            return null;
+        }
+
+        TimeZone toReturn = biasMatched ? bias : firstMatch;
+        return new OffsetResult(toReturn, oneMatch);
+    }
+
+    /**
+     * Returns {@code true} if the specified offset, DST state and time would be valid in the
+     * timeZone.
+     */
+    private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis, boolean isDst,
+            long whenMillis) {
+        int[] offsets = new int[2];
+        timeZone.getOffset(whenMillis, false /* local */, offsets);
+
+        // offsets[1] == 0 when the zone is not in DST.
+        boolean zoneIsDst = offsets[1] != 0;
+        if (isDst != zoneIsDst) {
+            return false;
+        }
+        return offsetMillis == (offsets[0] + offsets[1]);
+    }
+
+    /**
+     * Returns a time zone for the country, if there is one, that has the desired properties. If
+     * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
+     * an arbitrary match is returned based on the {@link #getTimeZoneMappings()} ordering.
+     *
+     * @param offsetMillis the offset from UTC at {@code whenMillis}
+     * @param dstOffsetMillis the part of {@code offsetMillis} contributed by DST, {@code null}
+     *                        means unknown
+     * @param whenMillis the UTC time to match against
+     * @param bias the time zone to prefer, can be null
+     */
+    public OffsetResult lookupByOffsetWithBias(int offsetMillis, Integer dstOffsetMillis,
+            long whenMillis, TimeZone bias) {
+        if (timeZoneMappings == null || timeZoneMappings.isEmpty()) {
+            return null;
+        }
+
+        List<TimeZone> candidates = getIcuTimeZones();
+
+        TimeZone firstMatch = null;
+        boolean biasMatched = false;
+        boolean oneMatch = true;
+        for (TimeZone match : candidates) {
+            if (!offsetMatchesAtTime(match, offsetMillis, dstOffsetMillis, whenMillis)) {
+                continue;
+            }
+
+            if (firstMatch == null) {
+                firstMatch = match;
+            } else {
+                oneMatch = false;
+            }
+            if (bias != null && match.getID().equals(bias.getID())) {
+                biasMatched = true;
+            }
+            if (firstMatch != null && !oneMatch && (bias == null || biasMatched)) {
+                break;
+            }
+        }
+        if (firstMatch == null) {
+            return null;
+        }
+
+        TimeZone toReturn = biasMatched ? bias : firstMatch;
+        return new OffsetResult(toReturn, oneMatch);
+    }
+
+    /**
+     * Returns {@code true} if the specified offset, DST and time would be valid in the
+     * timeZone.
+     */
+    private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis,
+            Integer dstOffsetMillis, long whenMillis) {
+        int[] offsets = new int[2];
+        timeZone.getOffset(whenMillis, false /* local */, offsets);
+
+        if (dstOffsetMillis != null) {
+            if (dstOffsetMillis.intValue() != offsets[1]) {
+                return false;
+            }
+        }
+        return offsetMillis == (offsets[0] + offsets[1]);
+    }
+
+    private static TimeZone getValidFrozenTimeZoneOrNull(String timeZoneId) {
+        TimeZone timeZone = TimeZone.getFrozenTimeZone(timeZoneId);
+        if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
+            return null;
+        }
+        return timeZone;
+    }
+
+    private static String normalizeCountryIso(String countryIso) {
+        // Lowercase ASCII is normalized for the purposes of the code in this class.
+        return countryIso.toLowerCase(Locale.US);
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/CountryZonesFinder.java b/luni/src/main/java/libcore/timezone/CountryZonesFinder.java
new file mode 100644
index 0000000..92f6631
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/CountryZonesFinder.java
@@ -0,0 +1,87 @@
+/*
+ * 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.timezone;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
+
+/**
+ * An in-memory representation of country &lt;-&gt; time zone mapping data.
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public final class CountryZonesFinder {
+
+    private final List<CountryTimeZones> countryTimeZonesList;
+
+    CountryZonesFinder(List<CountryTimeZones> countryTimeZonesList) {
+        this.countryTimeZonesList = new ArrayList<>(countryTimeZonesList);
+    }
+
+    // VisibleForTesting
+    public static CountryZonesFinder createForTests(List<CountryTimeZones> countryTimeZonesList) {
+        return new CountryZonesFinder(countryTimeZonesList);
+    }
+
+    /**
+     * Returns an immutable list of country ISO codes with time zones. The codes can be passed to
+     * {@link #lookupCountryTimeZones(String)} and similar methods.
+     */
+    @libcore.api.CorePlatformApi
+    public List<String> lookupAllCountryIsoCodes() {
+        List<String> isoCodes = new ArrayList<>(countryTimeZonesList.size());
+        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
+            isoCodes.add(countryTimeZones.getCountryIso());
+        }
+        return Collections.unmodifiableList(isoCodes);
+    }
+
+    /**
+     * Returns an immutable list of {@link CountryTimeZones} for countries that use the specified
+     * time zone. An exact, case-sensitive match is performed on the zone ID. This method never
+     * returns null.
+     */
+    @libcore.api.CorePlatformApi
+    public List<CountryTimeZones> lookupCountryTimeZonesForZoneId(String zoneId) {
+        List<CountryTimeZones> matches = new ArrayList<>(2);
+        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
+            boolean match = TimeZoneMapping.containsTimeZoneId(
+                    countryTimeZones.getTimeZoneMappings(), zoneId);
+            if (match) {
+                matches.add(countryTimeZones);
+            }
+        }
+        return Collections.unmodifiableList(matches);
+    }
+
+    /**
+     * Returns a {@link CountryTimeZones} object associated with the specified country code. If one
+     * cannot be found this method returns {@code null}.
+     */
+    @libcore.api.CorePlatformApi
+    public CountryTimeZones lookupCountryTimeZones(String countryIso) {
+        String normalizedCountryIso = TimeZoneFinder.normalizeCountryIso(countryIso);
+        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
+            if (countryTimeZones.getCountryIso().equals(normalizedCountryIso)) {
+                return countryTimeZones;
+            }
+        }
+        return null;
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java b/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
new file mode 100644
index 0000000..592fac1
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
@@ -0,0 +1,128 @@
+/*
+ * 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.timezone;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods associated with finding updateable time zone data files.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public final class TimeZoneDataFiles {
+    private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
+    private static final String ANDROID_RUNTIME_ROOT_ENV = "ANDROID_RUNTIME_ROOT";
+    private static final String ANDROID_TZDATA_ROOT_ENV = "ANDROID_TZDATA_ROOT";
+    private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
+
+    private TimeZoneDataFiles() {}
+
+    /**
+     * Returns time zone file paths for the specified file name in an array in the order they
+     * should be tried. See {@link #generateIcuDataPath()} for ICU files instead.
+     * <ul>
+     * <li>[0] - the location of the file in the /data partition (may not exist).</li>
+     * <li>[1] - the location of the file from the time zone module under /apex (may not exist).
+     * </li>
+     * <li>[2] - the location of the file from the runtime module under /apex (should exist).</li>
+     * </ul>
+     * <li>[3] - the location of the file in the /system partition (should exist).</li>
+     */
+    // VisibleForTesting
+    public static String[] getTimeZoneFilePaths(String fileName) {
+        return new String[] {
+                getDataTimeZoneFile(fileName),
+                getTimeZoneModuleFile("tz/" + fileName),
+                getRuntimeModuleFile("tz/" + fileName),
+                getSystemTimeZoneFile(fileName)
+        };
+    }
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    @libcore.api.CorePlatformApi
+    public static String getDataTimeZoneRootDir() {
+        return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/";
+    }
+
+    @libcore.api.CorePlatformApi
+    public static String getDataTimeZoneFile(String fileName) {
+        return getDataTimeZoneRootDir() + "current/" + fileName;
+    }
+
+    public static String getTimeZoneModuleFile(String fileName) {
+        return System.getenv(ANDROID_TZDATA_ROOT_ENV) + "/etc/" + fileName;
+    }
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    @libcore.api.CorePlatformApi
+    public static String getRuntimeModuleTzVersionFile() {
+        return getRuntimeModuleFile("tz/" + TzDataSetVersion.DEFAULT_FILE_NAME);
+    }
+
+    public static String getRuntimeModuleFile(String fileName) {
+        return System.getenv(ANDROID_RUNTIME_ROOT_ENV) + "/etc/" + fileName;
+    }
+
+    public static String getSystemTimeZoneFile(String fileName) {
+        return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/share/zoneinfo/" + fileName);
+    }
+
+    public static String getSystemIcuFile(String fileName) {
+        return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu/" + fileName);
+    }
+
+    public static String generateIcuDataPath() {
+        List<String> paths = new ArrayList<>(3);
+
+        // ICU should first look in ANDROID_DATA. This is used for (optional) time zone data
+        // delivered by APK (https://source.android.com/devices/tech/config/timezone-rules)
+        String dataIcuDataPath =
+                getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu/");
+        if (dataIcuDataPath != null) {
+            paths.add(dataIcuDataPath);
+        }
+
+        // ICU should then look for a mounted time zone module file in /apex. This is used for
+        // (optional) time zone data that can be updated with an APEX file.
+        String timeZoneModuleIcuDataPath = getTimeZoneModuleFile("icu/");
+        if (timeZoneModuleIcuDataPath != null) {
+            paths.add(timeZoneModuleIcuDataPath);
+        }
+
+        // ICU should always look in the runtime module path as this is where most of the data
+        // can be found.
+        String runtimeModuleIcuDataPath = getRuntimeModuleFile("icu/");
+        if (runtimeModuleIcuDataPath != null) {
+            paths.add(runtimeModuleIcuDataPath);
+        }
+        return String.join(":", paths);
+    }
+
+    /**
+     * Creates a path by combining the value of an environment variable with a relative path.
+     * Returns {@code null} if the environment variable is not set.
+     */
+    private static String getEnvironmentPath(String environmentVariable, String path) {
+        String variable = System.getenv(environmentVariable);
+        if (variable == null) {
+            return null;
+        }
+        return variable + path;
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/TimeZoneFinder.java b/luni/src/main/java/libcore/timezone/TimeZoneFinder.java
new file mode 100644
index 0000000..eebe8cc
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/TimeZoneFinder.java
@@ -0,0 +1,794 @@
+/*
+ * 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.timezone;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.icu.util.TimeZone;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
+
+/**
+ * A class that can find matching time zones by loading data from the tzlookup.xml file.
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public final class TimeZoneFinder {
+
+    private static final String TZLOOKUP_FILE_NAME = "tzlookup.xml";
+
+    // Root element. e.g. <timezones ianaversion="2017b">
+    private static final String TIMEZONES_ELEMENT = "timezones";
+    private static final String IANA_VERSION_ATTRIBUTE = "ianaversion";
+
+    // Country zones section. e.g. <countryzones>
+    private static final String COUNTRY_ZONES_ELEMENT = "countryzones";
+
+    // Country data. e.g. <country code="gb" default="Europe/London" everutc="y">
+    private static final String COUNTRY_ELEMENT = "country";
+    private static final String COUNTRY_CODE_ATTRIBUTE = "code";
+    private static final String DEFAULT_TIME_ZONE_ID_ATTRIBUTE = "default";
+    private static final String EVER_USES_UTC_ATTRIBUTE = "everutc";
+
+    // Country -> Time zone mapping. e.g. <id>ZoneId</id>, <id picker="n">ZoneId</id>,
+    // <id notafter={timestamp}>ZoneId</id>
+    // The default for the picker attribute when unspecified is "y".
+    // The notafter attribute is optional. It specifies a timestamp (time in milliseconds from Unix
+    // epoch start) after which the zone is not (effectively) in use. If unspecified the zone is in
+    // use forever.
+    private static final String ZONE_ID_ELEMENT = "id";
+    private static final String ZONE_SHOW_IN_PICKER_ATTRIBUTE = "picker";
+    private static final String ZONE_NOT_USED_AFTER_ATTRIBUTE = "notafter";
+
+    private static final String TRUE_ATTRIBUTE_VALUE = "y";
+    private static final String FALSE_ATTRIBUTE_VALUE = "n";
+
+    private static TimeZoneFinder instance;
+
+    private final ReaderSupplier xmlSource;
+
+    // Cached field for the last country looked up.
+    private CountryTimeZones lastCountryTimeZones;
+
+    private TimeZoneFinder(ReaderSupplier xmlSource) {
+        this.xmlSource = xmlSource;
+    }
+
+    /**
+     * Obtains an instance for use when resolving time zones. This method handles using the correct
+     * file when there are several to choose from. This method never returns {@code null}. No
+     * in-depth validation is performed on the file content, see {@link #validate()}.
+     */
+    @libcore.api.CorePlatformApi
+    public static TimeZoneFinder getInstance() {
+        synchronized(TimeZoneFinder.class) {
+            if (instance == null) {
+                String[] tzLookupFilePaths =
+                        TimeZoneDataFiles.getTimeZoneFilePaths(TZLOOKUP_FILE_NAME);
+                instance = createInstanceWithFallback(tzLookupFilePaths);
+            }
+        }
+        return instance;
+    }
+
+    // VisibleForTesting
+    public static TimeZoneFinder createInstanceWithFallback(String... tzLookupFilePaths) {
+        IOException lastException = null;
+        for (String tzLookupFilePath : tzLookupFilePaths) {
+            try {
+                // We assume that any file in /data was validated before install, and the system
+                // file was validated before the device shipped. Therefore, we do not pay the
+                // validation cost here.
+                return createInstance(tzLookupFilePath);
+            } catch (IOException e) {
+                // There's expected to be two files, and it's normal for the first file not to
+                // exist so we don't log, but keep the lastException so we can log it if there
+                // are no valid files available.
+                if (lastException != null) {
+                    e.addSuppressed(lastException);
+                }
+                lastException = e;
+            }
+        }
+
+        System.logE("No valid file found in set: " + Arrays.toString(tzLookupFilePaths)
+                + " Printing exceptions and falling back to empty map.", lastException);
+        return createInstanceForTests("<timezones><countryzones /></timezones>");
+    }
+
+    /**
+     * Obtains an instance using a specific data file, throwing an IOException if the file does not
+     * exist or is not readable. This method never returns {@code null}. No in-depth validation is
+     * performed on the file content, see {@link #validate()}.
+     */
+    @libcore.api.CorePlatformApi
+    public static TimeZoneFinder createInstance(String path) throws IOException {
+        ReaderSupplier xmlSupplier = ReaderSupplier.forFile(path, StandardCharsets.UTF_8);
+        return new TimeZoneFinder(xmlSupplier);
+    }
+
+    /** Used to create an instance using an in-memory XML String instead of a file. */
+    // VisibleForTesting
+    public static TimeZoneFinder createInstanceForTests(String xml) {
+        return new TimeZoneFinder(ReaderSupplier.forString(xml));
+    }
+
+    /**
+     * Parses the data file, throws an exception if it is invalid or cannot be read.
+     */
+    @libcore.api.CorePlatformApi
+    public void validate() throws IOException {
+        try {
+            processXml(new TimeZonesValidator());
+        } catch (XmlPullParserException e) {
+            throw new IOException("Parsing error", e);
+        }
+    }
+
+    /**
+     * Returns the IANA rules version associated with the data. If there is no version information
+     * or there is a problem reading the file then {@code null} is returned.
+     */
+    @libcore.api.CorePlatformApi
+    public String getIanaVersion() {
+        IanaVersionExtractor ianaVersionExtractor = new IanaVersionExtractor();
+        try {
+            processXml(ianaVersionExtractor);
+            return ianaVersionExtractor.getIanaVersion();
+        } catch (XmlPullParserException | IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Loads all the country &lt;-&gt; time zone mapping data into memory. This method can return
+     * {@code null} in the event of an error while reading the underlying data files.
+     */
+    @libcore.api.CorePlatformApi
+    public CountryZonesFinder getCountryZonesFinder() {
+        CountryZonesLookupExtractor extractor = new CountryZonesLookupExtractor();
+        try {
+            processXml(extractor);
+
+            return extractor.getCountryZonesLookup();
+        } catch (XmlPullParserException | IOException e) {
+            System.logW("Error reading country zones ", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns a frozen ICU time zone that has / would have had the specified offset and DST value
+     * at the specified moment in the specified country.
+     *
+     * <p>In order to be considered a configured zone must match the supplied offset information.
+     *
+     * <p>Matches are considered in a well-defined order. If multiple zones match and one of them
+     * also matches the (optional) bias parameter then the bias time zone will be returned.
+     * Otherwise the first match found is returned.
+     */
+    @libcore.api.CorePlatformApi
+    public TimeZone lookupTimeZoneByCountryAndOffset(
+            String countryIso, int offsetMillis, boolean isDst, long whenMillis, TimeZone bias) {
+
+        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+        if (countryTimeZones == null) {
+            return null;
+        }
+        CountryTimeZones.OffsetResult offsetResult =
+                countryTimeZones.lookupByOffsetWithBias(offsetMillis, isDst, whenMillis, bias);
+        return offsetResult != null ? offsetResult.mTimeZone : null;
+    }
+
+    /**
+     * Returns a "default" time zone ID known to be used in the specified country. This is
+     * the time zone ID that can be used if only the country code is known and can be presumed to be
+     * the "best" choice in the absence of other information. For countries with more than one zone
+     * the time zone will not be correct for everybody.
+     *
+     * <p>If the country code is not recognized or there is an error during lookup this can return
+     * null.
+     */
+    @libcore.api.CorePlatformApi
+    public String lookupDefaultTimeZoneIdByCountry(String countryIso) {
+        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+        return countryTimeZones == null ? null : countryTimeZones.getDefaultTimeZoneId();
+    }
+
+    /**
+     * Returns an immutable list of frozen ICU time zones known to be used in the specified country.
+     * If the country code is not recognized or there is an error during lookup this can return
+     * null. The TimeZones returned will never contain {@link TimeZone#UNKNOWN_ZONE}. This method
+     * can return an empty list in a case when the underlying data files reference only unknown
+     * zone IDs.
+     */
+    @libcore.api.CorePlatformApi
+    public List<TimeZone> lookupTimeZonesByCountry(String countryIso) {
+        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+        return countryTimeZones == null ? null : countryTimeZones.getIcuTimeZones();
+    }
+
+    /**
+     * Returns an immutable list of time zone IDs known to be used in the specified country.
+     * If the country code is not recognized or there is an error during lookup this can return
+     * null. The IDs returned will all be valid for use with
+     * {@link java.util.TimeZone#getTimeZone(String)} and
+     * {@link android.icu.util.TimeZone#getTimeZone(String)}. This method can return an empty list
+     * in a case when the underlying data files reference only unknown zone IDs.
+     */
+    @libcore.api.CorePlatformApi
+    public List<String> lookupTimeZoneIdsByCountry(String countryIso) {
+        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
+        return countryTimeZones == null
+                ? null : extractTimeZoneIds(countryTimeZones.getTimeZoneMappings());
+    }
+
+    /**
+     * Returns a {@link CountryTimeZones} object associated with the specified country code.
+     * Caching is handled as needed. If the country code is not recognized or there is an error
+     * during lookup this method can return null.
+     */
+    @libcore.api.CorePlatformApi
+    public CountryTimeZones lookupCountryTimeZones(String countryIso) {
+        synchronized (this) {
+            if (lastCountryTimeZones != null && lastCountryTimeZones.isForCountryCode(countryIso)) {
+                return lastCountryTimeZones;
+            }
+        }
+
+        SelectiveCountryTimeZonesExtractor extractor =
+                new SelectiveCountryTimeZonesExtractor(countryIso);
+        try {
+            processXml(extractor);
+
+            CountryTimeZones countryTimeZones = extractor.getValidatedCountryTimeZones();
+            if (countryTimeZones == null) {
+                // None matched. Return the null but don't change the cached value.
+                return null;
+            }
+
+            // Update the cached value.
+            synchronized (this) {
+                lastCountryTimeZones = countryTimeZones;
+            }
+            return countryTimeZones;
+        } catch (XmlPullParserException | IOException e) {
+            System.logW("Error reading country zones ", e);
+
+            // Error - don't change the cached value.
+            return null;
+        }
+    }
+
+    /**
+     * Processes the XML, applying the {@link TimeZonesProcessor} to the &lt;countryzones&gt;
+     * element. Processing can terminate early if the
+     * {@link TimeZonesProcessor#processCountryZones(String, String, boolean, List, String)} returns
+     * {@link TimeZonesProcessor#HALT} or it throws an exception.
+     */
+    private void processXml(TimeZonesProcessor processor)
+            throws XmlPullParserException, IOException {
+        try (Reader reader = xmlSource.get()) {
+            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
+            xmlPullParserFactory.setNamespaceAware(false);
+
+            XmlPullParser parser = xmlPullParserFactory.newPullParser();
+            parser.setInput(reader);
+
+            /*
+             * The expected XML structure is:
+             * <timezones ianaversion="2017b">
+             *   <countryzones>
+             *     <country code="us" default="America/New_York">
+             *       <id>America/New_York"</id>
+             *       ...
+             *       <id picker="n">America/Indiana/Vincennes</id>
+             *       ...
+             *       <id>America/Los_Angeles</id>
+             *     </country>
+             *     <country code="gb" default="Europe/London">
+             *       <id>Europe/London</id>
+             *     </country>
+             *   </countryzones>
+             * </timezones>
+             */
+
+            findRequiredStartTag(parser, TIMEZONES_ELEMENT);
+
+            // We do not require the ianaversion attribute be present. It is metadata that helps
+            // with versioning but is not required.
+            String ianaVersion = parser.getAttributeValue(
+                    null /* namespace */, IANA_VERSION_ATTRIBUTE);
+            if (processor.processHeader(ianaVersion) == TimeZonesProcessor.HALT) {
+                return;
+            }
+
+            // There is only one expected sub-element <countryzones> in the format currently, skip
+            // over anything before it.
+            findRequiredStartTag(parser, COUNTRY_ZONES_ELEMENT);
+
+            if (processCountryZones(parser, processor) == TimeZonesProcessor.HALT) {
+                return;
+            }
+
+            // Make sure we are on the </countryzones> tag.
+            checkOnEndTag(parser, COUNTRY_ZONES_ELEMENT);
+
+            // Advance to the next tag.
+            parser.next();
+
+            // Skip anything until </timezones>, and make sure the file is not truncated and we can
+            // find the end.
+            consumeUntilEndTag(parser, TIMEZONES_ELEMENT);
+
+            // Make sure we are on the </timezones> tag.
+            checkOnEndTag(parser, TIMEZONES_ELEMENT);
+        }
+    }
+
+    private static boolean processCountryZones(XmlPullParser parser,
+            TimeZonesProcessor processor) throws IOException, XmlPullParserException {
+
+        // Skip over any unexpected elements and process <country> elements.
+        while (findOptionalStartTag(parser, COUNTRY_ELEMENT)) {
+            if (processor == null) {
+                consumeUntilEndTag(parser, COUNTRY_ELEMENT);
+            } else {
+                String code = parser.getAttributeValue(
+                        null /* namespace */, COUNTRY_CODE_ATTRIBUTE);
+                if (code == null || code.isEmpty()) {
+                    throw new XmlPullParserException(
+                            "Unable to find country code: " + parser.getPositionDescription());
+                }
+                String defaultTimeZoneId = parser.getAttributeValue(
+                        null /* namespace */, DEFAULT_TIME_ZONE_ID_ATTRIBUTE);
+                if (defaultTimeZoneId == null || defaultTimeZoneId.isEmpty()) {
+                    throw new XmlPullParserException("Unable to find default time zone ID: "
+                            + parser.getPositionDescription());
+                }
+                Boolean everUsesUtc = parseBooleanAttribute(
+                        parser, EVER_USES_UTC_ATTRIBUTE, null /* defaultValue */);
+                if (everUsesUtc == null) {
+                    // There is no valid default: we require this to be specified.
+                    throw new XmlPullParserException(
+                            "Unable to find UTC hint attribute (" + EVER_USES_UTC_ATTRIBUTE + "): "
+                            + parser.getPositionDescription());
+                }
+
+                String debugInfo = parser.getPositionDescription();
+                List<TimeZoneMapping> timeZoneMappings = parseTimeZoneMappings(parser);
+                boolean result = processor.processCountryZones(code, defaultTimeZoneId, everUsesUtc,
+                        timeZoneMappings, debugInfo);
+                if (result == TimeZonesProcessor.HALT) {
+                    return TimeZonesProcessor.HALT;
+                }
+            }
+
+            // Make sure we are on the </country> element.
+            checkOnEndTag(parser, COUNTRY_ELEMENT);
+        }
+
+        return TimeZonesProcessor.CONTINUE;
+    }
+
+    private static List<TimeZoneMapping> parseTimeZoneMappings(XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        List<TimeZoneMapping> timeZoneMappings = new ArrayList<>();
+
+        // Skip over any unexpected elements and process <id> elements.
+        while (findOptionalStartTag(parser, ZONE_ID_ELEMENT)) {
+            // The picker attribute is optional and defaulted to true.
+            boolean showInPicker = parseBooleanAttribute(
+                    parser, ZONE_SHOW_IN_PICKER_ATTRIBUTE, true /* defaultValue */);
+            Long notUsedAfter = parseLongAttribute(
+                    parser, ZONE_NOT_USED_AFTER_ATTRIBUTE, null /* defaultValue */);
+            String zoneIdString = consumeText(parser);
+
+            // Make sure we are on the </id> element.
+            checkOnEndTag(parser, ZONE_ID_ELEMENT);
+
+            // Process the TimeZoneMapping.
+            if (zoneIdString == null || zoneIdString.length() == 0) {
+                throw new XmlPullParserException("Missing text for " + ZONE_ID_ELEMENT + "): "
+                        + parser.getPositionDescription());
+            }
+
+            TimeZoneMapping timeZoneMapping =
+                    new TimeZoneMapping(zoneIdString, showInPicker, notUsedAfter);
+            timeZoneMappings.add(timeZoneMapping);
+        }
+
+        // The list is made unmodifiable to avoid callers changing it.
+        return Collections.unmodifiableList(timeZoneMappings);
+    }
+
+    /**
+     * Parses an attribute value, which must be either {@code null} or a valid signed long value.
+     * If the attribute value is {@code null} then {@code defaultValue} is returned. If the
+     * attribute is present but not a valid long value then an XmlPullParserException is thrown.
+     */
+    private static Long parseLongAttribute(XmlPullParser parser, String attributeName,
+            Long defaultValue) throws XmlPullParserException {
+        String attributeValueString = parser.getAttributeValue(null /* namespace */, attributeName);
+        if (attributeValueString == null) {
+            return defaultValue;
+        }
+        try {
+            return Long.parseLong(attributeValueString);
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Attribute \"" + attributeName
+                    + "\" is not a long value: " + parser.getPositionDescription());
+        }
+    }
+
+    /**
+     * Parses an attribute value, which must be either {@code null}, {@code "y"} or {@code "n"}.
+     * If the attribute value is {@code null} then {@code defaultValue} is returned. If the
+     * attribute is present but not "y" or "n" then an XmlPullParserException is thrown.
+     */
+    private static Boolean parseBooleanAttribute(XmlPullParser parser,
+            String attributeName, Boolean defaultValue) throws XmlPullParserException {
+        String attributeValueString = parser.getAttributeValue(null /* namespace */, attributeName);
+        if (attributeValueString == null) {
+            return defaultValue;
+        }
+        boolean isTrue = TRUE_ATTRIBUTE_VALUE.equals(attributeValueString);
+        if (!(isTrue || FALSE_ATTRIBUTE_VALUE.equals(attributeValueString))) {
+            throw new XmlPullParserException("Attribute \"" + attributeName
+                    + "\" is not \"y\" or \"n\": " + parser.getPositionDescription());
+        }
+        return isTrue;
+    }
+
+    private static void findRequiredStartTag(XmlPullParser parser, String elementName)
+            throws IOException, XmlPullParserException {
+        findStartTag(parser, elementName, true /* elementRequired */);
+    }
+
+    /** Called when on a START_TAG. When returning false, it leaves the parser on the END_TAG. */
+    private static boolean findOptionalStartTag(XmlPullParser parser, String elementName)
+            throws IOException, XmlPullParserException {
+        return findStartTag(parser, elementName, false /* elementRequired */);
+    }
+
+    /**
+     * Find a START_TAG with the specified name without decreasing the depth, or increasing the
+     * depth by more than one. More deeply nested elements and text are skipped, even START_TAGs
+     * with matching names. Returns when the START_TAG is found or the next (non-nested) END_TAG is
+     * encountered. The return can take the form of an exception or a false if the START_TAG is not
+     * found. True is returned when it is.
+     */
+    private static boolean findStartTag(
+            XmlPullParser parser, String elementName, boolean elementRequired)
+            throws IOException, XmlPullParserException {
+
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+            switch (type) {
+                case XmlPullParser.START_TAG:
+                    String currentElementName = parser.getName();
+                    if (elementName.equals(currentElementName)) {
+                        return true;
+                    }
+
+                    // It was not the START_TAG we were looking for. Consume until the end.
+                    parser.next();
+                    consumeUntilEndTag(parser, currentElementName);
+                    break;
+                case XmlPullParser.END_TAG:
+                    if (elementRequired) {
+                        throw new XmlPullParserException(
+                                "No child element found with name " + elementName);
+                    }
+                    return false;
+                default:
+                    // Ignore.
+                    break;
+            }
+        }
+        throw new XmlPullParserException("Unexpected end of document while looking for "
+                + elementName);
+    }
+
+    /**
+     * Consume the remaining contents of an element and move to the END_TAG. Used when processing
+     * within an element can stop. The parser must be pointing at either the END_TAG we are looking
+     * for, a TEXT, or a START_TAG nested within the element to be consumed.
+     */
+    private static void consumeUntilEndTag(XmlPullParser parser, String elementName)
+            throws IOException, XmlPullParserException {
+
+        if (parser.getEventType() == XmlPullParser.END_TAG
+                && elementName.equals(parser.getName())) {
+            // Early return - we are already there.
+            return;
+        }
+
+        // Keep track of the required depth in case there are nested elements to be consumed.
+        // Both the name and the depth must match our expectation to complete.
+
+        int requiredDepth = parser.getDepth();
+        // A TEXT tag would be at the same depth as the END_TAG we are looking for.
+        if (parser.getEventType() == XmlPullParser.START_TAG) {
+            // A START_TAG would have incremented the depth, so we're looking for an END_TAG one
+            // higher than the current tag.
+            requiredDepth--;
+        }
+
+        while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
+            int type = parser.next();
+
+            int currentDepth = parser.getDepth();
+            if (currentDepth < requiredDepth) {
+                throw new XmlPullParserException(
+                        "Unexpected depth while looking for end tag: "
+                                + parser.getPositionDescription());
+            } else if (currentDepth == requiredDepth) {
+                if (type == XmlPullParser.END_TAG) {
+                    if (elementName.equals(parser.getName())) {
+                        return;
+                    }
+                    throw new XmlPullParserException(
+                            "Unexpected eng tag: " + parser.getPositionDescription());
+                }
+            }
+            // Everything else is either a type we are not interested in or is too deep and so is
+            // ignored.
+        }
+        throw new XmlPullParserException("Unexpected end of document");
+    }
+
+    /**
+     * Reads the text inside the current element. Should be called when the parser is currently
+     * on the START_TAG before the TEXT. The parser will be positioned on the END_TAG after this
+     * call when it completes successfully.
+     */
+    private static String consumeText(XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+
+        int type = parser.next();
+        String text;
+        if (type == XmlPullParser.TEXT) {
+            text = parser.getText();
+        } else {
+            throw new XmlPullParserException("Text not found. Found type=" + type
+                    + " at " + parser.getPositionDescription());
+        }
+
+        type = parser.next();
+        if (type != XmlPullParser.END_TAG) {
+            throw new XmlPullParserException(
+                    "Unexpected nested tag or end of document when expecting text: type=" + type
+                            + " at " + parser.getPositionDescription());
+        }
+        return text;
+    }
+
+    private static void checkOnEndTag(XmlPullParser parser, String elementName)
+            throws XmlPullParserException {
+        if (!(parser.getEventType() == XmlPullParser.END_TAG
+                && parser.getName().equals(elementName))) {
+            throw new XmlPullParserException(
+                    "Unexpected tag encountered: " + parser.getPositionDescription());
+        }
+    }
+
+    /**
+     * Processes &lt;timezones&gt; data.
+     */
+    private interface TimeZonesProcessor {
+
+        boolean CONTINUE = true;
+        boolean HALT = false;
+
+        /**
+         * Return {@link #CONTINUE} if processing of the XML should continue, {@link #HALT} if it
+         * should stop (but without considering this an error). Problems with the data are
+         * reported as an exception.
+         *
+         * <p>The default implementation returns {@link #CONTINUE}.
+         */
+        default boolean processHeader(String ianaVersion) throws XmlPullParserException {
+            return CONTINUE;
+        }
+
+        /**
+         * Returns {@link #CONTINUE} if processing of the XML should continue, {@link #HALT} if it
+         * should stop (but without considering this an error). Problems with the data are
+         * reported as an exception.
+         *
+         * <p>The default implementation returns {@link #CONTINUE}.
+         */
+        default boolean processCountryZones(String countryIso, String defaultTimeZoneId,
+                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
+                throws XmlPullParserException {
+            return CONTINUE;
+        }
+    }
+
+    /**
+     * Validates &lt;countryzones&gt; elements. Intended to be used before a proposed installation
+     * of new data. To be valid the country ISO code must be normalized, unique, the default time
+     * zone ID must be one of the time zones IDs and the time zone IDs list must not be empty. The
+     * IDs themselves are not checked against other data to see if they are recognized because other
+     * classes will not have been updated with the associated new time zone data yet and so will not
+     * be aware of newly added IDs.
+     */
+    private static class TimeZonesValidator implements TimeZonesProcessor {
+
+        private final Set<String> knownCountryCodes = new HashSet<>();
+
+        @Override
+        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
+                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
+                throws XmlPullParserException {
+            if (!normalizeCountryIso(countryIso).equals(countryIso)) {
+                throw new XmlPullParserException("Country code: " + countryIso
+                        + " is not normalized at " + debugInfo);
+            }
+            if (knownCountryCodes.contains(countryIso)) {
+                throw new XmlPullParserException("Second entry for country code: " + countryIso
+                        + " at " + debugInfo);
+            }
+            if (timeZoneMappings.isEmpty()) {
+                throw new XmlPullParserException("No time zone IDs for country code: " + countryIso
+                        + " at " + debugInfo);
+            }
+            if (!TimeZoneMapping.containsTimeZoneId(timeZoneMappings, defaultTimeZoneId)) {
+                throw new XmlPullParserException("defaultTimeZoneId for country code: "
+                        + countryIso + " is not one of the zones " + timeZoneMappings + " at "
+                        + debugInfo);
+            }
+            knownCountryCodes.add(countryIso);
+
+            return CONTINUE;
+        }
+    }
+
+    /**
+     * Reads just the IANA version from the file header. The version is then available via
+     * {@link #getIanaVersion()}.
+     */
+    private static class IanaVersionExtractor implements TimeZonesProcessor {
+
+        private String ianaVersion;
+
+        @Override
+        public boolean processHeader(String ianaVersion) throws XmlPullParserException {
+            this.ianaVersion = ianaVersion;
+            return HALT;
+        }
+
+        public String getIanaVersion() {
+            return ianaVersion;
+        }
+    }
+
+    /**
+     * Reads all country time zone information into memory and makes it available as a
+     * {@link CountryZonesFinder}.
+     */
+    private static class CountryZonesLookupExtractor implements TimeZonesProcessor {
+        private List<CountryTimeZones> countryTimeZonesList = new ArrayList<>(250 /* default */);
+
+        @Override
+        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
+                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
+                throws XmlPullParserException {
+
+            CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                    countryIso, defaultTimeZoneId, everUsesUtc, timeZoneMappings, debugInfo);
+            countryTimeZonesList.add(countryTimeZones);
+            return CONTINUE;
+        }
+
+        CountryZonesFinder getCountryZonesLookup() {
+            return new CountryZonesFinder(countryTimeZonesList);
+        }
+    }
+
+    /**
+     * Extracts <em>validated</em> time zones information associated with a specific country code.
+     * Processing is halted when the country code is matched and the validated result is also made
+     * available via {@link #getValidatedCountryTimeZones()}.
+     */
+    private static class SelectiveCountryTimeZonesExtractor implements TimeZonesProcessor {
+
+        private final String countryCodeToMatch;
+        private CountryTimeZones validatedCountryTimeZones;
+
+        private SelectiveCountryTimeZonesExtractor(String countryCodeToMatch) {
+            this.countryCodeToMatch = normalizeCountryIso(countryCodeToMatch);
+        }
+
+        @Override
+        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
+                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo) {
+            countryIso = normalizeCountryIso(countryIso);
+            if (!countryCodeToMatch.equals(countryIso)) {
+                return CONTINUE;
+            }
+            validatedCountryTimeZones = CountryTimeZones.createValidated(countryIso,
+                    defaultTimeZoneId, everUsesUtc, timeZoneMappings, debugInfo);
+
+            return HALT;
+        }
+
+        /**
+         * Returns the CountryTimeZones that matched, or {@code null} if there were no matches.
+         */
+        CountryTimeZones getValidatedCountryTimeZones() {
+            return validatedCountryTimeZones;
+        }
+    }
+
+    /**
+     * A source of Readers that can be used repeatedly.
+     */
+    private interface ReaderSupplier {
+        /** Returns a Reader. Throws an IOException if the Reader cannot be created. */
+        Reader get() throws IOException;
+
+        static ReaderSupplier forFile(String fileName, Charset charSet) throws IOException {
+            Path file = Paths.get(fileName);
+            if (!Files.exists(file)) {
+                throw new FileNotFoundException(fileName + " does not exist");
+            }
+            if (!Files.isRegularFile(file) && Files.isReadable(file)) {
+                throw new IOException(fileName + " must be a regular readable file.");
+            }
+            return () -> Files.newBufferedReader(file, charSet);
+        }
+
+        static ReaderSupplier forString(String xml) {
+            return () -> new StringReader(xml);
+        }
+    }
+
+    private static List<String> extractTimeZoneIds(List<TimeZoneMapping> timeZoneMappings) {
+        List<String> zoneIds = new ArrayList<>(timeZoneMappings.size());
+        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
+            zoneIds.add(timeZoneMapping.timeZoneId);
+        }
+        return Collections.unmodifiableList(zoneIds);
+    }
+
+    static String normalizeCountryIso(String countryIso) {
+        // Lowercase ASCII is normalized for the purposes of the input files and the code in this
+        // class and related classes.
+        return countryIso.toLowerCase(Locale.US);
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/TzDataSetVersion.java b/luni/src/main/java/libcore/timezone/TzDataSetVersion.java
new file mode 100644
index 0000000..2ba64a0
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/TzDataSetVersion.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2016 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.timezone;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Constants and logic associated with the time zone data version file.
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public class TzDataSetVersion {
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    /**
+     * The name typically given to the {@link TzDataSetVersion} file. See
+     * {@link TzDataSetVersion#readFromFile(File)}.
+     */
+    @libcore.api.CorePlatformApi
+    public static final String DEFAULT_FILE_NAME = "tz_version";
+
+    /**
+     * The major tz data format version supported by this device.
+     * Increment this for non-backwards compatible changes to the tz data format. Reset the minor
+     * version to 1 when doing so.
+     */
+    // @VisibleForTesting : Keep this inline-able: it is used from CTS tests.
+    public static final int CURRENT_FORMAT_MAJOR_VERSION = 3; // Android Q
+
+    /**
+     * Returns the major tz data format version supported by this device.
+     */
+    @libcore.api.CorePlatformApi
+    public static int currentFormatMajorVersion() {
+        return CURRENT_FORMAT_MAJOR_VERSION;
+    }
+
+    /**
+     * The minor tz data format version supported by this device. Increment this for
+     * backwards-compatible changes to the tz data format.
+     */
+    // @VisibleForTesting : Keep this inline-able: it is used from CTS tests.
+    public static final int CURRENT_FORMAT_MINOR_VERSION = 1;
+
+    /**
+     * Returns the minor tz data format version supported by this device.
+     */
+    @libcore.api.CorePlatformApi
+    public static int currentFormatMinorVersion() {
+        return CURRENT_FORMAT_MINOR_VERSION;
+    }
+
+    /** The full major + minor tz data format version for this device. */
+    private static final String FULL_CURRENT_FORMAT_VERSION_STRING =
+            toFormatVersionString(CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION);
+
+    private static final int FORMAT_VERSION_STRING_LENGTH =
+            FULL_CURRENT_FORMAT_VERSION_STRING.length();
+    private static final Pattern FORMAT_VERSION_PATTERN = Pattern.compile("(\\d{3})\\.(\\d{3})");
+
+    /** A pattern that matches the IANA rules value of a rules update. e.g. "2016g" */
+    private static final Pattern RULES_VERSION_PATTERN = Pattern.compile("(\\d{4}\\w)");
+
+    private static final int RULES_VERSION_LENGTH = 5;
+
+    /** A pattern that matches the revision of a rules update. e.g. "001" */
+    private static final Pattern REVISION_PATTERN = Pattern.compile("(\\d{3})");
+
+    private static final int REVISION_LENGTH = 3;
+
+    /**
+     * The length of a well-formed tz data set version file:
+     * {Format version}|{Rule version}|{Revision}
+     */
+    private static final int TZ_DATA_VERSION_FILE_LENGTH = FORMAT_VERSION_STRING_LENGTH + 1
+            + RULES_VERSION_LENGTH
+            + 1 + REVISION_LENGTH;
+
+    private static final Pattern TZ_DATA_VERSION_FILE_PATTERN = Pattern.compile(
+            FORMAT_VERSION_PATTERN.pattern() + "\\|"
+                    + RULES_VERSION_PATTERN.pattern() + "\\|"
+                    + REVISION_PATTERN.pattern()
+                    + ".*" /* ignore trailing */);
+
+    public final int formatMajorVersion;
+    public final int formatMinorVersion;
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    @libcore.api.CorePlatformApi
+    public final String rulesVersion;
+
+    public final int revision;
+
+    @libcore.api.CorePlatformApi
+    public TzDataSetVersion(int formatMajorVersion, int formatMinorVersion, String rulesVersion,
+            int revision) throws TzDataSetException {
+        this.formatMajorVersion = validate3DigitVersion(formatMajorVersion);
+        this.formatMinorVersion = validate3DigitVersion(formatMinorVersion);
+        if (!RULES_VERSION_PATTERN.matcher(rulesVersion).matches()) {
+            throw new TzDataSetException("Invalid rulesVersion: " + rulesVersion);
+        }
+        this.rulesVersion = rulesVersion;
+        this.revision = validate3DigitVersion(revision);
+    }
+
+    // VisibleForTesting
+    public static TzDataSetVersion fromBytes(byte[] bytes) throws TzDataSetException {
+        String tzDataVersion = new String(bytes, StandardCharsets.US_ASCII);
+        try {
+            Matcher matcher = TZ_DATA_VERSION_FILE_PATTERN.matcher(tzDataVersion);
+            if (!matcher.matches()) {
+                throw new TzDataSetException(
+                        "Invalid tz data version string: \"" + tzDataVersion + "\"");
+            }
+            String formatMajorVersion = matcher.group(1);
+            String formatMinorVersion = matcher.group(2);
+            String rulesVersion = matcher.group(3);
+            String revision = matcher.group(4);
+            return new TzDataSetVersion(
+                    from3DigitVersionString(formatMajorVersion),
+                    from3DigitVersionString(formatMinorVersion),
+                    rulesVersion,
+                    from3DigitVersionString(revision));
+        } catch (IndexOutOfBoundsException e) {
+            // The use of the regexp above should make this impossible.
+            throw new TzDataSetException(
+                    "tz data version string too short: \"" + tzDataVersion + "\"");
+        }
+    }
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    @libcore.api.CorePlatformApi
+    public static TzDataSetVersion readFromFile(File file) throws IOException, TzDataSetException {
+        byte[] versionBytes = readBytes(file, TzDataSetVersion.TZ_DATA_VERSION_FILE_LENGTH);
+        return fromBytes(versionBytes);
+    }
+
+    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
+    @libcore.api.CorePlatformApi
+    public byte[] toBytes() {
+        return toBytes(formatMajorVersion, formatMinorVersion, rulesVersion, revision);
+    }
+
+    private static byte[] toBytes(
+            int majorFormatVersion, int minorFormatVerison, String rulesVersion, int revision) {
+        return (toFormatVersionString(majorFormatVersion, minorFormatVerison)
+                + "|" + rulesVersion + "|" + to3DigitVersionString(revision))
+                .getBytes(StandardCharsets.US_ASCII);
+    }
+
+    @libcore.api.CorePlatformApi
+    public static boolean isCompatibleWithThisDevice(TzDataSetVersion tzDataVersion) {
+        return (CURRENT_FORMAT_MAJOR_VERSION == tzDataVersion.formatMajorVersion)
+                && (CURRENT_FORMAT_MINOR_VERSION <= tzDataVersion.formatMinorVersion);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        TzDataSetVersion that = (TzDataSetVersion) o;
+
+        if (formatMajorVersion != that.formatMajorVersion) {
+            return false;
+        }
+        if (formatMinorVersion != that.formatMinorVersion) {
+            return false;
+        }
+        if (revision != that.revision) {
+            return false;
+        }
+        return rulesVersion.equals(that.rulesVersion);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = formatMajorVersion;
+        result = 31 * result + formatMinorVersion;
+        result = 31 * result + rulesVersion.hashCode();
+        result = 31 * result + revision;
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TzDataSetVersion{" +
+                "formatMajorVersion=" + formatMajorVersion +
+                ", formatMinorVersion=" + formatMinorVersion +
+                ", rulesVersion='" + rulesVersion + '\'' +
+                ", revision=" + revision +
+                '}';
+    }
+
+    /**
+     * Returns a version as a zero-padded three-digit String value.
+     */
+    private static String to3DigitVersionString(int version) {
+        try {
+            return String.format(Locale.ROOT, "%03d", validate3DigitVersion(version));
+        } catch (TzDataSetException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Validates and parses a zero-padded three-digit String value.
+     */
+    private static int from3DigitVersionString(String versionString) throws TzDataSetException {
+        final String parseErrorMessage = "versionString must be a zero padded, 3 digit, positive"
+                + " decimal integer";
+        if (versionString.length() != 3) {
+            throw new TzDataSetException(parseErrorMessage);
+        }
+        try {
+            int version = Integer.parseInt(versionString);
+            return validate3DigitVersion(version);
+        } catch (NumberFormatException e) {
+            throw new TzDataSetException(parseErrorMessage, e);
+        }
+    }
+
+    private static int validate3DigitVersion(int value) throws TzDataSetException {
+        // 0 is allowed but is reserved for testing.
+        if (value < 0 || value > 999) {
+            throw new TzDataSetException("Expected 0 <= value <= 999, was " + value);
+        }
+        return value;
+    }
+
+    private static String toFormatVersionString(int majorFormatVersion, int minorFormatVersion) {
+        return to3DigitVersionString(majorFormatVersion)
+                + "." + to3DigitVersionString(minorFormatVersion);
+    }
+
+    /**
+     * Reads up to {@code maxBytes} bytes from the specified file. The returned array can be
+     * shorter than {@code maxBytes} if the file is shorter.
+     */
+    private static byte[] readBytes(File file, int maxBytes) throws IOException {
+        if (maxBytes <= 0) {
+            throw new IllegalArgumentException("maxBytes ==" + maxBytes);
+        }
+
+        try (FileInputStream in = new FileInputStream(file)) {
+            byte[] max = new byte[maxBytes];
+            int bytesRead = in.read(max, 0, maxBytes);
+            byte[] toReturn = new byte[bytesRead];
+            System.arraycopy(max, 0, toReturn, 0, bytesRead);
+            return toReturn;
+        }
+    }
+
+    /**
+     * A checked exception used in connection with time zone data sets.
+     */
+    @libcore.api.CorePlatformApi
+    public static class TzDataSetException extends Exception {
+
+        @libcore.api.CorePlatformApi
+        public TzDataSetException(String message) {
+            super(message);
+        }
+
+        @libcore.api.CorePlatformApi
+        public TzDataSetException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/ZoneInfoDB.java b/luni/src/main/java/libcore/timezone/ZoneInfoDB.java
new file mode 100644
index 0000000..ca29319
--- /dev/null
+++ b/luni/src/main/java/libcore/timezone/ZoneInfoDB.java
@@ -0,0 +1,421 @@
+/*
+ * 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.timezone;
+
+import android.system.ErrnoException;
+import dalvik.annotation.optimization.ReachabilitySensitive;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import libcore.io.BufferIterator;
+import libcore.io.MemoryMappedFile;
+import libcore.util.BasicLruCache;
+import libcore.util.ZoneInfo;
+
+/**
+ * A class used to initialize the time zone database. This implementation uses the
+ * Olson tzdata as the source of time zone information. However, to conserve
+ * disk space (inodes) and reduce I/O, all the data is concatenated into a single file,
+ * with an index to indicate the starting position of each time zone record.
+ *
+ * @hide - used to implement TimeZone
+ */
+@libcore.api.CorePlatformApi
+public final class ZoneInfoDB {
+
+  // VisibleForTesting
+  public static final String TZDATA_FILE = "tzdata";
+
+  private static final TzData DATA =
+          TzData.loadTzDataWithFallback(TimeZoneDataFiles.getTimeZoneFilePaths(TZDATA_FILE));
+
+  /** @hide */
+  @libcore.api.CorePlatformApi
+  public static class TzData implements AutoCloseable {
+
+    // The database reserves 40 bytes for each id.
+    private static final int SIZEOF_TZNAME = 40;
+
+    // The database uses 32-bit (4 byte) integers.
+    private static final int SIZEOF_TZINT = 4;
+
+    // Each index entry takes up this number of bytes.
+    public static final int SIZEOF_INDEX_ENTRY = SIZEOF_TZNAME + 3 * SIZEOF_TZINT;
+
+    /**
+     * {@code true} if {@link #close()} has been called meaning the instance cannot provide any
+     * data.
+     */
+    private boolean closed;
+
+    /**
+     * Rather than open, read, and close the big data file each time we look up a time zone,
+     * we map the big data file during startup, and then just use the MemoryMappedFile.
+     *
+     * At the moment, this "big" data file is about 500 KiB. At some point, that will be small
+     * enough that we could just keep the byte[] in memory, but using mmap(2) like this has the
+     * nice property that even if someone replaces the file under us (because multiple gservices
+     * updates have gone out, say), we still get a consistent (if outdated) view of the world.
+     */
+    // Android-added: @ReachabilitySensitive
+    @ReachabilitySensitive
+    private MemoryMappedFile mappedFile;
+
+    private String version;
+    private String zoneTab;
+
+    /**
+     * The 'ids' array contains time zone ids sorted alphabetically, for binary searching.
+     * The other two arrays are in the same order. 'byteOffsets' gives the byte offset
+     * of each time zone, and 'rawUtcOffsetsCache' gives the time zone's raw UTC offset.
+     */
+    private String[] ids;
+    private int[] byteOffsets;
+    private int[] rawUtcOffsetsCache; // Access this via getRawUtcOffsets instead.
+
+    /**
+     * ZoneInfo objects are worth caching because they are expensive to create.
+     * See http://b/8270865 for context.
+     */
+    private final static int CACHE_SIZE = 1;
+    private final BasicLruCache<String, ZoneInfo> cache =
+        new BasicLruCache<String, ZoneInfo>(CACHE_SIZE) {
+      @Override
+      protected ZoneInfo create(String id) {
+        try {
+          return makeTimeZoneUncached(id);
+        } catch (IOException e) {
+          throw new IllegalStateException("Unable to load timezone for ID=" + id, e);
+        }
+      }
+    };
+
+    /**
+     * Loads the data at the specified paths in order, returning the first valid one as a
+     * {@link TzData} object. If there is no valid one found a basic fallback instance is created
+     * containing just GMT.
+     */
+    public static TzData loadTzDataWithFallback(String... paths) {
+      for (String path : paths) {
+        TzData tzData = new TzData();
+        if (tzData.loadData(path)) {
+          return tzData;
+        }
+      }
+
+      // We didn't find any usable tzdata on disk, so let's just hard-code knowledge of "GMT".
+      // This is actually implemented in TimeZone itself, so if this is the only time zone
+      // we report, we won't be asked any more questions.
+      System.logE("Couldn't find any " + TZDATA_FILE + " file!");
+      return TzData.createFallback();
+    }
+
+    /**
+     * Loads the data at the specified path and returns the {@link TzData} object if it is valid,
+     * otherwise {@code null}.
+     */
+    @libcore.api.CorePlatformApi
+    public static TzData loadTzData(String path) {
+      TzData tzData = new TzData();
+      if (tzData.loadData(path)) {
+        return tzData;
+      }
+      return null;
+    }
+
+    private static TzData createFallback() {
+      TzData tzData = new TzData();
+      tzData.populateFallback();
+      return tzData;
+    }
+
+    private TzData() {
+    }
+
+    /**
+     * Visible for testing.
+     */
+    public BufferIterator getBufferIterator(String id) {
+      checkNotClosed();
+
+      // Work out where in the big data file this time zone is.
+      int index = Arrays.binarySearch(ids, id);
+      if (index < 0) {
+        return null;
+      }
+
+      int byteOffset = byteOffsets[index];
+      BufferIterator it = mappedFile.bigEndianIterator();
+      it.skip(byteOffset);
+      return it;
+    }
+
+    private void populateFallback() {
+      version = "missing";
+      zoneTab = "# Emergency fallback data.\n";
+      ids = new String[] { "GMT" };
+      byteOffsets = rawUtcOffsetsCache = new int[1];
+    }
+
+    /**
+     * Loads the data file at the specified path. If the data is valid {@code true} will be
+     * returned and the {@link TzData} instance can be used. If {@code false} is returned then the
+     * TzData instance is left in a closed state and must be discarded.
+     */
+    private boolean loadData(String path) {
+      try {
+        mappedFile = MemoryMappedFile.mmapRO(path);
+      } catch (ErrnoException errnoException) {
+        return false;
+      }
+      try {
+        readHeader();
+        return true;
+      } catch (Exception ex) {
+        close();
+
+        // Something's wrong with the file.
+        // Log the problem and return false so we try the next choice.
+        System.logE(TZDATA_FILE + " file \"" + path + "\" was present but invalid!", ex);
+        return false;
+      }
+    }
+
+    private void readHeader() throws IOException {
+      // byte[12] tzdata_version  -- "tzdata2012f\0"
+      // int index_offset
+      // int data_offset
+      // int zonetab_offset
+      BufferIterator it = mappedFile.bigEndianIterator();
+
+      try {
+        byte[] tzdata_version = new byte[12];
+        it.readByteArray(tzdata_version, 0, tzdata_version.length);
+        String magic = new String(tzdata_version, 0, 6, StandardCharsets.US_ASCII);
+        if (!magic.equals("tzdata") || tzdata_version[11] != 0) {
+          throw new IOException("bad tzdata magic: " + Arrays.toString(tzdata_version));
+        }
+        version = new String(tzdata_version, 6, 5, StandardCharsets.US_ASCII);
+
+        final int fileSize = mappedFile.size();
+        int index_offset = it.readInt();
+        validateOffset(index_offset, fileSize);
+        int data_offset = it.readInt();
+        validateOffset(data_offset, fileSize);
+        int zonetab_offset = it.readInt();
+        validateOffset(zonetab_offset, fileSize);
+
+        if (index_offset >= data_offset || data_offset >= zonetab_offset) {
+          throw new IOException("Invalid offset: index_offset=" + index_offset
+                  + ", data_offset=" + data_offset + ", zonetab_offset=" + zonetab_offset
+                  + ", fileSize=" + fileSize);
+        }
+
+        readIndex(it, index_offset, data_offset);
+        readZoneTab(it, zonetab_offset, fileSize - zonetab_offset);
+      } catch (IndexOutOfBoundsException e) {
+        throw new IOException("Invalid read from data file", e);
+      }
+    }
+
+    private static void validateOffset(int offset, int size) throws IOException {
+      if (offset < 0 || offset >= size) {
+        throw new IOException("Invalid offset=" + offset + ", size=" + size);
+      }
+    }
+
+    private void readZoneTab(BufferIterator it, int zoneTabOffset, int zoneTabSize) {
+      byte[] bytes = new byte[zoneTabSize];
+      it.seek(zoneTabOffset);
+      it.readByteArray(bytes, 0, bytes.length);
+      zoneTab = new String(bytes, 0, bytes.length, StandardCharsets.US_ASCII);
+    }
+
+    private void readIndex(BufferIterator it, int indexOffset, int dataOffset) throws IOException {
+      it.seek(indexOffset);
+
+      byte[] idBytes = new byte[SIZEOF_TZNAME];
+      int indexSize = (dataOffset - indexOffset);
+      if (indexSize % SIZEOF_INDEX_ENTRY != 0) {
+        throw new IOException("Index size is not divisible by " + SIZEOF_INDEX_ENTRY
+                + ", indexSize=" + indexSize);
+      }
+      int entryCount = indexSize / SIZEOF_INDEX_ENTRY;
+
+      byteOffsets = new int[entryCount];
+      ids = new String[entryCount];
+
+      for (int i = 0; i < entryCount; i++) {
+        // Read the fixed length timezone ID.
+        it.readByteArray(idBytes, 0, idBytes.length);
+
+        // Read the offset into the file where the data for ID can be found.
+        byteOffsets[i] = it.readInt();
+        byteOffsets[i] += dataOffset;
+
+        int length = it.readInt();
+        if (length < 44) {
+          throw new IOException("length in index file < sizeof(tzhead)");
+        }
+        it.skip(4); // Skip the unused 4 bytes that used to be the raw offset.
+
+        // Calculate the true length of the ID.
+        int len = 0;
+        while (idBytes[len] != 0 && len < idBytes.length) {
+          len++;
+        }
+        if (len == 0) {
+          throw new IOException("Invalid ID at index=" + i);
+        }
+        ids[i] = new String(idBytes, 0, len, StandardCharsets.US_ASCII);
+        if (i > 0) {
+          if (ids[i].compareTo(ids[i - 1]) <= 0) {
+            throw new IOException("Index not sorted or contains multiple entries with the same ID"
+                    + ", index=" + i + ", ids[i]=" + ids[i] + ", ids[i - 1]=" + ids[i - 1]);
+          }
+        }
+      }
+    }
+
+    @libcore.api.CorePlatformApi
+    public void validate() throws IOException {
+      checkNotClosed();
+      // Validate the data in the tzdata file by loading each and every zone.
+      for (String id : getAvailableIDs()) {
+        ZoneInfo zoneInfo = makeTimeZoneUncached(id);
+        if (zoneInfo == null) {
+          throw new IOException("Unable to find data for ID=" + id);
+        }
+      }
+    }
+
+    ZoneInfo makeTimeZoneUncached(String id) throws IOException {
+      BufferIterator it = getBufferIterator(id);
+      if (it == null) {
+        return null;
+      }
+
+      return ZoneInfo.readTimeZone(id, it, System.currentTimeMillis());
+    }
+
+    public String[] getAvailableIDs() {
+      checkNotClosed();
+      return ids.clone();
+    }
+
+    public String[] getAvailableIDs(int rawUtcOffset) {
+      checkNotClosed();
+      List<String> matches = new ArrayList<String>();
+      int[] rawUtcOffsets = getRawUtcOffsets();
+      for (int i = 0; i < rawUtcOffsets.length; ++i) {
+        if (rawUtcOffsets[i] == rawUtcOffset) {
+          matches.add(ids[i]);
+        }
+      }
+      return matches.toArray(new String[matches.size()]);
+    }
+
+    private synchronized int[] getRawUtcOffsets() {
+      if (rawUtcOffsetsCache != null) {
+        return rawUtcOffsetsCache;
+      }
+      rawUtcOffsetsCache = new int[ids.length];
+      for (int i = 0; i < ids.length; ++i) {
+        // This creates a TimeZone, which is quite expensive. Hence the cache.
+        // Note that icu4c does the same (without the cache), so if you're
+        // switching this code over to icu4j you should check its performance.
+        // Telephony shouldn't care, but someone converting a bunch of calendar
+        // events might.
+        rawUtcOffsetsCache[i] = cache.get(ids[i]).getRawOffset();
+      }
+      return rawUtcOffsetsCache;
+    }
+
+    @libcore.api.CorePlatformApi
+    public String getVersion() {
+      checkNotClosed();
+      return version;
+    }
+
+    public String getZoneTab() {
+      checkNotClosed();
+      return zoneTab;
+    }
+
+    @libcore.api.CorePlatformApi
+    public ZoneInfo makeTimeZone(String id) throws IOException {
+      checkNotClosed();
+      ZoneInfo zoneInfo = cache.get(id);
+      // The object from the cache is cloned because TimeZone / ZoneInfo are mutable.
+      return zoneInfo == null ? null : (ZoneInfo) zoneInfo.clone();
+    }
+
+    @libcore.api.CorePlatformApi
+    public boolean hasTimeZone(String id) throws IOException {
+      checkNotClosed();
+      return cache.get(id) != null;
+    }
+
+    public void close() {
+      if (!closed) {
+        closed = true;
+
+        // Clear state that takes up appreciable heap.
+        ids = null;
+        byteOffsets = null;
+        rawUtcOffsetsCache = null;
+        cache.evictAll();
+
+        // Remove the mapped file (if needed).
+        if (mappedFile != null) {
+          try {
+            mappedFile.close();
+          } catch (ErrnoException ignored) {
+          }
+          mappedFile = null;
+        }
+      }
+    }
+
+    private void checkNotClosed() throws IllegalStateException {
+      if (closed) {
+        throw new IllegalStateException("TzData is closed");
+      }
+    }
+
+    @Override protected void finalize() throws Throwable {
+      try {
+        close();
+      } finally {
+        super.finalize();
+      }
+    }
+  }
+
+  private ZoneInfoDB() {
+  }
+
+  @libcore.api.CorePlatformApi
+  public static TzData getInstance() {
+    return DATA;
+  }
+}
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..3a8d854
--- /dev/null
+++ b/luni/src/main/java/libcore/util/ArrayUtils.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.util;
+
+/**
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+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
+     */
+    @libcore.api.CorePlatformApi
+    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/BasicLruCache.java b/luni/src/main/java/libcore/util/BasicLruCache.java
index fa89e3d..20a3bee 100644
--- a/luni/src/main/java/libcore/util/BasicLruCache.java
+++ b/luni/src/main/java/libcore/util/BasicLruCache.java
@@ -16,17 +16,21 @@
 
 package libcore.util;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
  * A minimal least-recently-used cache for libcore. Prefer {@code
  * android.util.LruCache} where that is available.
+ * @hide
  */
 public class BasicLruCache<K, V> {
+    @UnsupportedAppUsage
     private final LinkedHashMap<K, V> map;
     private final int maxSize;
 
+    @UnsupportedAppUsage
     public BasicLruCache(int maxSize) {
         if (maxSize <= 0) {
             throw new IllegalArgumentException("maxSize <= 0");
@@ -41,6 +45,7 @@
      * head of the queue. This returns null if a value is not cached and cannot
      * be created.
      */
+    @UnsupportedAppUsage
     public final V get(K key) {
         if (key == null) {
             throw new NullPointerException("key == null");
@@ -79,6 +84,7 @@
      * @return the previous value mapped by {@code key}. Although that entry is
      *     no longer cached, it has not been passed to {@link #entryEvicted}.
      */
+    @UnsupportedAppUsage
     public synchronized final V put(K key, V value) {
         if (key == null) {
             throw new NullPointerException("key == null");
@@ -129,6 +135,7 @@
     /**
      * Clear the cache, calling {@link #entryEvicted} on each removed entry.
      */
+    @UnsupportedAppUsage
     public synchronized final void evictAll() {
         trimToSize(0);
     }
diff --git a/luni/src/main/java/libcore/util/CoreLibraryDebug.java b/luni/src/main/java/libcore/util/CoreLibraryDebug.java
new file mode 100644
index 0000000..c39017f
--- /dev/null
+++ b/luni/src/main/java/libcore/util/CoreLibraryDebug.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.timezone.TzDataSetVersion;
+import libcore.timezone.TzDataSetVersion.TzDataSetException;
+import libcore.timezone.ZoneInfoDB;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Provides APIs for obtaining metadata for the managed core library and lower-level
+ * components like bionic and the runtime.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public class CoreLibraryDebug {
+
+    private static final String CORE_LIBRARY_TIMEZONE_DEBUG_PREFIX = "core_library.timezone.";
+
+    private CoreLibraryDebug() {}
+
+    /**
+     * Returns information about the Core Library for debugging.
+     */
+    @libcore.api.CorePlatformApi
+    public static DebugInfo getDebugInfo() {
+        DebugInfo debugInfo = new DebugInfo();
+        populateTimeZoneFilesInfo(debugInfo);
+        populateTimeZoneLibraryReportedVersion(debugInfo);
+        return debugInfo;
+    }
+
+    /**
+     * Adds information about the available time zone file sets on the device to the supplied
+     * {@link DebugInfo}. See also {@link #populateTimeZoneLibraryReportedVersion(DebugInfo)} for a method
+     * that provides information about the time zone files actually in use by libraries.
+     */
+    private static void populateTimeZoneFilesInfo(DebugInfo debugInfo) {
+        String debugKeyPrefix = CORE_LIBRARY_TIMEZONE_DEBUG_PREFIX + "source.";
+
+        // Time zone module tz data set.
+        {
+            String tzDataModulePrefix = debugKeyPrefix + "tzdata_module_";
+            String versionFileName = TimeZoneDataFiles.getTimeZoneModuleFile(
+                    "tz/" + TzDataSetVersion.DEFAULT_FILE_NAME);
+            addTzDataSetVersionDebugInfo(versionFileName, tzDataModulePrefix, debugInfo);
+        }
+
+        // Runtime module tz data set.
+        {
+            String runtimeModulePrefix = debugKeyPrefix + "runtime_module_";
+            String versionFileName = TimeZoneDataFiles.getRuntimeModuleFile(
+                    "tz/" + TzDataSetVersion.DEFAULT_FILE_NAME);
+            addTzDataSetVersionDebugInfo(versionFileName, runtimeModulePrefix, debugInfo);
+        }
+
+        // /system tz data set.
+        {
+            String systemDirPrefix = debugKeyPrefix + "system_";
+            String versionFileName =
+                    TimeZoneDataFiles.getSystemTimeZoneFile(TzDataSetVersion.DEFAULT_FILE_NAME);
+            addTzDataSetVersionDebugInfo(versionFileName, systemDirPrefix, debugInfo);
+        }
+    }
+
+    private static void addTzDataSetVersionDebugInfo(String tzDataSetVersionFileName,
+            String debugKeyPrefix, DebugInfo debugInfo) {
+        File file = new File(tzDataSetVersionFileName);
+        String statusKey = debugKeyPrefix + "status";
+        if (file.exists()) {
+            try {
+                TzDataSetVersion tzDataSetVersion =
+                        TzDataSetVersion.readFromFile(file);
+                String formatVersionString = tzDataSetVersion.formatMajorVersion + "."
+                        + tzDataSetVersion.formatMinorVersion;
+                debugInfo.addStringEntry(statusKey, "OK")
+                        .addStringEntry(debugKeyPrefix + "formatVersion", formatVersionString)
+                        .addStringEntry(debugKeyPrefix + "rulesVersion",
+                                tzDataSetVersion.rulesVersion)
+                        .addStringEntry(debugKeyPrefix + "revision",
+                                tzDataSetVersion.revision);
+            } catch (IOException | TzDataSetException e) {
+                debugInfo.addStringEntry(statusKey, "ERROR");
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_class", e.getClass().getName());
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_msg", e.getMessage());
+                System.logE("Error reading " + file, e);
+            }
+        } else {
+            debugInfo.addStringEntry(statusKey, "NOT_FOUND");
+        }
+    }
+
+    private static void populateTimeZoneLibraryReportedVersion(DebugInfo debugInfo) {
+        String debugKeyPrefix = CORE_LIBRARY_TIMEZONE_DEBUG_PREFIX + "lib.";
+        debugInfo.addStringEntry(
+                debugKeyPrefix + "icu4j.tzdb_version",
+                android.icu.util.TimeZone.getTZDataVersion());
+        debugInfo.addStringEntry(
+                debugKeyPrefix + "libcore.tzdb_version",
+                ZoneInfoDB.getInstance().getVersion());
+        debugInfo.addStringEntry(
+                debugKeyPrefix + "icu4c.tzdb_version",
+                libcore.icu.ICU.getTZDataVersion());
+    }
+}
diff --git a/luni/src/main/java/libcore/util/CountryTimeZones.java b/luni/src/main/java/libcore/util/CountryTimeZones.java
deleted file mode 100644
index f05bf28..0000000
--- a/luni/src/main/java/libcore/util/CountryTimeZones.java
+++ /dev/null
@@ -1,483 +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.util;
-
-import android.icu.util.TimeZone;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-
-/**
- * Information about a country's time zones.
- */
-public final class CountryTimeZones {
-
-    /**
-     * The result of lookup up a time zone using offset information (and possibly more).
-     */
-    public final static class OffsetResult {
-
-        /** A zone that matches the supplied criteria. See also {@link #mOneMatch}. */
-        public final TimeZone mTimeZone;
-
-        /** True if there is one match for the supplied criteria */
-        public final boolean mOneMatch;
-
-        public OffsetResult(TimeZone timeZone, boolean oneMatch) {
-            mTimeZone = java.util.Objects.requireNonNull(timeZone);
-            mOneMatch = oneMatch;
-        }
-
-        @Override
-        public String toString() {
-            return "Result{" +
-                    "mTimeZone='" + mTimeZone + '\'' +
-                    ", mOneMatch=" + mOneMatch +
-                    '}';
-        }
-    }
-
-    /**
-     * A mapping to a time zone ID with some associated metadata.
-     */
-    public final static class TimeZoneMapping {
-        public final String timeZoneId;
-        public final boolean showInPicker;
-        public final Long notUsedAfter;
-
-        TimeZoneMapping(String timeZoneId, boolean showInPicker, Long notUsedAfter) {
-            this.timeZoneId = timeZoneId;
-            this.showInPicker = showInPicker;
-            this.notUsedAfter = notUsedAfter;
-        }
-
-        // VisibleForTesting
-        public static TimeZoneMapping createForTests(
-                String timeZoneId, boolean showInPicker, Long notUsedAfter) {
-            return new TimeZoneMapping(timeZoneId, showInPicker, notUsedAfter);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-            TimeZoneMapping that = (TimeZoneMapping) o;
-            return showInPicker == that.showInPicker &&
-                    Objects.equals(timeZoneId, that.timeZoneId) &&
-                    Objects.equals(notUsedAfter, that.notUsedAfter);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(timeZoneId, showInPicker, notUsedAfter);
-        }
-
-        @Override
-        public String toString() {
-            return "TimeZoneMapping{"
-                    + "timeZoneId='" + timeZoneId + '\''
-                    + ", showInPicker=" + showInPicker
-                    + ", notUsedAfter=" + notUsedAfter
-                    + '}';
-        }
-
-        /**
-         * Returns {@code true} if one of the supplied {@link TimeZoneMapping} objects is for the
-         * specified time zone ID.
-         */
-        public static boolean containsTimeZoneId(
-                List<TimeZoneMapping> timeZoneMappings, String timeZoneId) {
-            for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-                if (timeZoneMapping.timeZoneId.equals(timeZoneId)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    private final String countryIso;
-    private final String defaultTimeZoneId;
-    private final List<TimeZoneMapping> timeZoneMappings;
-    private final boolean everUsesUtc;
-
-    // Memoized frozen ICU TimeZone object for the default.
-    private TimeZone icuDefaultTimeZone;
-    // Memoized frozen ICU TimeZone objects for the timeZoneIds.
-    private List<TimeZone> icuTimeZones;
-
-    private CountryTimeZones(String countryIso, String defaultTimeZoneId, boolean everUsesUtc,
-            List<TimeZoneMapping> timeZoneMappings) {
-        this.countryIso = java.util.Objects.requireNonNull(countryIso);
-        this.defaultTimeZoneId = defaultTimeZoneId;
-        this.everUsesUtc = everUsesUtc;
-        // Create a defensive copy of the mapping list.
-        this.timeZoneMappings = Collections.unmodifiableList(new ArrayList<>(timeZoneMappings));
-    }
-
-    /**
-     * Creates a {@link CountryTimeZones} object containing only known time zone IDs.
-     */
-    public static CountryTimeZones createValidated(String countryIso, String defaultTimeZoneId,
-            boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo) {
-
-        // We rely on ZoneInfoDB to tell us what the known valid time zone IDs are. ICU may
-        // recognize more but we want to be sure that zone IDs can be used with java.util as well as
-        // android.icu and ICU is expected to have a superset.
-        String[] validTimeZoneIdsArray = ZoneInfoDB.getInstance().getAvailableIDs();
-        HashSet<String> validTimeZoneIdsSet = new HashSet<>(Arrays.asList(validTimeZoneIdsArray));
-        List<TimeZoneMapping> validCountryTimeZoneMappings = new ArrayList<>();
-        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-            String timeZoneId = timeZoneMapping.timeZoneId;
-            if (!validTimeZoneIdsSet.contains(timeZoneId)) {
-                System.logW("Skipping invalid zone: " + timeZoneId + " at " + debugInfo);
-            } else {
-                validCountryTimeZoneMappings.add(timeZoneMapping);
-            }
-        }
-
-        // We don't get too strict at runtime about whether the defaultTimeZoneId must be
-        // one of the country's time zones because this is the data we have to use (we also
-        // assume the data was validated by earlier steps). The default time zone ID must just
-        // be a recognized zone ID: if it's not valid we leave it null.
-        if (!validTimeZoneIdsSet.contains(defaultTimeZoneId)) {
-            System.logW("Invalid default time zone ID: " + defaultTimeZoneId
-                    + " at " + debugInfo);
-            defaultTimeZoneId = null;
-        }
-
-        String normalizedCountryIso = normalizeCountryIso(countryIso);
-        return new CountryTimeZones(
-                normalizedCountryIso, defaultTimeZoneId, everUsesUtc, validCountryTimeZoneMappings);
-    }
-
-    /**
-     * Returns the ISO code for the country.
-     */
-    public String getCountryIso() {
-        return countryIso;
-    }
-
-    /**
-     * Returns true if the ISO code for the country is a match for the one specified.
-     */
-    public boolean isForCountryCode(String countryIso) {
-        return this.countryIso.equals(normalizeCountryIso(countryIso));
-    }
-
-    /**
-     * Returns the default time zone ID for the country. Can return null in cases when no data is
-     * available or the time zone ID provided to
-     * {@link #createValidated(String, String, boolean, List, String)} was not recognized.
-     */
-    public synchronized TimeZone getDefaultTimeZone() {
-        if (icuDefaultTimeZone == null) {
-            TimeZone defaultTimeZone;
-            if (defaultTimeZoneId == null) {
-                defaultTimeZone = null;
-            } else {
-                defaultTimeZone = getValidFrozenTimeZoneOrNull(defaultTimeZoneId);
-            }
-            icuDefaultTimeZone = defaultTimeZone;
-        }
-        return icuDefaultTimeZone;
-    }
-
-    /**
-     * Returns the default time zone ID for the country. Can return null in cases when no data is
-     * available or the time zone ID provided to
-     * {@link #createValidated(String, String, boolean, List, String)} was not recognized.
-     */
-    public String getDefaultTimeZoneId() {
-        return defaultTimeZoneId;
-    }
-
-    /**
-     * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
-     * "priority" order. The list can be empty if there were no zones configured or the configured
-     * zone IDs were not recognized.
-     */
-    public List<TimeZoneMapping> getTimeZoneMappings() {
-        return timeZoneMappings;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        CountryTimeZones that = (CountryTimeZones) o;
-
-        if (everUsesUtc != that.everUsesUtc) {
-            return false;
-        }
-        if (!countryIso.equals(that.countryIso)) {
-            return false;
-        }
-        if (defaultTimeZoneId != null ? !defaultTimeZoneId.equals(that.defaultTimeZoneId)
-                : that.defaultTimeZoneId != null) {
-            return false;
-        }
-        return timeZoneMappings.equals(that.timeZoneMappings);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = countryIso.hashCode();
-        result = 31 * result + (defaultTimeZoneId != null ? defaultTimeZoneId.hashCode() : 0);
-        result = 31 * result + timeZoneMappings.hashCode();
-        result = 31 * result + (everUsesUtc ? 1 : 0);
-        return result;
-    }
-
-    /**
-     * Returns an ordered list of time zones for the country in an undefined but "priority"
-     * order for a country. The list can be empty if there were no zones configured or the
-     * configured zone IDs were not recognized.
-     */
-    public synchronized List<TimeZone> getIcuTimeZones() {
-        if (icuTimeZones == null) {
-            ArrayList<TimeZone> mutableList = new ArrayList<>(timeZoneMappings.size());
-            for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-                String timeZoneId = timeZoneMapping.timeZoneId;
-                TimeZone timeZone;
-                if (timeZoneId.equals(defaultTimeZoneId)) {
-                    timeZone = getDefaultTimeZone();
-                } else {
-                    timeZone = getValidFrozenTimeZoneOrNull(timeZoneId);
-                }
-                // This shouldn't happen given the validation that takes place in
-                // createValidatedCountryTimeZones().
-                if (timeZone == null) {
-                    System.logW("Skipping invalid zone: " + timeZoneId);
-                    continue;
-                }
-                mutableList.add(timeZone);
-            }
-            icuTimeZones = Collections.unmodifiableList(mutableList);
-        }
-        return icuTimeZones;
-    }
-
-    /**
-     * Returns true if the country has at least one zone that is the same as UTC at the given time.
-     */
-    public boolean hasUtcZone(long whenMillis) {
-        // If the data tells us the country never uses UTC we don't have to check anything.
-        if (!everUsesUtc) {
-            return false;
-        }
-
-        for (TimeZone zone : getIcuTimeZones()) {
-            if (zone.getOffset(whenMillis) == 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns {@code true} if the default time zone for the country is either the only zone used or
-     * if it has the same offsets as all other zones used by the country <em>at the specified time
-     * </em> making the default equivalent to all other zones used by the country <em>at that time
-     * </em>.
-     */
-    public boolean isDefaultOkForCountryTimeZoneDetection(long whenMillis) {
-        if (timeZoneMappings.isEmpty()) {
-            // Should never happen unless there's been an error loading the data.
-            return false;
-        } else if (timeZoneMappings.size() == 1) {
-            // The default is the only zone so it's a good candidate.
-            return true;
-        } else {
-            TimeZone countryDefault = getDefaultTimeZone();
-            if (countryDefault == null) {
-                return false;
-            }
-
-            int countryDefaultOffset = countryDefault.getOffset(whenMillis);
-            List<TimeZone> candidates = getIcuTimeZones();
-            for (TimeZone candidate : candidates) {
-                if (candidate == countryDefault) {
-                    continue;
-                }
-
-                int candidateOffset = candidate.getOffset(whenMillis);
-                if (countryDefaultOffset != candidateOffset) {
-                    // Multiple different offsets means the default should not be used.
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Returns a time zone for the country, if there is one, that has the desired properties. If
-     * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
-     * an arbitrary match is returned based on the {@link #getTimeZoneMappings()} ordering.
-     *
-     * @param offsetMillis the offset from UTC at {@code whenMillis}
-     * @param isDst whether the zone is in DST
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be null
-     * @deprecated Use {@link #lookupByOffsetWithBias(int, Integer, long, TimeZone)} instead
-     */
-    @Deprecated
-    public OffsetResult lookupByOffsetWithBias(int offsetMillis, boolean isDst, long whenMillis,
-            TimeZone bias) {
-        if (timeZoneMappings == null || timeZoneMappings.isEmpty()) {
-            return null;
-        }
-
-        List<TimeZone> candidates = getIcuTimeZones();
-
-        TimeZone firstMatch = null;
-        boolean biasMatched = false;
-        boolean oneMatch = true;
-        for (TimeZone match : candidates) {
-            if (!offsetMatchesAtTime(match, offsetMillis, isDst, whenMillis)) {
-                continue;
-            }
-
-            if (firstMatch == null) {
-                firstMatch = match;
-            } else {
-                oneMatch = false;
-            }
-            if (bias != null && match.getID().equals(bias.getID())) {
-                biasMatched = true;
-            }
-            if (firstMatch != null && !oneMatch && (bias == null || biasMatched)) {
-                break;
-            }
-        }
-        if (firstMatch == null) {
-            return null;
-        }
-
-        TimeZone toReturn = biasMatched ? bias : firstMatch;
-        return new OffsetResult(toReturn, oneMatch);
-    }
-
-    /**
-     * Returns {@code true} if the specified offset, DST state and time would be valid in the
-     * timeZone.
-     */
-    private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis, boolean isDst,
-            long whenMillis) {
-        int[] offsets = new int[2];
-        timeZone.getOffset(whenMillis, false /* local */, offsets);
-
-        // offsets[1] == 0 when the zone is not in DST.
-        boolean zoneIsDst = offsets[1] != 0;
-        if (isDst != zoneIsDst) {
-            return false;
-        }
-        return offsetMillis == (offsets[0] + offsets[1]);
-    }
-
-    /**
-     * Returns a time zone for the country, if there is one, that has the desired properties. If
-     * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
-     * an arbitrary match is returned based on the {@link #getTimeZoneMappings()} ordering.
-     *
-     * @param offsetMillis the offset from UTC at {@code whenMillis}
-     * @param dstOffsetMillis the part of {@code offsetMillis} contributed by DST, {@code null}
-     *                        means unknown
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be null
-     */
-    public OffsetResult lookupByOffsetWithBias(int offsetMillis, Integer dstOffsetMillis,
-            long whenMillis, TimeZone bias) {
-        if (timeZoneMappings == null || timeZoneMappings.isEmpty()) {
-            return null;
-        }
-
-        List<TimeZone> candidates = getIcuTimeZones();
-
-        TimeZone firstMatch = null;
-        boolean biasMatched = false;
-        boolean oneMatch = true;
-        for (TimeZone match : candidates) {
-            if (!offsetMatchesAtTime(match, offsetMillis, dstOffsetMillis, whenMillis)) {
-                continue;
-            }
-
-            if (firstMatch == null) {
-                firstMatch = match;
-            } else {
-                oneMatch = false;
-            }
-            if (bias != null && match.getID().equals(bias.getID())) {
-                biasMatched = true;
-            }
-            if (firstMatch != null && !oneMatch && (bias == null || biasMatched)) {
-                break;
-            }
-        }
-        if (firstMatch == null) {
-            return null;
-        }
-
-        TimeZone toReturn = biasMatched ? bias : firstMatch;
-        return new OffsetResult(toReturn, oneMatch);
-    }
-
-    /**
-     * Returns {@code true} if the specified offset, DST and time would be valid in the
-     * timeZone.
-     */
-    private static boolean offsetMatchesAtTime(TimeZone timeZone, int offsetMillis,
-            Integer dstOffsetMillis, long whenMillis) {
-        int[] offsets = new int[2];
-        timeZone.getOffset(whenMillis, false /* local */, offsets);
-
-        if (dstOffsetMillis != null) {
-            if (dstOffsetMillis.intValue() != offsets[1]) {
-                return false;
-            }
-        }
-        return offsetMillis == (offsets[0] + offsets[1]);
-    }
-
-    private static TimeZone getValidFrozenTimeZoneOrNull(String timeZoneId) {
-        TimeZone timeZone = TimeZone.getFrozenTimeZone(timeZoneId);
-        if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
-            return null;
-        }
-        return timeZone;
-    }
-
-    private static String normalizeCountryIso(String countryIso) {
-        // Lowercase ASCII is normalized for the purposes of the code in this class.
-        return countryIso.toLowerCase(Locale.US);
-    }
-}
diff --git a/luni/src/main/java/libcore/util/CountryZonesFinder.java b/luni/src/main/java/libcore/util/CountryZonesFinder.java
deleted file mode 100644
index cbc8a1b..0000000
--- a/luni/src/main/java/libcore/util/CountryZonesFinder.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import libcore.util.CountryTimeZones.TimeZoneMapping;
-
-/**
- * An in-memory representation of country &lt;-&gt; time zone mapping data.
- */
-public final class CountryZonesFinder {
-
-    private final List<CountryTimeZones> countryTimeZonesList;
-
-    CountryZonesFinder(List<CountryTimeZones> countryTimeZonesList) {
-        this.countryTimeZonesList = new ArrayList<>(countryTimeZonesList);
-    }
-
-    // VisibleForTesting
-    public static CountryZonesFinder createForTests(List<CountryTimeZones> countryTimeZonesList) {
-        return new CountryZonesFinder(countryTimeZonesList);
-    }
-
-    /**
-     * Returns an immutable list of country ISO codes with time zones. The codes can be passed to
-     * {@link #lookupCountryTimeZones(String)} and similar methods.
-     */
-    public List<String> lookupAllCountryIsoCodes() {
-        List<String> isoCodes = new ArrayList<>(countryTimeZonesList.size());
-        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
-            isoCodes.add(countryTimeZones.getCountryIso());
-        }
-        return Collections.unmodifiableList(isoCodes);
-    }
-
-    /**
-     * Returns an immutable list of {@link CountryTimeZones} for countries that use the specified
-     * time zone. An exact, case-sensitive match is performed on the zone ID. This method never
-     * returns null.
-     */
-    public List<CountryTimeZones> lookupCountryTimeZonesForZoneId(String zoneId) {
-        List<CountryTimeZones> matches = new ArrayList<>(2);
-        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
-            boolean match = TimeZoneMapping.containsTimeZoneId(
-                    countryTimeZones.getTimeZoneMappings(), zoneId);
-            if (match) {
-                matches.add(countryTimeZones);
-            }
-        }
-        return Collections.unmodifiableList(matches);
-    }
-
-    /**
-     * Returns a {@link CountryTimeZones} object associated with the specified country code. If one
-     * cannot be found this method returns {@code null}.
-     */
-    public CountryTimeZones lookupCountryTimeZones(String countryIso) {
-        String normalizedCountryIso = TimeZoneFinder.normalizeCountryIso(countryIso);
-        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
-            if (countryTimeZones.getCountryIso().equals(normalizedCountryIso)) {
-                return countryTimeZones;
-            }
-        }
-        return null;
-    }
-}
diff --git a/luni/src/main/java/libcore/util/DebugInfo.java b/luni/src/main/java/libcore/util/DebugInfo.java
new file mode 100644
index 0000000..78baa71
--- /dev/null
+++ b/luni/src/main/java/libcore/util/DebugInfo.java
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A container class for debug information.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public class DebugInfo {
+    private final List<DebugEntry> entries;
+
+    @libcore.api.CorePlatformApi
+    public DebugInfo() {
+        this.entries = new ArrayList<>();
+    }
+
+    /**
+     * Adds a key / string value.
+     *
+     * @return {@code this} for chaining calls
+     */
+    @libcore.api.CorePlatformApi
+    public DebugInfo addStringEntry(String key, String value) {
+        entries.add(new DebugEntry(key, value));
+        return this;
+    }
+
+    /**
+     * Adds a key / string value. Converts the supplied int value to a String.
+     *
+     * @return {@code this} for chaining calls
+     */
+    @libcore.api.CorePlatformApi
+    public DebugInfo addStringEntry(String key, int value) {
+        addStringEntry(key, Integer.toString(value));
+        return this;
+    }
+
+    /** Returns all the debug entries. */
+    @libcore.api.CorePlatformApi
+    public List<DebugEntry> getDebugEntries() {
+        return entries;
+    }
+
+    /** Returns the first debug entry with the given key, or {@code null} if it does not exist. */
+    public DebugEntry getDebugEntry(String key) {
+        for (DebugEntry entry : getDebugEntries()) {
+            if (key.equals(entry.getKey())) {
+                return entry;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * A generic key/value for a single piece of debug information.
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    public static class DebugEntry {
+        private final String key;
+        private final String stringValue;
+
+        @libcore.api.CorePlatformApi
+        public DebugEntry(String key, String stringValue) {
+            this.key = key;
+            this.stringValue = stringValue;
+        }
+
+        @libcore.api.CorePlatformApi
+        public String getKey() {
+            return key;
+        }
+
+        @libcore.api.CorePlatformApi
+        public String getStringValue() {
+            return stringValue;
+        }
+    }
+}
diff --git a/luni/src/main/java/libcore/util/EmptyArray.java b/luni/src/main/java/libcore/util/EmptyArray.java
index eac06f2..5b60683 100644
--- a/luni/src/main/java/libcore/util/EmptyArray.java
+++ b/luni/src/main/java/libcore/util/EmptyArray.java
@@ -16,19 +16,34 @@
 
 package libcore.util;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+/** @hide */
+@libcore.api.CorePlatformApi
 public final class EmptyArray {
     private EmptyArray() {}
 
+    @libcore.api.CorePlatformApi
     public static final boolean[] BOOLEAN = new boolean[0];
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static final byte[] BYTE = new byte[0];
     public static final char[] CHAR = new char[0];
     public static final double[] DOUBLE = new double[0];
+    @libcore.api.CorePlatformApi
     public static final float[] FLOAT = new float[0];
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static final int[] INT = new int[0];
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static final long[] LONG = new long[0];
 
     public static final Class<?>[] CLASS = new Class[0];
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
     public static final Object[] OBJECT = new Object[0];
+    @libcore.api.CorePlatformApi
     public static final String[] STRING = new String[0];
     public static final Throwable[] THROWABLE = new Throwable[0];
     public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
diff --git a/luni/src/main/java/libcore/util/HexEncoding.java b/luni/src/main/java/libcore/util/HexEncoding.java
index 5303bb4..eceec6b 100644
--- a/luni/src/main/java/libcore/util/HexEncoding.java
+++ b/luni/src/main/java/libcore/util/HexEncoding.java
@@ -18,7 +18,9 @@
 
 /**
  * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class HexEncoding {
 
     /** Hidden constructor to prevent instantiation. */
@@ -29,6 +31,7 @@
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
      */
+    @libcore.api.CorePlatformApi
     public static char[] encode(byte[] data) {
         return encode(data, 0, data.length);
     }
@@ -36,6 +39,7 @@
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
      */
+    @libcore.api.CorePlatformApi
     public static char[] encode(byte[] data, int offset, int len) {
         char[] result = new char[len * 2];
         for (int i = 0; i < len; i++) {
@@ -51,6 +55,7 @@
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
      */
+    @libcore.api.CorePlatformApi
     public static String encodeToString(byte[] data) {
         return new String(encode(data));
     }
@@ -61,6 +66,7 @@
      *
      * Throws an {@code IllegalArgumentException} if the input is malformed.
      */
+    @libcore.api.CorePlatformApi
     public static byte[] decode(String encoded) throws IllegalArgumentException {
         return decode(encoded.toCharArray());
     }
@@ -82,6 +88,7 @@
      *
      * Throws an {@code IllegalArgumentException} if the input is malformed.
      */
+    @libcore.api.CorePlatformApi
     public static byte[] decode(char[] encoded) throws IllegalArgumentException {
         return decode(encoded, false);
     }
@@ -93,6 +100,7 @@
      *
      * Throws an {@code IllegalArgumentException} if the input is malformed.
      */
+    @libcore.api.CorePlatformApi
     public static byte[] decode(char[] encoded, boolean allowSingleChar) throws IllegalArgumentException {
         int resultLengthBytes = (encoded.length + 1) / 2;
         byte[] result = new byte[resultLengthBytes];
diff --git a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
index 57caa05..5dc1e98 100644
--- a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
+++ b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
@@ -19,6 +19,8 @@
 import dalvik.system.VMRuntime;
 import sun.misc.Cleaner;
 
+import java.lang.ref.Reference;
+
 /**
  * A NativeAllocationRegistry is used to associate native allocations with
  * Java objects and register them with the runtime.
@@ -38,49 +40,158 @@
  * used to register any number of native allocations of that kind.
  * @hide
  */
+@libcore.api.CorePlatformApi
 public class NativeAllocationRegistry {
 
     private final ClassLoader classLoader;
+
+    // Pointer to native deallocation function of type void f(void* freeFunction).
     private final long freeFunction;
+
+    // The size of the registered native objects. This can be, and usually is, approximate.
+    // The least significant bit is one iff the object was allocated primarily with system
+    // malloc().
+    // This field is examined by ahat and other tools. We chose this encoding of the "is_malloced"
+    // information to (a) allow existing readers to continue to work with minimal confusion,
+    // and (b) to avoid adding a field to NativeAllocationRegistry objects.
     private final long size;
+    // Bit mask for "is_malloced" information.
+    private static final long IS_MALLOCED = 0x1;
 
     /**
-     * Constructs a NativeAllocationRegistry for a particular kind of native
-     * allocation.
-     * The address of a native function that can be used to free this kind
-     * native allocation should be provided using the
-     * <code>freeFunction</code> argument. The native function should have the
-     * type:
+     * Return a NativeAllocationRegistry for native memory that is mostly
+     * allocated by means other than the system memory allocator. For example,
+     * the memory may be allocated directly with mmap.
+     * @param classLoader  ClassLoader that was used to load the native
+     *                     library defining freeFunction.
+     *                     This ensures that the the native library isn't unloaded
+     *                     before freeFunction is called.
+     * @param freeFunction address of a native function of type
+     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     kind of native allocation
+     * @param size         estimated size in bytes of the part of the described
+     *                     native memory that is not allocated with system malloc.
+     *                     Approximate values are acceptable.
+     * @throws IllegalArgumentException If <code>size</code> is negative
+     */
+    @libcore.api.CorePlatformApi
+    public static NativeAllocationRegistry createNonmalloced(
+            ClassLoader classLoader, long freeFunction, long size) {
+        return new NativeAllocationRegistry(classLoader, freeFunction, size, false);
+    }
+
+    /**
+     * Return a NativeAllocationRegistry for native memory that is mostly
+     * allocated by the system memory allocator.
+     * For example, the memory may be allocated directly with new or malloc.
+     * <p>
+     * The native function should have the type:
      * <pre>
      *    void f(void* nativePtr);
      * </pre>
      * <p>
-     * The <code>classLoader</code> argument should be the class loader used
-     * to load the native library that freeFunction belongs to. This is needed
-     * to ensure the native library doesn't get unloaded before freeFunction
-     * is called.
+     * @param classLoader  ClassLoader that was used to load the native
+     *                     library freeFunction belongs to.
+     * @param freeFunction address of a native function of type
+     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     kind of native allocation
+     * @param size         estimated size in bytes of the part of the described
+     *                     native memory allocated with system malloc.
+     *                     Approximate values are acceptable. For sizes less than
+     *                     a few hundered KB, use the simplified overload below.
+     * @throws IllegalArgumentException If <code>size</code> is negative
+     */
+    @libcore.api.CorePlatformApi
+    public static NativeAllocationRegistry createMalloced(
+            ClassLoader classLoader, long freeFunction, long size) {
+        return new NativeAllocationRegistry(classLoader, freeFunction, size, true);
+    }
+
+    /**
+     * Return a NativeAllocationRegistry for native memory that is mostly
+     * allocated by the system memory allocator. This version is preferred
+     * for smaller objects (typically less than a few hundred KB).
+     * @param classLoader  ClassLoader that was used to load the native
+     *                     library freeFunction belongs to.
+     * @param freeFunction address of a native function of type
+     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     kind of native allocation
+     */
+    @libcore.api.CorePlatformApi
+    public static NativeAllocationRegistry createMalloced(
+            ClassLoader classLoader, long freeFunction) {
+        return new NativeAllocationRegistry(classLoader, freeFunction, 0, true);
+    }
+
+    /**
+     * Constructs a NativeAllocationRegistry for a particular kind of native
+     * allocation.
      * <p>
      * The <code>size</code> should be an estimate of the total number of
      * native bytes this kind of native allocation takes up. Different
      * NativeAllocationRegistrys must be used to register native allocations
      * with different estimated sizes, even if they use the same
-     * <code>freeFunction</code>.
+     * <code>freeFunction</code>. This is used to help inform the garbage
+     * collector about the possible need for collection. Memory allocated with
+     * native malloc is implicitly included, and ideally should not be included in this
+     * argument.
+     * <p>
      * @param classLoader  ClassLoader that was used to load the native
      *                     library freeFunction belongs to.
      * @param freeFunction address of a native function used to free this
      *                     kind of native allocation
      * @param size         estimated size in bytes of this kind of native
-     *                     allocation
-     * @throws IllegalArgumentException If <code>size</code> is negative
+     *                     allocation. If mallocAllocation is false, then this
+     *                     should ideally exclude memory allocated by system
+     *                     malloc. However including it will simply double-count it,
+     *                     typically resulting in slightly increased GC frequency.
+     *                     If mallocAllocation is true, then this affects only the
+     *                     frequency with which we sample the malloc heap, and debugging
+     *                     tools. In this case a value of zero is commonly used to
+     *                     indicate an unknown non-huge size.
+     * @param mallocAllocation the native object is primarily allocated via malloc.
      */
-    public NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size) {
+    private NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size,
+            boolean mallocAllocation) {
         if (size < 0) {
             throw new IllegalArgumentException("Invalid native allocation size: " + size);
         }
-
         this.classLoader = classLoader;
         this.freeFunction = freeFunction;
-        this.size = size;
+        this.size = mallocAllocation ? (size | IS_MALLOCED) : (size & ~IS_MALLOCED);
+    }
+
+    /**
+     * Constructs a NativeAllocationRegistry for a particular kind of native
+     * allocation.
+     * <p>
+     * New code should use the preceding factory methods rather than calling this
+     * constructor directly.
+     * <p>
+     * The <code>size</code> should be an estimate of the total number of
+     * native bytes this kind of native allocation takes up excluding bytes allocated
+     * with system malloc. Different
+     * NativeAllocationRegistrys must be used to register native allocations
+     * with different estimated sizes, even if they use the same
+     * <code>freeFunction</code>. This is used to help inform the garbage
+     * collector about the possible need for collection. Memory allocated with
+     * native malloc is implicitly included, and ideally should not be included in this
+     * argument.
+     * <p>
+     * @param classLoader  ClassLoader that was used to load the native
+     *                     library freeFunction belongs to.
+     * @param freeFunction address of a native function used to free this
+     *                     kind of native allocation
+     * @param size         estimated size in bytes of this kind of native
+     *                     allocation, excluding memory allocated with system malloc.
+     *                     A value of 0 indicates that the memory was allocated mainly
+     *                     with malloc.
+     *
+     * @param mallocAllocation the native object is primarily allocated via malloc.
+     */
+    @libcore.api.CorePlatformApi
+    public NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size) {
+        this(classLoader, freeFunction, size, size == 0);
     }
 
     /**
@@ -115,6 +226,7 @@
      *                           argument before the OutOfMemoryError is
      *                           thrown.
      */
+    @libcore.api.CorePlatformApi
     public Runnable registerNativeAllocation(Object referent, long nativePtr) {
         if (referent == null) {
             throw new IllegalArgumentException("referent is null");
@@ -136,56 +248,8 @@
         } // Other exceptions are impossible.
         // Enable the cleaner only after we can no longer throw anything, including OOME.
         thunk.setNativePtr(nativePtr);
-        return result;
-    }
-
-    /**
-     * Interface for custom native allocation allocators used by
-     * {@link #registerNativeAllocation(Object, Allocator) registerNativeAllocation(Object, Allocator)}.
-     */
-    public interface Allocator {
-        /**
-         * Allocate a native allocation and return its address.
-         */
-        long allocate();
-    }
-
-    /**
-     * Registers and allocates a new native allocation and associated Java
-     * object with the runtime.
-     * This can be used for registering large allocations where the underlying
-     * native allocation shouldn't be performed until it's clear there is
-     * enough space on the Java heap to register the allocation.
-     * <p>
-     * If the allocator returns null, the allocation is not registered and a
-     * null Runnable is returned.
-     *
-     * @param referent      Non-null java object to associate the native allocation with
-     * @param allocator     used to perform the underlying native allocation.
-     * @return runnable to explicitly free native allocation
-     * @throws IllegalArgumentException if referent is null.
-     * @throws OutOfMemoryError  if there is not enough space on the Java heap
-     *                           in which to register the allocation. In this
-     *                           case, the allocator will not be run.
-     */
-    public Runnable registerNativeAllocation(Object referent, Allocator allocator) {
-        if (referent == null) {
-            throw new IllegalArgumentException("referent is null");
-        }
-
-        // Create the cleaner before running the allocator so that
-        // VMRuntime.registerNativeFree is eventually called if the allocate
-        // method throws an exception.
-        CleanerThunk thunk = new CleanerThunk();
-        Cleaner cleaner = Cleaner.create(referent, thunk);
-        CleanerRunner result = new CleanerRunner(cleaner);
-        long nativePtr = allocator.allocate();
-        if (nativePtr == 0) {
-            cleaner.clean();
-            return null;
-        }
-        registerNativeAllocation(this.size);
-        thunk.setNativePtr(nativePtr);
+        // Ensure that cleaner doesn't get invoked before we enable it.
+        Reference.reachabilityFence(referent);
         return result;
     }
 
@@ -220,14 +284,27 @@
         }
     }
 
-    // TODO: Change the runtime to support passing the size as a long instead
-    // of an int. For now, we clamp the size to fit.
+    // Inform the garbage collector of the allocation. We do this differently for
+    // malloc-based allocations.
     private static void registerNativeAllocation(long size) {
-        VMRuntime.getRuntime().registerNativeAllocation((int)Math.min(size, Integer.MAX_VALUE));
+        VMRuntime runtime = VMRuntime.getRuntime();
+        if ((size & IS_MALLOCED) != 0) {
+            final long notifyImmediateThreshold = 300000;
+            if (size >= notifyImmediateThreshold) {
+                runtime.notifyNativeAllocationsInternal();
+            } else {
+                runtime.notifyNativeAllocation();
+            }
+        } else {
+            runtime.registerNativeAllocation(size);
+        }
     }
 
+    // Inform the garbage collector of deallocation, if appropriate.
     private static void registerNativeFree(long size) {
-        VMRuntime.getRuntime().registerNativeFree((int)Math.min(size, Integer.MAX_VALUE));
+        if ((size & IS_MALLOCED) == 0) {
+            VMRuntime.getRuntime().registerNativeFree(size);
+        }
     }
 
     /**
@@ -236,6 +313,7 @@
      * native allocation using a <code>freeFunction</code> without using a
      * NativeAllocationRegistry.
      */
+    @libcore.api.CorePlatformApi
     public static native void applyFreeFunction(long freeFunction, long nativePtr);
 }
 
diff --git a/luni/src/main/java/libcore/util/NonNull.java b/luni/src/main/java/libcore/util/NonNull.java
index f2f2ef6..900e581 100644
--- a/luni/src/main/java/libcore/util/NonNull.java
+++ b/luni/src/main/java/libcore/util/NonNull.java
@@ -16,7 +16,6 @@
 package libcore.util;
 
 import static java.lang.annotation.ElementType.TYPE_USE;
-import static java.lang.annotation.ElementType.TYPE_PARAMETER;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import java.lang.annotation.Documented;
@@ -27,10 +26,12 @@
  * Denotes that a type use can never be null.
  * <p>
  * This is a marker annotation and it has no specific attributes.
+ * @hide
  */
 @Documented
 @Retention(SOURCE)
 @Target({TYPE_USE})
+@libcore.api.IntraCoreApi
 public @interface NonNull {
    /**
     * Min Android API level (inclusive) to which this annotation is applied.
diff --git a/luni/src/main/java/libcore/util/Nullable.java b/luni/src/main/java/libcore/util/Nullable.java
index c2823af..c8cbe38 100644
--- a/luni/src/main/java/libcore/util/Nullable.java
+++ b/luni/src/main/java/libcore/util/Nullable.java
@@ -16,7 +16,6 @@
 package libcore.util;
 
 import static java.lang.annotation.ElementType.TYPE_USE;
-import static java.lang.annotation.ElementType.TYPE_PARAMETER;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import java.lang.annotation.Documented;
@@ -27,10 +26,12 @@
  * Denotes that a type use can be a null.
  * <p>
  * This is a marker annotation and it has no specific attributes.
+ * @hide
  */
 @Documented
 @Retention(SOURCE)
 @Target({TYPE_USE})
+@libcore.api.IntraCoreApi
 public @interface Nullable {
    /**
     * Min Android API level (inclusive) to which this annotation is applied.
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/SneakyThrow.java b/luni/src/main/java/libcore/util/SneakyThrow.java
index 411d346..679996f 100644
--- a/luni/src/main/java/libcore/util/SneakyThrow.java
+++ b/luni/src/main/java/libcore/util/SneakyThrow.java
@@ -22,12 +22,20 @@
  *
  * See
  * http://www.mail-archive.com/javaposse@googlegroups.com/msg05984.html
+ *
+ * @hide
  */
+@libcore.api.CorePlatformApi
 public class SneakyThrow {
+
+    private SneakyThrow() {
+    }
+
     /**
      * A hacky method that always throws {@code t} even if {@code t} is a checked exception,
      * and is not declared to be thrown.
      */
+    @libcore.api.CorePlatformApi
     public static void sneakyThrow(Throwable t) {
         SneakyThrow.<RuntimeException>sneakyThrow_(t);
     }
@@ -36,4 +44,3 @@
        throw (T) t;
     }
 }
-
diff --git a/luni/src/main/java/libcore/util/TimeZoneDataFiles.java b/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
deleted file mode 100644
index c792665..0000000
--- a/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
+++ /dev/null
@@ -1,84 +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.util;
-
-/**
- * Utility methods associated with finding updateable time zone data files.
- */
-public final class TimeZoneDataFiles {
-
-    private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
-    private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
-
-    private TimeZoneDataFiles() {}
-
-    /**
-     * Returns two time zone file paths for the specified file name in an array in the order they
-     * should be tried. See {@link #generateIcuDataPath()} for ICU files instead.
-     * <ul>
-     * <li>[0] - the location of the file in the /data partition (may not exist).</li>
-     * <li>[1] - the location of the file in the /system partition (should exist).</li>
-     * </ul>
-     */
-    // VisibleForTesting
-    public static String[] getTimeZoneFilePaths(String fileName) {
-        return new String[] {
-                getDataTimeZoneFile(fileName),
-                getSystemTimeZoneFile(fileName)
-        };
-    }
-
-    private static String getDataTimeZoneFile(String fileName) {
-        return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/current/" + fileName;
-    }
-
-    // VisibleForTesting
-    public static String getSystemTimeZoneFile(String fileName) {
-        return System.getenv(ANDROID_ROOT_ENV) + "/usr/share/zoneinfo/" + fileName;
-    }
-
-    public static String generateIcuDataPath() {
-        StringBuilder icuDataPathBuilder = new StringBuilder();
-        // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
-        String dataIcuDataPath = getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu");
-        if (dataIcuDataPath != null) {
-            icuDataPathBuilder.append(dataIcuDataPath);
-        }
-
-        // ICU should always look in ANDROID_ROOT.
-        String systemIcuDataPath = getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu");
-        if (systemIcuDataPath != null) {
-            if (icuDataPathBuilder.length() > 0) {
-                icuDataPathBuilder.append(":");
-            }
-            icuDataPathBuilder.append(systemIcuDataPath);
-        }
-        return icuDataPathBuilder.toString();
-    }
-
-    /**
-     * Creates a path by combining the value of an environment variable with a relative path.
-     * Returns {@code null} if the environment variable is not set.
-     */
-    private static String getEnvironmentPath(String environmentVariable, String path) {
-        String variable = System.getenv(environmentVariable);
-        if (variable == null) {
-            return null;
-        }
-        return variable + path;
-    }
-}
diff --git a/luni/src/main/java/libcore/util/TimeZoneFinder.java b/luni/src/main/java/libcore/util/TimeZoneFinder.java
deleted file mode 100644
index 7c682d0..0000000
--- a/luni/src/main/java/libcore/util/TimeZoneFinder.java
+++ /dev/null
@@ -1,781 +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.util;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.icu.util.TimeZone;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import libcore.util.CountryTimeZones.TimeZoneMapping;
-
-/**
- * A class that can find matching time zones by loading data from the tzlookup.xml file.
- */
-public final class TimeZoneFinder {
-
-    private static final String TZLOOKUP_FILE_NAME = "tzlookup.xml";
-
-    // Root element. e.g. <timezones ianaversion="2017b">
-    private static final String TIMEZONES_ELEMENT = "timezones";
-    private static final String IANA_VERSION_ATTRIBUTE = "ianaversion";
-
-    // Country zones section. e.g. <countryzones>
-    private static final String COUNTRY_ZONES_ELEMENT = "countryzones";
-
-    // Country data. e.g. <country code="gb" default="Europe/London" everutc="y">
-    private static final String COUNTRY_ELEMENT = "country";
-    private static final String COUNTRY_CODE_ATTRIBUTE = "code";
-    private static final String DEFAULT_TIME_ZONE_ID_ATTRIBUTE = "default";
-    private static final String EVER_USES_UTC_ATTRIBUTE = "everutc";
-
-    // Country -> Time zone mapping. e.g. <id>ZoneId</id>, <id picker="n">ZoneId</id>,
-    // <id notafter={timestamp}>ZoneId</id>
-    // The default for the picker attribute when unspecified is "y".
-    // The notafter attribute is optional. It specifies a timestamp (time in milliseconds from Unix
-    // epoch start) after which the zone is not (effectively) in use. If unspecified the zone is in
-    // use forever.
-    private static final String ZONE_ID_ELEMENT = "id";
-    private static final String ZONE_SHOW_IN_PICKER_ATTRIBUTE = "picker";
-    private static final String ZONE_NOT_USED_AFTER_ATTRIBUTE = "notafter";
-
-    private static final String TRUE_ATTRIBUTE_VALUE = "y";
-    private static final String FALSE_ATTRIBUTE_VALUE = "n";
-
-    private static TimeZoneFinder instance;
-
-    private final ReaderSupplier xmlSource;
-
-    // Cached field for the last country looked up.
-    private CountryTimeZones lastCountryTimeZones;
-
-    private TimeZoneFinder(ReaderSupplier xmlSource) {
-        this.xmlSource = xmlSource;
-    }
-
-    /**
-     * Obtains an instance for use when resolving time zones. This method handles using the correct
-     * file when there are several to choose from. This method never returns {@code null}. No
-     * in-depth validation is performed on the file content, see {@link #validate()}.
-     */
-    public static TimeZoneFinder getInstance() {
-        synchronized(TimeZoneFinder.class) {
-            if (instance == null) {
-                String[] tzLookupFilePaths =
-                        TimeZoneDataFiles.getTimeZoneFilePaths(TZLOOKUP_FILE_NAME);
-                instance = createInstanceWithFallback(tzLookupFilePaths[0], tzLookupFilePaths[1]);
-            }
-        }
-        return instance;
-    }
-
-    // VisibleForTesting
-    public static TimeZoneFinder createInstanceWithFallback(String... tzLookupFilePaths) {
-        IOException lastException = null;
-        for (String tzLookupFilePath : tzLookupFilePaths) {
-            try {
-                // We assume that any file in /data was validated before install, and the system
-                // file was validated before the device shipped. Therefore, we do not pay the
-                // validation cost here.
-                return createInstance(tzLookupFilePath);
-            } catch (IOException e) {
-                // There's expected to be two files, and it's normal for the first file not to
-                // exist so we don't log, but keep the lastException so we can log it if there
-                // are no valid files available.
-                if (lastException != null) {
-                    e.addSuppressed(lastException);
-                }
-                lastException = e;
-            }
-        }
-
-        System.logE("No valid file found in set: " + Arrays.toString(tzLookupFilePaths)
-                + " Printing exceptions and falling back to empty map.", lastException);
-        return createInstanceForTests("<timezones><countryzones /></timezones>");
-    }
-
-    /**
-     * Obtains an instance using a specific data file, throwing an IOException if the file does not
-     * exist or is not readable. This method never returns {@code null}. No in-depth validation is
-     * performed on the file content, see {@link #validate()}.
-     */
-    public static TimeZoneFinder createInstance(String path) throws IOException {
-        ReaderSupplier xmlSupplier = ReaderSupplier.forFile(path, StandardCharsets.UTF_8);
-        return new TimeZoneFinder(xmlSupplier);
-    }
-
-    /** Used to create an instance using an in-memory XML String instead of a file. */
-    // VisibleForTesting
-    public static TimeZoneFinder createInstanceForTests(String xml) {
-        return new TimeZoneFinder(ReaderSupplier.forString(xml));
-    }
-
-    /**
-     * Parses the data file, throws an exception if it is invalid or cannot be read.
-     */
-    public void validate() throws IOException {
-        try {
-            processXml(new TimeZonesValidator());
-        } catch (XmlPullParserException e) {
-            throw new IOException("Parsing error", e);
-        }
-    }
-
-    /**
-     * Returns the IANA rules version associated with the data. If there is no version information
-     * or there is a problem reading the file then {@code null} is returned.
-     */
-    public String getIanaVersion() {
-        IanaVersionExtractor ianaVersionExtractor = new IanaVersionExtractor();
-        try {
-            processXml(ianaVersionExtractor);
-            return ianaVersionExtractor.getIanaVersion();
-        } catch (XmlPullParserException | IOException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Loads all the country &lt;-&gt; time zone mapping data into memory. This method can return
-     * {@code null} in the event of an error while reading the underlying data files.
-     */
-    public CountryZonesFinder getCountryZonesFinder() {
-        CountryZonesLookupExtractor extractor = new CountryZonesLookupExtractor();
-        try {
-            processXml(extractor);
-
-            return extractor.getCountryZonesLookup();
-        } catch (XmlPullParserException | IOException e) {
-            System.logW("Error reading country zones ", e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns a frozen ICU time zone that has / would have had the specified offset and DST value
-     * at the specified moment in the specified country.
-     *
-     * <p>In order to be considered a configured zone must match the supplied offset information.
-     *
-     * <p>Matches are considered in a well-defined order. If multiple zones match and one of them
-     * also matches the (optional) bias parameter then the bias time zone will be returned.
-     * Otherwise the first match found is returned.
-     */
-    public TimeZone lookupTimeZoneByCountryAndOffset(
-            String countryIso, int offsetMillis, boolean isDst, long whenMillis, TimeZone bias) {
-
-        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
-        if (countryTimeZones == null) {
-            return null;
-        }
-        CountryTimeZones.OffsetResult offsetResult =
-                countryTimeZones.lookupByOffsetWithBias(offsetMillis, isDst, whenMillis, bias);
-        return offsetResult != null ? offsetResult.mTimeZone : null;
-    }
-
-    /**
-     * Returns a "default" time zone ID known to be used in the specified country. This is
-     * the time zone ID that can be used if only the country code is known and can be presumed to be
-     * the "best" choice in the absence of other information. For countries with more than one zone
-     * the time zone will not be correct for everybody.
-     *
-     * <p>If the country code is not recognized or there is an error during lookup this can return
-     * null.
-     */
-    public String lookupDefaultTimeZoneIdByCountry(String countryIso) {
-        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
-        return countryTimeZones == null ? null : countryTimeZones.getDefaultTimeZoneId();
-    }
-
-    /**
-     * Returns an immutable list of frozen ICU time zones known to be used in the specified country.
-     * If the country code is not recognized or there is an error during lookup this can return
-     * null. The TimeZones returned will never contain {@link TimeZone#UNKNOWN_ZONE}. This method
-     * can return an empty list in a case when the underlying data files reference only unknown
-     * zone IDs.
-     */
-    public List<TimeZone> lookupTimeZonesByCountry(String countryIso) {
-        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
-        return countryTimeZones == null ? null : countryTimeZones.getIcuTimeZones();
-    }
-
-    /**
-     * Returns an immutable list of time zone IDs known to be used in the specified country.
-     * If the country code is not recognized or there is an error during lookup this can return
-     * null. The IDs returned will all be valid for use with
-     * {@link java.util.TimeZone#getTimeZone(String)} and
-     * {@link android.icu.util.TimeZone#getTimeZone(String)}. This method can return an empty list
-     * in a case when the underlying data files reference only unknown zone IDs.
-     */
-    public List<String> lookupTimeZoneIdsByCountry(String countryIso) {
-        CountryTimeZones countryTimeZones = lookupCountryTimeZones(countryIso);
-        return countryTimeZones == null
-                ? null : extractTimeZoneIds(countryTimeZones.getTimeZoneMappings());
-    }
-
-    /**
-     * Returns a {@link CountryTimeZones} object associated with the specified country code.
-     * Caching is handled as needed. If the country code is not recognized or there is an error
-     * during lookup this method can return null.
-     */
-    public CountryTimeZones lookupCountryTimeZones(String countryIso) {
-        synchronized (this) {
-            if (lastCountryTimeZones != null && lastCountryTimeZones.isForCountryCode(countryIso)) {
-                return lastCountryTimeZones;
-            }
-        }
-
-        SelectiveCountryTimeZonesExtractor extractor =
-                new SelectiveCountryTimeZonesExtractor(countryIso);
-        try {
-            processXml(extractor);
-
-            CountryTimeZones countryTimeZones = extractor.getValidatedCountryTimeZones();
-            if (countryTimeZones == null) {
-                // None matched. Return the null but don't change the cached value.
-                return null;
-            }
-
-            // Update the cached value.
-            synchronized (this) {
-                lastCountryTimeZones = countryTimeZones;
-            }
-            return countryTimeZones;
-        } catch (XmlPullParserException | IOException e) {
-            System.logW("Error reading country zones ", e);
-
-            // Error - don't change the cached value.
-            return null;
-        }
-    }
-
-    /**
-     * Processes the XML, applying the {@link TimeZonesProcessor} to the &lt;countryzones&gt;
-     * element. Processing can terminate early if the
-     * {@link TimeZonesProcessor#processCountryZones(String, String, boolean, List, String)} returns
-     * {@link TimeZonesProcessor#HALT} or it throws an exception.
-     */
-    private void processXml(TimeZonesProcessor processor)
-            throws XmlPullParserException, IOException {
-        try (Reader reader = xmlSource.get()) {
-            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
-            xmlPullParserFactory.setNamespaceAware(false);
-
-            XmlPullParser parser = xmlPullParserFactory.newPullParser();
-            parser.setInput(reader);
-
-            /*
-             * The expected XML structure is:
-             * <timezones ianaversion="2017b">
-             *   <countryzones>
-             *     <country code="us" default="America/New_York">
-             *       <id>America/New_York"</id>
-             *       ...
-             *       <id picker="n">America/Indiana/Vincennes</id>
-             *       ...
-             *       <id>America/Los_Angeles</id>
-             *     </country>
-             *     <country code="gb" default="Europe/London">
-             *       <id>Europe/London</id>
-             *     </country>
-             *   </countryzones>
-             * </timezones>
-             */
-
-            findRequiredStartTag(parser, TIMEZONES_ELEMENT);
-
-            // We do not require the ianaversion attribute be present. It is metadata that helps
-            // with versioning but is not required.
-            String ianaVersion = parser.getAttributeValue(
-                    null /* namespace */, IANA_VERSION_ATTRIBUTE);
-            if (processor.processHeader(ianaVersion) == TimeZonesProcessor.HALT) {
-                return;
-            }
-
-            // There is only one expected sub-element <countryzones> in the format currently, skip
-            // over anything before it.
-            findRequiredStartTag(parser, COUNTRY_ZONES_ELEMENT);
-
-            if (processCountryZones(parser, processor) == TimeZonesProcessor.HALT) {
-                return;
-            }
-
-            // Make sure we are on the </countryzones> tag.
-            checkOnEndTag(parser, COUNTRY_ZONES_ELEMENT);
-
-            // Advance to the next tag.
-            parser.next();
-
-            // Skip anything until </timezones>, and make sure the file is not truncated and we can
-            // find the end.
-            consumeUntilEndTag(parser, TIMEZONES_ELEMENT);
-
-            // Make sure we are on the </timezones> tag.
-            checkOnEndTag(parser, TIMEZONES_ELEMENT);
-        }
-    }
-
-    private static boolean processCountryZones(XmlPullParser parser,
-            TimeZonesProcessor processor) throws IOException, XmlPullParserException {
-
-        // Skip over any unexpected elements and process <country> elements.
-        while (findOptionalStartTag(parser, COUNTRY_ELEMENT)) {
-            if (processor == null) {
-                consumeUntilEndTag(parser, COUNTRY_ELEMENT);
-            } else {
-                String code = parser.getAttributeValue(
-                        null /* namespace */, COUNTRY_CODE_ATTRIBUTE);
-                if (code == null || code.isEmpty()) {
-                    throw new XmlPullParserException(
-                            "Unable to find country code: " + parser.getPositionDescription());
-                }
-                String defaultTimeZoneId = parser.getAttributeValue(
-                        null /* namespace */, DEFAULT_TIME_ZONE_ID_ATTRIBUTE);
-                if (defaultTimeZoneId == null || defaultTimeZoneId.isEmpty()) {
-                    throw new XmlPullParserException("Unable to find default time zone ID: "
-                            + parser.getPositionDescription());
-                }
-                Boolean everUsesUtc = parseBooleanAttribute(
-                        parser, EVER_USES_UTC_ATTRIBUTE, null /* defaultValue */);
-                if (everUsesUtc == null) {
-                    // There is no valid default: we require this to be specified.
-                    throw new XmlPullParserException(
-                            "Unable to find UTC hint attribute (" + EVER_USES_UTC_ATTRIBUTE + "): "
-                            + parser.getPositionDescription());
-                }
-
-                String debugInfo = parser.getPositionDescription();
-                List<TimeZoneMapping> timeZoneMappings = parseTimeZoneMappings(parser);
-                boolean result = processor.processCountryZones(code, defaultTimeZoneId, everUsesUtc,
-                        timeZoneMappings, debugInfo);
-                if (result == TimeZonesProcessor.HALT) {
-                    return TimeZonesProcessor.HALT;
-                }
-            }
-
-            // Make sure we are on the </country> element.
-            checkOnEndTag(parser, COUNTRY_ELEMENT);
-        }
-
-        return TimeZonesProcessor.CONTINUE;
-    }
-
-    private static List<TimeZoneMapping> parseTimeZoneMappings(XmlPullParser parser)
-            throws IOException, XmlPullParserException {
-        List<TimeZoneMapping> timeZoneMappings = new ArrayList<>();
-
-        // Skip over any unexpected elements and process <id> elements.
-        while (findOptionalStartTag(parser, ZONE_ID_ELEMENT)) {
-            // The picker attribute is optional and defaulted to true.
-            boolean showInPicker = parseBooleanAttribute(
-                    parser, ZONE_SHOW_IN_PICKER_ATTRIBUTE, true /* defaultValue */);
-            Long notUsedAfter = parseLongAttribute(
-                    parser, ZONE_NOT_USED_AFTER_ATTRIBUTE, null /* defaultValue */);
-            String zoneIdString = consumeText(parser);
-
-            // Make sure we are on the </id> element.
-            checkOnEndTag(parser, ZONE_ID_ELEMENT);
-
-            // Process the TimeZoneMapping.
-            if (zoneIdString == null || zoneIdString.length() == 0) {
-                throw new XmlPullParserException("Missing text for " + ZONE_ID_ELEMENT + "): "
-                        + parser.getPositionDescription());
-            }
-
-            TimeZoneMapping timeZoneMapping =
-                    new TimeZoneMapping(zoneIdString, showInPicker, notUsedAfter);
-            timeZoneMappings.add(timeZoneMapping);
-        }
-
-        // The list is made unmodifiable to avoid callers changing it.
-        return Collections.unmodifiableList(timeZoneMappings);
-    }
-
-    /**
-     * Parses an attribute value, which must be either {@code null} or a valid signed long value.
-     * If the attribute value is {@code null} then {@code defaultValue} is returned. If the
-     * attribute is present but not a valid long value then an XmlPullParserException is thrown.
-     */
-    private static Long parseLongAttribute(XmlPullParser parser, String attributeName,
-            Long defaultValue) throws XmlPullParserException {
-        String attributeValueString = parser.getAttributeValue(null /* namespace */, attributeName);
-        if (attributeValueString == null) {
-            return defaultValue;
-        }
-        try {
-            return Long.parseLong(attributeValueString);
-        } catch (NumberFormatException e) {
-            throw new XmlPullParserException("Attribute \"" + attributeName
-                    + "\" is not a long value: " + parser.getPositionDescription());
-        }
-    }
-
-    /**
-     * Parses an attribute value, which must be either {@code null}, {@code "y"} or {@code "n"}.
-     * If the attribute value is {@code null} then {@code defaultValue} is returned. If the
-     * attribute is present but not "y" or "n" then an XmlPullParserException is thrown.
-     */
-    private static Boolean parseBooleanAttribute(XmlPullParser parser,
-            String attributeName, Boolean defaultValue) throws XmlPullParserException {
-        String attributeValueString = parser.getAttributeValue(null /* namespace */, attributeName);
-        if (attributeValueString == null) {
-            return defaultValue;
-        }
-        boolean isTrue = TRUE_ATTRIBUTE_VALUE.equals(attributeValueString);
-        if (!(isTrue || FALSE_ATTRIBUTE_VALUE.equals(attributeValueString))) {
-            throw new XmlPullParserException("Attribute \"" + attributeName
-                    + "\" is not \"y\" or \"n\": " + parser.getPositionDescription());
-        }
-        return isTrue;
-    }
-
-    private static void findRequiredStartTag(XmlPullParser parser, String elementName)
-            throws IOException, XmlPullParserException {
-        findStartTag(parser, elementName, true /* elementRequired */);
-    }
-
-    /** Called when on a START_TAG. When returning false, it leaves the parser on the END_TAG. */
-    private static boolean findOptionalStartTag(XmlPullParser parser, String elementName)
-            throws IOException, XmlPullParserException {
-        return findStartTag(parser, elementName, false /* elementRequired */);
-    }
-
-    /**
-     * Find a START_TAG with the specified name without decreasing the depth, or increasing the
-     * depth by more than one. More deeply nested elements and text are skipped, even START_TAGs
-     * with matching names. Returns when the START_TAG is found or the next (non-nested) END_TAG is
-     * encountered. The return can take the form of an exception or a false if the START_TAG is not
-     * found. True is returned when it is.
-     */
-    private static boolean findStartTag(
-            XmlPullParser parser, String elementName, boolean elementRequired)
-            throws IOException, XmlPullParserException {
-
-        int type;
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
-            switch (type) {
-                case XmlPullParser.START_TAG:
-                    String currentElementName = parser.getName();
-                    if (elementName.equals(currentElementName)) {
-                        return true;
-                    }
-
-                    // It was not the START_TAG we were looking for. Consume until the end.
-                    parser.next();
-                    consumeUntilEndTag(parser, currentElementName);
-                    break;
-                case XmlPullParser.END_TAG:
-                    if (elementRequired) {
-                        throw new XmlPullParserException(
-                                "No child element found with name " + elementName);
-                    }
-                    return false;
-                default:
-                    // Ignore.
-                    break;
-            }
-        }
-        throw new XmlPullParserException("Unexpected end of document while looking for "
-                + elementName);
-    }
-
-    /**
-     * Consume the remaining contents of an element and move to the END_TAG. Used when processing
-     * within an element can stop. The parser must be pointing at either the END_TAG we are looking
-     * for, a TEXT, or a START_TAG nested within the element to be consumed.
-     */
-    private static void consumeUntilEndTag(XmlPullParser parser, String elementName)
-            throws IOException, XmlPullParserException {
-
-        if (parser.getEventType() == XmlPullParser.END_TAG
-                && elementName.equals(parser.getName())) {
-            // Early return - we are already there.
-            return;
-        }
-
-        // Keep track of the required depth in case there are nested elements to be consumed.
-        // Both the name and the depth must match our expectation to complete.
-
-        int requiredDepth = parser.getDepth();
-        // A TEXT tag would be at the same depth as the END_TAG we are looking for.
-        if (parser.getEventType() == XmlPullParser.START_TAG) {
-            // A START_TAG would have incremented the depth, so we're looking for an END_TAG one
-            // higher than the current tag.
-            requiredDepth--;
-        }
-
-        while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
-            int type = parser.next();
-
-            int currentDepth = parser.getDepth();
-            if (currentDepth < requiredDepth) {
-                throw new XmlPullParserException(
-                        "Unexpected depth while looking for end tag: "
-                                + parser.getPositionDescription());
-            } else if (currentDepth == requiredDepth) {
-                if (type == XmlPullParser.END_TAG) {
-                    if (elementName.equals(parser.getName())) {
-                        return;
-                    }
-                    throw new XmlPullParserException(
-                            "Unexpected eng tag: " + parser.getPositionDescription());
-                }
-            }
-            // Everything else is either a type we are not interested in or is too deep and so is
-            // ignored.
-        }
-        throw new XmlPullParserException("Unexpected end of document");
-    }
-
-    /**
-     * Reads the text inside the current element. Should be called when the parser is currently
-     * on the START_TAG before the TEXT. The parser will be positioned on the END_TAG after this
-     * call when it completes successfully.
-     */
-    private static String consumeText(XmlPullParser parser)
-            throws IOException, XmlPullParserException {
-
-        int type = parser.next();
-        String text;
-        if (type == XmlPullParser.TEXT) {
-            text = parser.getText();
-        } else {
-            throw new XmlPullParserException("Text not found. Found type=" + type
-                    + " at " + parser.getPositionDescription());
-        }
-
-        type = parser.next();
-        if (type != XmlPullParser.END_TAG) {
-            throw new XmlPullParserException(
-                    "Unexpected nested tag or end of document when expecting text: type=" + type
-                            + " at " + parser.getPositionDescription());
-        }
-        return text;
-    }
-
-    private static void checkOnEndTag(XmlPullParser parser, String elementName)
-            throws XmlPullParserException {
-        if (!(parser.getEventType() == XmlPullParser.END_TAG
-                && parser.getName().equals(elementName))) {
-            throw new XmlPullParserException(
-                    "Unexpected tag encountered: " + parser.getPositionDescription());
-        }
-    }
-
-    /**
-     * Processes &lt;timezones&gt; data.
-     */
-    private interface TimeZonesProcessor {
-
-        boolean CONTINUE = true;
-        boolean HALT = false;
-
-        /**
-         * Return {@link #CONTINUE} if processing of the XML should continue, {@link #HALT} if it
-         * should stop (but without considering this an error). Problems with the data are
-         * reported as an exception.
-         *
-         * <p>The default implementation returns {@link #CONTINUE}.
-         */
-        default boolean processHeader(String ianaVersion) throws XmlPullParserException {
-            return CONTINUE;
-        }
-
-        /**
-         * Returns {@link #CONTINUE} if processing of the XML should continue, {@link #HALT} if it
-         * should stop (but without considering this an error). Problems with the data are
-         * reported as an exception.
-         *
-         * <p>The default implementation returns {@link #CONTINUE}.
-         */
-        default boolean processCountryZones(String countryIso, String defaultTimeZoneId,
-                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
-                throws XmlPullParserException {
-            return CONTINUE;
-        }
-    }
-
-    /**
-     * Validates &lt;countryzones&gt; elements. Intended to be used before a proposed installation
-     * of new data. To be valid the country ISO code must be normalized, unique, the default time
-     * zone ID must be one of the time zones IDs and the time zone IDs list must not be empty. The
-     * IDs themselves are not checked against other data to see if they are recognized because other
-     * classes will not have been updated with the associated new time zone data yet and so will not
-     * be aware of newly added IDs.
-     */
-    private static class TimeZonesValidator implements TimeZonesProcessor {
-
-        private final Set<String> knownCountryCodes = new HashSet<>();
-
-        @Override
-        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
-                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
-                throws XmlPullParserException {
-            if (!normalizeCountryIso(countryIso).equals(countryIso)) {
-                throw new XmlPullParserException("Country code: " + countryIso
-                        + " is not normalized at " + debugInfo);
-            }
-            if (knownCountryCodes.contains(countryIso)) {
-                throw new XmlPullParserException("Second entry for country code: " + countryIso
-                        + " at " + debugInfo);
-            }
-            if (timeZoneMappings.isEmpty()) {
-                throw new XmlPullParserException("No time zone IDs for country code: " + countryIso
-                        + " at " + debugInfo);
-            }
-            if (!TimeZoneMapping.containsTimeZoneId(timeZoneMappings, defaultTimeZoneId)) {
-                throw new XmlPullParserException("defaultTimeZoneId for country code: "
-                        + countryIso + " is not one of the zones " + timeZoneMappings + " at "
-                        + debugInfo);
-            }
-            knownCountryCodes.add(countryIso);
-
-            return CONTINUE;
-        }
-    }
-
-    /**
-     * Reads just the IANA version from the file header. The version is then available via
-     * {@link #getIanaVersion()}.
-     */
-    private static class IanaVersionExtractor implements TimeZonesProcessor {
-
-        private String ianaVersion;
-
-        @Override
-        public boolean processHeader(String ianaVersion) throws XmlPullParserException {
-            this.ianaVersion = ianaVersion;
-            return HALT;
-        }
-
-        public String getIanaVersion() {
-            return ianaVersion;
-        }
-    }
-
-    /**
-     * Reads all country time zone information into memory and makes it available as a
-     * {@link CountryZonesFinder}.
-     */
-    private static class CountryZonesLookupExtractor implements TimeZonesProcessor {
-        private List<CountryTimeZones> countryTimeZonesList = new ArrayList<>(250 /* default */);
-
-        @Override
-        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
-                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo)
-                throws XmlPullParserException {
-
-            CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                    countryIso, defaultTimeZoneId, everUsesUtc, timeZoneMappings, debugInfo);
-            countryTimeZonesList.add(countryTimeZones);
-            return CONTINUE;
-        }
-
-        CountryZonesFinder getCountryZonesLookup() {
-            return new CountryZonesFinder(countryTimeZonesList);
-        }
-    }
-
-    /**
-     * Extracts <em>validated</em> time zones information associated with a specific country code.
-     * Processing is halted when the country code is matched and the validated result is also made
-     * available via {@link #getValidatedCountryTimeZones()}.
-     */
-    private static class SelectiveCountryTimeZonesExtractor implements TimeZonesProcessor {
-
-        private final String countryCodeToMatch;
-        private CountryTimeZones validatedCountryTimeZones;
-
-        private SelectiveCountryTimeZonesExtractor(String countryCodeToMatch) {
-            this.countryCodeToMatch = normalizeCountryIso(countryCodeToMatch);
-        }
-
-        @Override
-        public boolean processCountryZones(String countryIso, String defaultTimeZoneId,
-                boolean everUsesUtc, List<TimeZoneMapping> timeZoneMappings, String debugInfo) {
-            countryIso = normalizeCountryIso(countryIso);
-            if (!countryCodeToMatch.equals(countryIso)) {
-                return CONTINUE;
-            }
-            validatedCountryTimeZones = CountryTimeZones.createValidated(countryIso,
-                    defaultTimeZoneId, everUsesUtc, timeZoneMappings, debugInfo);
-
-            return HALT;
-        }
-
-        /**
-         * Returns the CountryTimeZones that matched, or {@code null} if there were no matches.
-         */
-        CountryTimeZones getValidatedCountryTimeZones() {
-            return validatedCountryTimeZones;
-        }
-    }
-
-    /**
-     * A source of Readers that can be used repeatedly.
-     */
-    private interface ReaderSupplier {
-        /** Returns a Reader. Throws an IOException if the Reader cannot be created. */
-        Reader get() throws IOException;
-
-        static ReaderSupplier forFile(String fileName, Charset charSet) throws IOException {
-            Path file = Paths.get(fileName);
-            if (!Files.exists(file)) {
-                throw new FileNotFoundException(fileName + " does not exist");
-            }
-            if (!Files.isRegularFile(file) && Files.isReadable(file)) {
-                throw new IOException(fileName + " must be a regular readable file.");
-            }
-            return () -> Files.newBufferedReader(file, charSet);
-        }
-
-        static ReaderSupplier forString(String xml) {
-            return () -> new StringReader(xml);
-        }
-    }
-
-    private static List<String> extractTimeZoneIds(List<TimeZoneMapping> timeZoneMappings) {
-        List<String> zoneIds = new ArrayList<>(timeZoneMappings.size());
-        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-            zoneIds.add(timeZoneMapping.timeZoneId);
-        }
-        return Collections.unmodifiableList(zoneIds);
-    }
-
-    static String normalizeCountryIso(String countryIso) {
-        // Lowercase ASCII is normalized for the purposes of the input files and the code in this
-        // class and related classes.
-        return countryIso.toLowerCase(Locale.US);
-    }
-}
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..3fafb39
--- /dev/null
+++ b/luni/src/main/java/libcore/util/XmlObjectFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public class XmlObjectFactory {
+
+    private XmlObjectFactory() {}
+
+    /**
+     * Returns a new instance of the platform default {@link XmlSerializer} more efficiently than
+     * using {@code XmlPullParserFactory.newInstance().newSerializer()}.
+     */
+    @libcore.api.CorePlatformApi
+    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()}.
+     */
+    @libcore.api.CorePlatformApi
+    public static XmlPullParser newXmlPullParser() {
+        return new KXmlParser();
+    }
+
+    /**
+     * Returns the plaform default {@link XMLReader}.
+     */
+    @libcore.api.CorePlatformApi
+    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..abd98b1 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -22,6 +22,7 @@
  */
 package libcore.util;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.util.Arrays;
@@ -30,13 +31,15 @@
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 import libcore.io.BufferIterator;
+import libcore.timezone.ZoneInfoDB;
 
 /**
  * Our concrete TimeZone implementation, backed by zoneinfo data.
  *
  * <p>This reads time zone information from a binary file stored on the platform. The binary file
- * is essentially a single file containing compacted versions of all the tzfile (see
- * {@code man 5 tzfile} for details of the source) and an index by long name, e.g. Europe/London.
+ * is essentially a single file containing compacted versions of all the tzfiles produced by the
+ * zone info compiler (zic) tool (see {@code man 5 tzfile} for details of the format and
+ * {@code man 8 zic}) and an index by long name, e.g. Europe/London.
  *
  * <p>The compacted form is created by {@code external/icu/tools/ZoneCompactor.java} and is used
  * by both this and Bionic. {@link ZoneInfoDB} is responsible for mapping the binary file, and
@@ -60,8 +63,12 @@
  * dates before 1900 and after 2038. There is an extended version of the table that uses 64 bits
  * to store the data but that information is not used by this.
  *
+ * <p>This class should be in libcore.timezone but this class is Serializable so cannot
+ * be moved there without breaking apps that have (for some reason) serialized TimeZone objects.
+ *
  * @hide - used to implement TimeZone
  */
+@libcore.api.CorePlatformApi
 public final class ZoneInfo extends TimeZone {
     private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
     private static final long MILLISECONDS_PER_400_YEARS =
@@ -80,7 +87,16 @@
     // Proclaim serialization compatibility with pre-OpenJDK AOSP
     static final long serialVersionUID = -4598738130123921552L;
 
+    /**
+     * The (best guess) non-DST offset used "today". It is stored in milliseconds.
+     * See also {@link #mOffsets} which holds values relative to this value, albeit in seconds.
+     */
     private int mRawOffset;
+
+    /**
+     * The earliest non-DST offset for the zone. It is stored in milliseconds and is absolute, i.e.
+     * it is not relative to mRawOffset.
+     */
     private final int mEarliestRawOffset;
 
     /**
@@ -131,6 +147,7 @@
      *
      * @see #mTypes
      */
+    @UnsupportedAppUsage
     private final long[] mTransitions;
 
     /**
@@ -276,36 +293,39 @@
         setID(name);
 
         // Find the latest daylight and standard offsets (if any).
-        int lastStd = -1;
-        int lastDst = -1;
-        for (int i = mTransitions.length - 1; (lastStd == -1 || lastDst == -1) && i >= 0; --i) {
-            int type = mTypes[i] & 0xff;
-            if (lastStd == -1 && mIsDsts[type] == 0) {
-                lastStd = i;
+        int lastStdTransitionIndex = -1;
+        int lastDstTransitionIndex = -1;
+        for (int i = mTransitions.length - 1;
+                (lastStdTransitionIndex == -1 || lastDstTransitionIndex == -1) && i >= 0; --i) {
+            int typeIndex = mTypes[i] & 0xff;
+            if (lastStdTransitionIndex == -1 && mIsDsts[typeIndex] == 0) {
+                lastStdTransitionIndex = i;
             }
-            if (lastDst == -1 && mIsDsts[type] != 0) {
-                lastDst = i;
+            if (lastDstTransitionIndex == -1 && mIsDsts[typeIndex] != 0) {
+                lastDstTransitionIndex = i;
             }
         }
 
         // 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 {
-            if (lastStd == -1) {
+            if (lastStdTransitionIndex == -1) {
                 throw new IllegalStateException( "ZoneInfo requires at least one non-DST "
                         + "transition to be provided for each timezone that has at least one "
                         + "transition but could not find one for '" + name + "'");
             }
-            mRawOffset = gmtOffsets[mTypes[lastStd] & 0xff];
+            mRawOffset = gmtOffsets[mTypes[lastStdTransitionIndex] & 0xff];
         }
 
-        if (lastDst != -1) {
+        if (lastDstTransitionIndex != -1) {
             // Check to see if the last DST transition is in the future or the past. If it is in
             // the past then we treat it as if it doesn't exist, at least for the purposes of
             // setting mDstSavings and mUseDst.
-            long lastDSTTransitionTime = mTransitions[lastDst];
+            long lastDSTTransitionTime = mTransitions[lastDstTransitionIndex];
 
             // Convert the current time in millis into seconds. Unlike other places that convert
             // time in milliseconds into seconds in order to compare with transition time this
@@ -321,11 +341,11 @@
             // useDaylightTime at the start of 2009 but "false" at the end. This seems appropriate.
             if (lastDSTTransitionTime < currentUnixTimeSeconds) {
                 // The last DST transition is before now so treat it as if it doesn't exist.
-                lastDst = -1;
+                lastDstTransitionIndex = -1;
             }
         }
 
-        if (lastDst == -1) {
+        if (lastDstTransitionIndex == -1) {
             // There were no DST transitions or at least no future DST transitions so DST is not
             // used.
             mDstSavings = 0;
@@ -333,22 +353,31 @@
         } else {
             // Use the latest transition's pair of offsets to compute the DST savings.
             // This isn't generally useful, but it's exposed by TimeZone.getDSTSavings.
-            int lastGmtOffset = gmtOffsets[mTypes[lastStd] & 0xff];
-            int lastDstOffset = gmtOffsets[mTypes[lastDst] & 0xff];
+            int lastGmtOffset = gmtOffsets[mTypes[lastStdTransitionIndex] & 0xff];
+            int lastDstOffset = gmtOffsets[mTypes[lastDstTransitionIndex] & 0xff];
             mDstSavings = (lastDstOffset - lastGmtOffset) * 1000;
             mUseDst = true;
         }
 
-        // Cache the oldest known raw offset, in case we're asked about times that predate our
-        // transition data.
-        int firstStd = -1;
-        for (int i = 0; i < mTransitions.length; ++i) {
-            if (mIsDsts[mTypes[i] & 0xff] == 0) {
-                firstStd = i;
+        // From the tzfile docs (Jan 2019):
+        // The localtime(3) function uses the first standard-time ttinfo structure
+        // in the file (or simply the first ttinfo structure in the absence of a
+        // standard-time structure) if either tzh_timecnt is zero or the time
+        // argument is less than the first transition time recorded in the file.
+        //
+        // Cache the raw offset associated with the first nonDst type, in case we're asked about
+        // times that predate our transition data. Android falls back to mRawOffset if there are
+        // only DST ttinfo structures (assumed rare).
+        int firstStdTypeIndex = -1;
+        for (int i = 0; i < mIsDsts.length; ++i) {
+            if (mIsDsts[i] == 0) {
+                firstStdTypeIndex = i;
                 break;
             }
         }
-        int earliestRawOffset = (firstStd != -1) ? gmtOffsets[mTypes[firstStd] & 0xff] : mRawOffset;
+
+        int earliestRawOffset = (firstStdTypeIndex != -1)
+                ? gmtOffsets[firstStdTypeIndex] : mRawOffset;
 
         // Rather than keep offsets from UTC, we use offsets from local time, so the raw offset
         // can be changed and automatically affect all the offsets.
@@ -696,7 +725,10 @@
      *
      * <p>All offsets are considered to be safe for addition / subtraction / multiplication without
      * worrying about overflow. All absolute time arithmetic is checked for overflow / underflow.
+     *
+     * @hide
      */
+    @libcore.api.CorePlatformApi
     public static class WallTime {
 
         // We use a GregorianCalendar (set to UTC) to handle all the date/time normalization logic
@@ -716,6 +748,7 @@
         private int isDst;
         private int gmtOffsetSeconds;
 
+        @libcore.api.CorePlatformApi
         public WallTime() {
             this.calendar = new GregorianCalendar(0, 0, 0, 0, 0, 0);
             calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -728,6 +761,7 @@
          * <p>When going from an instant to a wall time it is always unambiguous because there
          * is only one offset rule acting at any given instant. We do not consider leap seconds.
          */
+        @libcore.api.CorePlatformApi
         public void localtime(int timeSeconds, ZoneInfo zoneInfo) {
             try {
                 int offsetSeconds = zoneInfo.mRawOffset / 1000;
@@ -741,8 +775,9 @@
                     int offsetIndex = zoneInfo.findOffsetIndexForTimeInSeconds(timeSeconds);
                     if (offsetIndex == -1) {
                         // -1 means timeSeconds is "before the first recorded transition". The first
-                        // recorded transition is treated as a transition from non-DST and the raw
-                        // offset.
+                        // recorded transition is treated as a transition from non-DST and the
+                        // earliest known raw offset.
+                        offsetSeconds = zoneInfo.mEarliestRawOffset / 1000;
                         isDst = 0;
                     } else {
                         offsetSeconds += zoneInfo.mOffsets[offsetIndex];
@@ -751,7 +786,7 @@
                 }
 
                 // Perform arithmetic that might underflow before setting fields.
-                int wallTimeSeconds = checkedAdd(timeSeconds, offsetSeconds);
+                int wallTimeSeconds = checked32BitAdd(timeSeconds, offsetSeconds);
 
                 // Set fields.
                 calendar.setTimeInMillis(wallTimeSeconds * 1000L);
@@ -787,6 +822,7 @@
          * <p>We do not assume that adjacent transitions modify the DST state; adjustments can
          * occur for other reasons such as when a zone changes its raw offset.
          */
+        @libcore.api.CorePlatformApi
         public int mktime(ZoneInfo zoneInfo) {
             // Normalize isDst to -1, 0 or 1 to simplify isDst equality checks below.
             this.isDst = this.isDst > 0 ? this.isDst = 1 : this.isDst < 0 ? this.isDst = -1 : 0;
@@ -803,7 +839,7 @@
             try {
                 final int wallTimeSeconds =  (int) longWallTimeSeconds;
                 final int rawOffsetSeconds = zoneInfo.mRawOffset / 1000;
-                final int rawTimeSeconds = checkedSubtract(wallTimeSeconds, rawOffsetSeconds);
+                final int rawTimeSeconds = checked32BitSubtract(wallTimeSeconds, rawOffsetSeconds);
 
                 if (zoneInfo.mTransitions.length == 0) {
                     // There is no transition information. There is just a raw offset for all time.
@@ -888,10 +924,11 @@
                 int jOffsetSeconds = rawOffsetSeconds + offsetsToTry[j];
                 int targetIntervalOffsetSeconds = targetInterval.getTotalOffsetSeconds();
                 int adjustmentSeconds = targetIntervalOffsetSeconds - jOffsetSeconds;
-                int adjustedWallTimeSeconds = checkedAdd(oldWallTimeSeconds, adjustmentSeconds);
+                int adjustedWallTimeSeconds =
+                        checked32BitAdd(oldWallTimeSeconds, adjustmentSeconds);
                 if (targetInterval.containsWallTime(adjustedWallTimeSeconds)) {
                     // Perform any arithmetic that might overflow.
-                    int returnValue = checkedSubtract(adjustedWallTimeSeconds,
+                    int returnValue = checked32BitSubtract(adjustedWallTimeSeconds,
                             targetIntervalOffsetSeconds);
 
                     // Modify field state and return the result.
@@ -1025,8 +1062,8 @@
                             // the result might be a DST or a non-DST answer for wall times that can
                             // exist in two OffsetIntervals.
                             int totalOffsetSeconds = offsetInterval.getTotalOffsetSeconds();
-                            int returnValue = checkedSubtract(wallTimeSeconds,
-                                    totalOffsetSeconds);
+                            int returnValue =
+                                    checked32BitSubtract(wallTimeSeconds, totalOffsetSeconds);
 
                             copyFieldsFromCalendar();
                             this.isDst = offsetInterval.getIsDst();
@@ -1077,82 +1114,102 @@
             return null;
         }
 
+        @libcore.api.CorePlatformApi
         public void setYear(int year) {
             this.year = year;
         }
 
+        @libcore.api.CorePlatformApi
         public void setMonth(int month) {
             this.month = month;
         }
 
+        @libcore.api.CorePlatformApi
         public void setMonthDay(int monthDay) {
             this.monthDay = monthDay;
         }
 
+        @libcore.api.CorePlatformApi
         public void setHour(int hour) {
             this.hour = hour;
         }
 
+        @libcore.api.CorePlatformApi
         public void setMinute(int minute) {
             this.minute = minute;
         }
 
+        @libcore.api.CorePlatformApi
         public void setSecond(int second) {
             this.second = second;
         }
 
+        @libcore.api.CorePlatformApi
         public void setWeekDay(int weekDay) {
             this.weekDay = weekDay;
         }
 
+        @libcore.api.CorePlatformApi
         public void setYearDay(int yearDay) {
             this.yearDay = yearDay;
         }
 
+        @libcore.api.CorePlatformApi
         public void setIsDst(int isDst) {
             this.isDst = isDst;
         }
 
+        @libcore.api.CorePlatformApi
         public void setGmtOffset(int gmtoff) {
             this.gmtOffsetSeconds = gmtoff;
         }
 
+        @libcore.api.CorePlatformApi
         public int getYear() {
             return year;
         }
 
+        @libcore.api.CorePlatformApi
         public int getMonth() {
             return month;
         }
 
+        @libcore.api.CorePlatformApi
         public int getMonthDay() {
             return monthDay;
         }
 
+        @libcore.api.CorePlatformApi
         public int getHour() {
             return hour;
         }
 
+        @libcore.api.CorePlatformApi
         public int getMinute() {
             return minute;
         }
 
+        @libcore.api.CorePlatformApi
         public int getSecond() {
             return second;
         }
 
+        @libcore.api.CorePlatformApi
         public int getWeekDay() {
             return weekDay;
         }
 
+        @libcore.api.CorePlatformApi
         public int getYearDay() {
             return yearDay;
         }
 
+        @libcore.api.CorePlatformApi
         public int getGmtOffset() {
             return gmtOffsetSeconds;
         }
 
+        @libcore.api.CorePlatformApi
         public int getIsDst() {
             return isDst;
         }
@@ -1193,16 +1250,19 @@
      * Crucially this means that there was a "gap" after PST when PDT started, and an overlap when
      * PDT ended and PST began.
      *
-     * <p>For convenience all wall-time values are represented as the number of seconds since the
-     * beginning of the Unix epoch <em>in UTC</em>. To convert from a wall-time to the actual time
-     * in the offset it is necessary to <em>subtract</em> the {@code totalOffsetSeconds}.
+     * <p>Although wall-time means "local time", for convenience all wall-time values are stored in
+     * the number of seconds since the beginning of the Unix epoch to get that time <em>in UTC</em>.
+     * To convert from a wall-time to the actual UTC time it is necessary to <em>subtract</em> the
+     * {@code totalOffsetSeconds}.
      * For example: If the offset in PST is -07:00 hours, then:
      * timeInPstSeconds = wallTimeUtcSeconds - offsetSeconds
      * i.e. 13:00 UTC - (-07:00) = 20:00 UTC = 13:00 PST
      */
     static class OffsetInterval {
 
+        /** The time the interval starts in seconds since start of epoch, inclusive. */
         private final int startWallTimeSeconds;
+        /** The time the interval ends in seconds since start of epoch, exclusive. */
         private final int endWallTimeSeconds;
         private final int isDst;
         private final int totalOffsetSeconds;
@@ -1210,40 +1270,60 @@
         /**
          * Creates an {@link OffsetInterval}.
          *
-         * <p>If {@code transitionIndex} is -1, the transition is synthesized to be a non-DST offset
-         * that runs from the beginning of time until the first transition in {@code timeZone} and
-         * has an offset of {@code timezone.mRawOffset}. If {@code transitionIndex} is the last
-         * transition that transition is considered to run until the end of representable time.
+         * <p>If {@code transitionIndex} is -1, where possible the transition is synthesized to run
+         * from the beginning of 32-bit time until the first transition in {@code timeZone} with
+         * offset information based on the first type defined. If {@code transitionIndex} is the
+         * last transition, that transition is considered to run until the end of 32-bit time.
          * Otherwise, the information is extracted from {@code timeZone.mTransitions},
-         * {@code timeZone.mOffsets} an {@code timeZone.mIsDsts}.
+         * {@code timeZone.mOffsets} and {@code timeZone.mIsDsts}.
+         *
+         * <p>This method can return null when:
+         * <ol>
+         * <li>the {@code transitionIndex} is outside the allowed range, i.e.
+         *   {@code transitionIndex < -1 || transitionIndex >= [the number of transitions]}.</li>
+         * <li>when calculations result in a zero-length interval. This is only expected to occur
+         *   when dealing with transitions close to (or exactly at) {@code Integer.MIN_VALUE} and
+         *   {@code Integer.MAX_VALUE} and where it's difficult to convert from UTC to local times.
+         *   </li>
+         * </ol>
          */
-        public static OffsetInterval create(ZoneInfo timeZone, int transitionIndex)
-                throws CheckedArithmeticException {
-
+        public static OffsetInterval create(ZoneInfo timeZone, int transitionIndex) {
             if (transitionIndex < -1 || transitionIndex >= timeZone.mTransitions.length) {
                 return null;
             }
 
-            int rawOffsetSeconds = timeZone.mRawOffset / 1000;
             if (transitionIndex == -1) {
-                int endWallTimeSeconds = checkedAdd(timeZone.mTransitions[0], rawOffsetSeconds);
-                return new OffsetInterval(Integer.MIN_VALUE, endWallTimeSeconds, 0 /* isDst */,
-                        rawOffsetSeconds);
+                int totalOffsetSeconds = timeZone.mEarliestRawOffset / 1000;
+                int isDst = 0;
+
+                int startWallTimeSeconds = Integer.MIN_VALUE;
+                int endWallTimeSeconds =
+                        saturated32BitAdd(timeZone.mTransitions[0], totalOffsetSeconds);
+                if (startWallTimeSeconds == endWallTimeSeconds) {
+                    // There's no point in returning an OffsetInterval that lasts 0 seconds.
+                    return null;
+                }
+                return new OffsetInterval(startWallTimeSeconds, endWallTimeSeconds, isDst,
+                        totalOffsetSeconds);
             }
 
+            int rawOffsetSeconds = timeZone.mRawOffset / 1000;
             int type = timeZone.mTypes[transitionIndex] & 0xff;
             int totalOffsetSeconds = timeZone.mOffsets[type] + rawOffsetSeconds;
             int endWallTimeSeconds;
             if (transitionIndex == timeZone.mTransitions.length - 1) {
-                // If this is the last transition, make up the end time.
                 endWallTimeSeconds = Integer.MAX_VALUE;
             } else {
-                endWallTimeSeconds = checkedAdd(timeZone.mTransitions[transitionIndex + 1],
-                        totalOffsetSeconds);
+                endWallTimeSeconds = saturated32BitAdd(
+                        timeZone.mTransitions[transitionIndex + 1], totalOffsetSeconds);
             }
             int isDst = timeZone.mIsDsts[type];
             int startWallTimeSeconds =
-                    checkedAdd(timeZone.mTransitions[transitionIndex], totalOffsetSeconds);
+                    saturated32BitAdd(timeZone.mTransitions[transitionIndex], totalOffsetSeconds);
+            if (startWallTimeSeconds == endWallTimeSeconds) {
+                // There's no point in returning an OffsetInterval that lasts 0 seconds.
+                return null;
+            }
             return new OffsetInterval(
                     startWallTimeSeconds, endWallTimeSeconds, isDst, totalOffsetSeconds);
         }
@@ -1284,11 +1364,11 @@
     }
 
     /**
-     * Calculate (a + b).
+     * Calculate (a + b). The result must be in the Integer range otherwise an exception is thrown.
      *
      * @throws CheckedArithmeticException if overflow or underflow occurs
      */
-    private static int checkedAdd(long a, int b) throws CheckedArithmeticException {
+    private static int checked32BitAdd(long a, int b) throws CheckedArithmeticException {
         // Adapted from Guava IntMath.checkedAdd();
         long result = a + b;
         if (result != (int) result) {
@@ -1298,16 +1378,30 @@
     }
 
     /**
-     * Calculate (a - b).
+     * Calculate (a - b). The result must be in the Integer range otherwise an exception is thrown.
      *
      * @throws CheckedArithmeticException if overflow or underflow occurs
      */
-    private static int checkedSubtract(int a, int b) throws CheckedArithmeticException {
+    private static int checked32BitSubtract(long a, int b) throws CheckedArithmeticException {
         // Adapted from Guava IntMath.checkedSubtract();
-        long result = (long) a - b;
+        long result = a - b;
         if (result != (int) result) {
             throw new CheckedArithmeticException();
         }
         return (int) result;
     }
+
+    /**
+     * Calculate (a + b). If the result would overflow or underflow outside of the Integer range
+     * Integer.MAX_VALUE or Integer.MIN_VALUE will be returned, respectively.
+     */
+    private static int saturated32BitAdd(long a, int b) {
+        long result = a + b;
+        if (result > Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        } else if (result < Integer.MIN_VALUE) {
+            return Integer.MIN_VALUE;
+        }
+        return (int) result;
+    }
 }
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
deleted file mode 100644
index 9e58070..0000000
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * 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 android.system.ErrnoException;
-import dalvik.annotation.optimization.ReachabilitySensitive;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import libcore.io.BufferIterator;
-import libcore.io.MemoryMappedFile;
-
-/**
- * A class used to initialize the time zone database. This implementation uses the
- * Olson tzdata as the source of time zone information. However, to conserve
- * disk space (inodes) and reduce I/O, all the data is concatenated into a single file,
- * with an index to indicate the starting position of each time zone record.
- *
- * @hide - used to implement TimeZone
- */
-public final class ZoneInfoDB {
-
-  // VisibleForTesting
-  public static final String TZDATA_FILE = "tzdata";
-
-  private static final TzData DATA =
-          TzData.loadTzDataWithFallback(TimeZoneDataFiles.getTimeZoneFilePaths(TZDATA_FILE));
-
-  public static class TzData implements AutoCloseable {
-
-    // The database reserves 40 bytes for each id.
-    private static final int SIZEOF_TZNAME = 40;
-
-    // The database uses 32-bit (4 byte) integers.
-    private static final int SIZEOF_TZINT = 4;
-
-    // Each index entry takes up this number of bytes.
-    public static final int SIZEOF_INDEX_ENTRY = SIZEOF_TZNAME + 3 * SIZEOF_TZINT;
-
-    /**
-     * {@code true} if {@link #close()} has been called meaning the instance cannot provide any
-     * data.
-     */
-    private boolean closed;
-
-    /**
-     * Rather than open, read, and close the big data file each time we look up a time zone,
-     * we map the big data file during startup, and then just use the MemoryMappedFile.
-     *
-     * At the moment, this "big" data file is about 500 KiB. At some point, that will be small
-     * enough that we could just keep the byte[] in memory, but using mmap(2) like this has the
-     * nice property that even if someone replaces the file under us (because multiple gservices
-     * updates have gone out, say), we still get a consistent (if outdated) view of the world.
-     */
-    // Android-added: @ReachabilitySensitive
-    @ReachabilitySensitive
-    private MemoryMappedFile mappedFile;
-
-    private String version;
-    private String zoneTab;
-
-    /**
-     * The 'ids' array contains time zone ids sorted alphabetically, for binary searching.
-     * The other two arrays are in the same order. 'byteOffsets' gives the byte offset
-     * of each time zone, and 'rawUtcOffsetsCache' gives the time zone's raw UTC offset.
-     */
-    private String[] ids;
-    private int[] byteOffsets;
-    private int[] rawUtcOffsetsCache; // Access this via getRawUtcOffsets instead.
-
-    /**
-     * ZoneInfo objects are worth caching because they are expensive to create.
-     * See http://b/8270865 for context.
-     */
-    private final static int CACHE_SIZE = 1;
-    private final BasicLruCache<String, ZoneInfo> cache =
-        new BasicLruCache<String, ZoneInfo>(CACHE_SIZE) {
-      @Override
-      protected ZoneInfo create(String id) {
-        try {
-          return makeTimeZoneUncached(id);
-        } catch (IOException e) {
-          throw new IllegalStateException("Unable to load timezone for ID=" + id, e);
-        }
-      }
-    };
-
-    /**
-     * Loads the data at the specified paths in order, returning the first valid one as a
-     * {@link TzData} object. If there is no valid one found a basic fallback instance is created
-     * containing just GMT.
-     */
-    public static TzData loadTzDataWithFallback(String... paths) {
-      for (String path : paths) {
-        TzData tzData = new TzData();
-        if (tzData.loadData(path)) {
-          return tzData;
-        }
-      }
-
-      // We didn't find any usable tzdata on disk, so let's just hard-code knowledge of "GMT".
-      // This is actually implemented in TimeZone itself, so if this is the only time zone
-      // we report, we won't be asked any more questions.
-      System.logE("Couldn't find any " + TZDATA_FILE + " file!");
-      return TzData.createFallback();
-    }
-
-    /**
-     * Loads the data at the specified path and returns the {@link TzData} object if it is valid,
-     * otherwise {@code null}.
-     */
-    public static TzData loadTzData(String path) {
-      TzData tzData = new TzData();
-      if (tzData.loadData(path)) {
-        return tzData;
-      }
-      return null;
-    }
-
-    private static TzData createFallback() {
-      TzData tzData = new TzData();
-      tzData.populateFallback();
-      return tzData;
-    }
-
-    private TzData() {
-    }
-
-    /**
-     * Visible for testing.
-     */
-    public BufferIterator getBufferIterator(String id) {
-      checkNotClosed();
-
-      // Work out where in the big data file this time zone is.
-      int index = Arrays.binarySearch(ids, id);
-      if (index < 0) {
-        return null;
-      }
-
-      int byteOffset = byteOffsets[index];
-      BufferIterator it = mappedFile.bigEndianIterator();
-      it.skip(byteOffset);
-      return it;
-    }
-
-    private void populateFallback() {
-      version = "missing";
-      zoneTab = "# Emergency fallback data.\n";
-      ids = new String[] { "GMT" };
-      byteOffsets = rawUtcOffsetsCache = new int[1];
-    }
-
-    /**
-     * Loads the data file at the specified path. If the data is valid {@code true} will be
-     * returned and the {@link TzData} instance can be used. If {@code false} is returned then the
-     * TzData instance is left in a closed state and must be discarded.
-     */
-    private boolean loadData(String path) {
-      try {
-        mappedFile = MemoryMappedFile.mmapRO(path);
-      } catch (ErrnoException errnoException) {
-        return false;
-      }
-      try {
-        readHeader();
-        return true;
-      } catch (Exception ex) {
-        close();
-
-        // Something's wrong with the file.
-        // Log the problem and return false so we try the next choice.
-        System.logE(TZDATA_FILE + " file \"" + path + "\" was present but invalid!", ex);
-        return false;
-      }
-    }
-
-    private void readHeader() throws IOException {
-      // byte[12] tzdata_version  -- "tzdata2012f\0"
-      // int index_offset
-      // int data_offset
-      // int zonetab_offset
-      BufferIterator it = mappedFile.bigEndianIterator();
-
-      try {
-        byte[] tzdata_version = new byte[12];
-        it.readByteArray(tzdata_version, 0, tzdata_version.length);
-        String magic = new String(tzdata_version, 0, 6, StandardCharsets.US_ASCII);
-        if (!magic.equals("tzdata") || tzdata_version[11] != 0) {
-          throw new IOException("bad tzdata magic: " + Arrays.toString(tzdata_version));
-        }
-        version = new String(tzdata_version, 6, 5, StandardCharsets.US_ASCII);
-
-        final int fileSize = mappedFile.size();
-        int index_offset = it.readInt();
-        validateOffset(index_offset, fileSize);
-        int data_offset = it.readInt();
-        validateOffset(data_offset, fileSize);
-        int zonetab_offset = it.readInt();
-        validateOffset(zonetab_offset, fileSize);
-
-        if (index_offset >= data_offset || data_offset >= zonetab_offset) {
-          throw new IOException("Invalid offset: index_offset=" + index_offset
-                  + ", data_offset=" + data_offset + ", zonetab_offset=" + zonetab_offset
-                  + ", fileSize=" + fileSize);
-        }
-
-        readIndex(it, index_offset, data_offset);
-        readZoneTab(it, zonetab_offset, fileSize - zonetab_offset);
-      } catch (IndexOutOfBoundsException e) {
-        throw new IOException("Invalid read from data file", e);
-      }
-    }
-
-    private static void validateOffset(int offset, int size) throws IOException {
-      if (offset < 0 || offset >= size) {
-        throw new IOException("Invalid offset=" + offset + ", size=" + size);
-      }
-    }
-
-    private void readZoneTab(BufferIterator it, int zoneTabOffset, int zoneTabSize) {
-      byte[] bytes = new byte[zoneTabSize];
-      it.seek(zoneTabOffset);
-      it.readByteArray(bytes, 0, bytes.length);
-      zoneTab = new String(bytes, 0, bytes.length, StandardCharsets.US_ASCII);
-    }
-
-    private void readIndex(BufferIterator it, int indexOffset, int dataOffset) throws IOException {
-      it.seek(indexOffset);
-
-      byte[] idBytes = new byte[SIZEOF_TZNAME];
-      int indexSize = (dataOffset - indexOffset);
-      if (indexSize % SIZEOF_INDEX_ENTRY != 0) {
-        throw new IOException("Index size is not divisible by " + SIZEOF_INDEX_ENTRY
-                + ", indexSize=" + indexSize);
-      }
-      int entryCount = indexSize / SIZEOF_INDEX_ENTRY;
-
-      byteOffsets = new int[entryCount];
-      ids = new String[entryCount];
-
-      for (int i = 0; i < entryCount; i++) {
-        // Read the fixed length timezone ID.
-        it.readByteArray(idBytes, 0, idBytes.length);
-
-        // Read the offset into the file where the data for ID can be found.
-        byteOffsets[i] = it.readInt();
-        byteOffsets[i] += dataOffset;
-
-        int length = it.readInt();
-        if (length < 44) {
-          throw new IOException("length in index file < sizeof(tzhead)");
-        }
-        it.skip(4); // Skip the unused 4 bytes that used to be the raw offset.
-
-        // Calculate the true length of the ID.
-        int len = 0;
-        while (idBytes[len] != 0 && len < idBytes.length) {
-          len++;
-        }
-        if (len == 0) {
-          throw new IOException("Invalid ID at index=" + i);
-        }
-        ids[i] = new String(idBytes, 0, len, StandardCharsets.US_ASCII);
-        if (i > 0) {
-          if (ids[i].compareTo(ids[i - 1]) <= 0) {
-            throw new IOException("Index not sorted or contains multiple entries with the same ID"
-                    + ", index=" + i + ", ids[i]=" + ids[i] + ", ids[i - 1]=" + ids[i - 1]);
-          }
-        }
-      }
-    }
-
-    public void validate() throws IOException {
-      checkNotClosed();
-      // Validate the data in the tzdata file by loading each and every zone.
-      for (String id : getAvailableIDs()) {
-        ZoneInfo zoneInfo = makeTimeZoneUncached(id);
-        if (zoneInfo == null) {
-          throw new IOException("Unable to find data for ID=" + id);
-        }
-      }
-    }
-
-    ZoneInfo makeTimeZoneUncached(String id) throws IOException {
-      BufferIterator it = getBufferIterator(id);
-      if (it == null) {
-        return null;
-      }
-
-      return ZoneInfo.readTimeZone(id, it, System.currentTimeMillis());
-    }
-
-    public String[] getAvailableIDs() {
-      checkNotClosed();
-      return ids.clone();
-    }
-
-    public String[] getAvailableIDs(int rawUtcOffset) {
-      checkNotClosed();
-      List<String> matches = new ArrayList<String>();
-      int[] rawUtcOffsets = getRawUtcOffsets();
-      for (int i = 0; i < rawUtcOffsets.length; ++i) {
-        if (rawUtcOffsets[i] == rawUtcOffset) {
-          matches.add(ids[i]);
-        }
-      }
-      return matches.toArray(new String[matches.size()]);
-    }
-
-    private synchronized int[] getRawUtcOffsets() {
-      if (rawUtcOffsetsCache != null) {
-        return rawUtcOffsetsCache;
-      }
-      rawUtcOffsetsCache = new int[ids.length];
-      for (int i = 0; i < ids.length; ++i) {
-        // This creates a TimeZone, which is quite expensive. Hence the cache.
-        // Note that icu4c does the same (without the cache), so if you're
-        // switching this code over to icu4j you should check its performance.
-        // Telephony shouldn't care, but someone converting a bunch of calendar
-        // events might.
-        rawUtcOffsetsCache[i] = cache.get(ids[i]).getRawOffset();
-      }
-      return rawUtcOffsetsCache;
-    }
-
-    public String getVersion() {
-      checkNotClosed();
-      return version;
-    }
-
-    public String getZoneTab() {
-      checkNotClosed();
-      return zoneTab;
-    }
-
-    public ZoneInfo makeTimeZone(String id) throws IOException {
-      checkNotClosed();
-      ZoneInfo zoneInfo = cache.get(id);
-      // The object from the cache is cloned because TimeZone / ZoneInfo are mutable.
-      return zoneInfo == null ? null : (ZoneInfo) zoneInfo.clone();
-    }
-
-    public boolean hasTimeZone(String id) throws IOException {
-      checkNotClosed();
-      return cache.get(id) != null;
-    }
-
-    public void close() {
-      if (!closed) {
-        closed = true;
-
-        // Clear state that takes up appreciable heap.
-        ids = null;
-        byteOffsets = null;
-        rawUtcOffsetsCache = null;
-        cache.evictAll();
-
-        // Remove the mapped file (if needed).
-        if (mappedFile != null) {
-          try {
-            mappedFile.close();
-          } catch (ErrnoException ignored) {
-          }
-          mappedFile = null;
-        }
-      }
-    }
-
-    private void checkNotClosed() throws IllegalStateException {
-      if (closed) {
-        throw new IllegalStateException("TzData is closed");
-      }
-    }
-
-    @Override protected void finalize() throws Throwable {
-      try {
-        close();
-      } finally {
-        super.finalize();
-      }
-    }
-
-    /**
-     * Returns the String describing the IANA version of the rules contained in the specified TzData
-     * file. This method just reads the header of the file, and so is less expensive than mapping
-     * the whole file into memory (and provides no guarantees about validity).
-     */
-    public static String getRulesVersion(File tzDataFile) throws IOException {
-      try (FileInputStream is = new FileInputStream(tzDataFile)) {
-
-        final int bytesToRead = 12;
-        byte[] tzdataVersion = new byte[bytesToRead];
-        int bytesRead = is.read(tzdataVersion, 0, bytesToRead);
-        if (bytesRead != bytesToRead) {
-          throw new IOException("File too short: only able to read " + bytesRead + " bytes.");
-        }
-
-        String magic = new String(tzdataVersion, 0, 6, StandardCharsets.US_ASCII);
-        if (!magic.equals("tzdata") || tzdataVersion[11] != 0) {
-          throw new IOException("bad tzdata magic: " + Arrays.toString(tzdataVersion));
-        }
-        return new String(tzdataVersion, 6, 5, StandardCharsets.US_ASCII);
-      }
-    }
-  }
-
-  private ZoneInfoDB() {
-  }
-
-  public static TzData getInstance() {
-    return DATA;
-  }
-}
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/ExpatAttributes.java b/luni/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
index 9ce8e81..3368f92 100644
--- a/luni/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
+++ b/luni/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.xml.sax.Attributes;
 
 /**
@@ -28,6 +29,10 @@
      */
     private static final String CDATA = "CDATA";
 
+    @UnsupportedAppUsage
+    public ExpatAttributes() {
+    }
+
     /**
      * Gets the number of attributes.
      */
diff --git a/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java b/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
index 4e3cedc..71c94f9 100644
--- a/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
+++ b/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import dalvik.annotation.optimization.ReachabilitySensitive;
 import java.io.IOException;
 import java.io.InputStream;
@@ -56,6 +57,7 @@
 
     private final Locator locator = new ExpatLocator();
 
+    @UnsupportedAppUsage
     private final ExpatReader xmlReader;
 
     private final String publicId;
@@ -63,6 +65,7 @@
 
     private final String encoding;
 
+    @UnsupportedAppUsage
     private final ExpatAttributes attributes = new CurrentAttributes();
 
     private static final String OUTSIDE_START_ELEMENT
@@ -80,6 +83,7 @@
     /**
      * Constructs a new parser with the specified encoding.
      */
+    @UnsupportedAppUsage
     /*package*/ ExpatParser(String encoding, ExpatReader xmlReader,
             boolean processNamespaces, String publicId, String systemId) {
         this.publicId = publicId;
@@ -425,6 +429,7 @@
      * @param length of characters to use
      * @throws SAXException if an error occurs during parsing
      */
+    @UnsupportedAppUsage
     /*package*/ void append(char[] xml, int offset, int length)
             throws SAXException {
         try {
@@ -457,6 +462,7 @@
      * @param length of bytes to use
      * @throws SAXException if an error occurs during parsing
      */
+    @UnsupportedAppUsage
     /*package*/ void append(byte[] xml, int offset, int length)
             throws SAXException {
         try {
@@ -542,6 +548,7 @@
      *
      * @throws SAXException if the xml is incomplete
      */
+    @UnsupportedAppUsage
     /*package*/ void finish() throws SAXException {
         try {
             appendString(this.pointer, "", true);
@@ -602,6 +609,7 @@
      * Clones the current attributes so they can be used outside of
      * startElement().
      */
+    @UnsupportedAppUsage
     /*package*/ Attributes cloneAttributes() {
         if (!inStartElement) {
             throw new IllegalStateException(OUTSIDE_START_ELEMENT);
@@ -770,6 +778,7 @@
      */
     private static class EntityParser extends ExpatParser {
 
+        @UnsupportedAppUsage
         private int depth = 0;
 
         private EntityParser(String encoding, ExpatReader xmlReader,
diff --git a/luni/src/main/java/org/apache/harmony/xml/ExpatReader.java b/luni/src/main/java/org/apache/harmony/xml/ExpatReader.java
index e0542b1..510a889 100644
--- a/luni/src/main/java/org/apache/harmony/xml/ExpatReader.java
+++ b/luni/src/main/java/org/apache/harmony/xml/ExpatReader.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
@@ -40,6 +41,7 @@
      * ExpatParser accesses these fields directly during parsing. The user
      * should be able to safely change them during parsing.
      */
+    @UnsupportedAppUsage
     /*package*/ ContentHandler contentHandler;
     /*package*/ DTDHandler dtdHandler;
     /*package*/ EntityResolver entityResolver;
@@ -64,6 +66,10 @@
                 = BASE_URI + "external-parameter-entities";
     }
 
+    @UnsupportedAppUsage
+    public ExpatReader() {
+    }
+
     public boolean getFeature(String name)
             throws SAXNotRecognizedException, SAXNotSupportedException {
         if (name == null) {
diff --git a/luni/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/luni/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
index 0749998..a0da24d 100644
--- a/luni/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml.dom;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -42,6 +43,7 @@
     boolean namespaceAware;
     String namespaceURI;
     String prefix;
+    @UnsupportedAppUsage
     String localName;
 
     private List<AttrImpl> attributes = new ArrayList<AttrImpl>();
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/luni/src/main/java/org/w3c/dom/ls/LSSerializerFilter.java b/luni/src/main/java/org/w3c/dom/ls/LSSerializerFilter.java
index 0a03810..554807c 100644
--- a/luni/src/main/java/org/w3c/dom/ls/LSSerializerFilter.java
+++ b/luni/src/main/java/org/w3c/dom/ls/LSSerializerFilter.java
@@ -12,6 +12,7 @@
 
 package org.w3c.dom.ls;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.w3c.dom.traversal.NodeFilter;
 
 /**
@@ -60,6 +61,7 @@
      * <br> The constants used here are defined in [<a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113'>DOM Level 2 Traversal and      Range</a>]
      * .
      */
+    @UnsupportedAppUsage
     public int getWhatToShow();
 
 }
diff --git a/luni/src/main/java/org/w3c/dom/traversal/NodeFilter.java b/luni/src/main/java/org/w3c/dom/traversal/NodeFilter.java
index 12f6377..24f7599 100644
--- a/luni/src/main/java/org/w3c/dom/traversal/NodeFilter.java
+++ b/luni/src/main/java/org/w3c/dom/traversal/NodeFilter.java
@@ -12,6 +12,7 @@
 
 package org.w3c.dom.traversal;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.w3c.dom.Node;
 
 /**
@@ -141,6 +142,7 @@
      * @return A constant to determine whether the node is accepted,
      *   rejected, or skipped, as defined above.
      */
+    @UnsupportedAppUsage
     public short acceptNode(Node n);
 
 }
diff --git a/luni/src/main/java/org/w3c/dom/traversal/NodeIterator.java b/luni/src/main/java/org/w3c/dom/traversal/NodeIterator.java
index f1fd5d0..686beb7 100644
--- a/luni/src/main/java/org/w3c/dom/traversal/NodeIterator.java
+++ b/luni/src/main/java/org/w3c/dom/traversal/NodeIterator.java
@@ -12,6 +12,7 @@
 
 package org.w3c.dom.traversal;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Node;
 
@@ -83,6 +84,7 @@
      *   INVALID_STATE_ERR: Raised if this method is called after the
      *   <code>detach</code> method was invoked.
      */
+    @UnsupportedAppUsage
     public Node nextNode()
                          throws DOMException;
 
@@ -106,6 +108,7 @@
      * or <code>previousNode</code> will raise the exception
      * INVALID_STATE_ERR.
      */
+    @UnsupportedAppUsage
     public void detach();
 
 }
diff --git a/luni/src/main/java/org/xml/sax/InputSource.java b/luni/src/main/java/org/xml/sax/InputSource.java
index b9b148e..3750cfe 100644
--- a/luni/src/main/java/org/xml/sax/InputSource.java
+++ b/luni/src/main/java/org/xml/sax/InputSource.java
@@ -5,6 +5,7 @@
 
 package org.xml.sax;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.InputStream;
 import java.io.Reader;
 
@@ -326,10 +327,15 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     private String publicId;
+    @UnsupportedAppUsage
     private String systemId;
+    @UnsupportedAppUsage
     private InputStream byteStream;
+    @UnsupportedAppUsage
     private String encoding;
+    @UnsupportedAppUsage
     private Reader characterStream;
 
 }
diff --git a/luni/src/main/java/org/xml/sax/SAXException.java b/luni/src/main/java/org/xml/sax/SAXException.java
index b8d0a9b..ea69d3f 100644
--- a/luni/src/main/java/org/xml/sax/SAXException.java
+++ b/luni/src/main/java/org/xml/sax/SAXException.java
@@ -5,6 +5,8 @@
 
 package org.xml.sax;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * Encapsulate a general SAX error or warning.
  *
@@ -144,6 +146,7 @@
     /**
      * @serial The embedded exception if tunnelling, or null.
      */
+    @UnsupportedAppUsage
     private Exception exception;
 
 }
diff --git a/luni/src/main/java/org/xml/sax/SAXParseException.java b/luni/src/main/java/org/xml/sax/SAXParseException.java
index 424f77b..72b16cf 100644
--- a/luni/src/main/java/org/xml/sax/SAXParseException.java
+++ b/luni/src/main/java/org/xml/sax/SAXParseException.java
@@ -5,6 +5,8 @@
 
 package org.xml.sax;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
 /**
  * Encapsulate an XML parse error or warning.
  *
@@ -163,6 +165,7 @@
      * @param lineNumber The line number of the error, or -1.
      * @param columnNumber The column number of the error, or -1.
      */
+    @UnsupportedAppUsage
     private void init (String publicId, String systemId,
                int lineNumber, int columnNumber)
     {
@@ -241,6 +244,7 @@
      * @serial The public identifier, or null.
      * @see #getPublicId
      */
+    @UnsupportedAppUsage
     private String publicId;
 
 
@@ -248,6 +252,7 @@
      * @serial The system identifier, or null.
      * @see #getSystemId
      */
+    @UnsupportedAppUsage
     private String systemId;
 
 
@@ -255,6 +260,7 @@
      * @serial The line number, or -1.
      * @see #getLineNumber
      */
+    @UnsupportedAppUsage
     private int lineNumber;
 
 
@@ -262,6 +268,7 @@
      * @serial The column number, or -1.
      * @see #getColumnNumber
      */
+    @UnsupportedAppUsage
     private int columnNumber;
 
 }
diff --git a/luni/src/main/java/org/xml/sax/ext/Attributes2Impl.java b/luni/src/main/java/org/xml/sax/ext/Attributes2Impl.java
index 52fa1e5..b3702a4 100644
--- a/luni/src/main/java/org/xml/sax/ext/Attributes2Impl.java
+++ b/luni/src/main/java/org/xml/sax/ext/Attributes2Impl.java
@@ -5,6 +5,7 @@
 
 package org.xml.sax.ext;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 import org.xml.sax.Attributes;
 import org.xml.sax.helpers.AttributesImpl;
@@ -37,7 +38,9 @@
  */
 public class Attributes2Impl extends AttributesImpl implements Attributes2
 {
+    @UnsupportedAppUsage
     private boolean[] declared;
+    @UnsupportedAppUsage
     private boolean[] specified;
 
 
diff --git a/luni/src/main/java/org/xml/sax/ext/Locator2Impl.java b/luni/src/main/java/org/xml/sax/ext/Locator2Impl.java
index 9274d58..bb9582f 100644
--- a/luni/src/main/java/org/xml/sax/ext/Locator2Impl.java
+++ b/luni/src/main/java/org/xml/sax/ext/Locator2Impl.java
@@ -5,6 +5,7 @@
 
 package org.xml.sax.ext;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.xml.sax.Locator;
 import org.xml.sax.helpers.LocatorImpl;
 
@@ -26,7 +27,9 @@
  */
 public class Locator2Impl extends LocatorImpl implements Locator2
 {
+    @UnsupportedAppUsage
     private String    encoding;
+    @UnsupportedAppUsage
     private String    version;
 
 
diff --git a/luni/src/main/java/org/xml/sax/helpers/AttributesImpl.java b/luni/src/main/java/org/xml/sax/helpers/AttributesImpl.java
index f6d5f85..9193075 100644
--- a/luni/src/main/java/org/xml/sax/helpers/AttributesImpl.java
+++ b/luni/src/main/java/org/xml/sax/helpers/AttributesImpl.java
@@ -6,6 +6,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.xml.sax.Attributes;
 
 
@@ -563,6 +564,7 @@
      * @param n The minimum number of attributes that the array must
      *        be able to hold.
      */
+    @UnsupportedAppUsage
     private void ensureCapacity (int n)    {
         if (n <= 0) {
             return;
@@ -595,6 +597,7 @@
      * @param index The index to report.
      * @exception java.lang.ArrayIndexOutOfBoundsException Always.
      */
+    @UnsupportedAppUsage
     private void badIndex (int index)
     throws ArrayIndexOutOfBoundsException
     {
@@ -609,7 +612,9 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     int length;
+    @UnsupportedAppUsage
     String data [];
 
 }
diff --git a/luni/src/main/java/org/xml/sax/helpers/LocatorImpl.java b/luni/src/main/java/org/xml/sax/helpers/LocatorImpl.java
index e7ec76a..944c41a 100644
--- a/luni/src/main/java/org/xml/sax/helpers/LocatorImpl.java
+++ b/luni/src/main/java/org/xml/sax/helpers/LocatorImpl.java
@@ -5,6 +5,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import org.xml.sax.Locator;
 
 
@@ -204,9 +205,13 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     private String publicId;
+    @UnsupportedAppUsage
     private String systemId;
+    @UnsupportedAppUsage
     private int lineNumber;
+    @UnsupportedAppUsage
     private int columnNumber;
 
 }
diff --git a/luni/src/main/java/org/xml/sax/helpers/NamespaceSupport.java b/luni/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
index 5f96797..820f8d2 100644
--- a/luni/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
+++ b/luni/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
@@ -6,6 +6,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EmptyStackException;
@@ -113,6 +114,7 @@
     /**
      * An empty enumeration.
      */
+    @UnsupportedAppUsage
     private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.emptyList());
 
 
@@ -517,9 +519,13 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     private Context contexts[];
+    @UnsupportedAppUsage
     private Context currentContext;
+    @UnsupportedAppUsage
     private int contextPos;
+    @UnsupportedAppUsage
     private boolean namespaceDeclUris;
 
 
@@ -544,6 +550,7 @@
     /**
      * Create the root-level Namespace context.
      */
+    @UnsupportedAppUsage
     Context ()
     {
         copyTables();
diff --git a/luni/src/main/java/org/xml/sax/helpers/ParserAdapter.java b/luni/src/main/java/org/xml/sax/helpers/ParserAdapter.java
index 9d1c683..5acc659 100644
--- a/luni/src/main/java/org/xml/sax/helpers/ParserAdapter.java
+++ b/luni/src/main/java/org/xml/sax/helpers/ParserAdapter.java
@@ -6,6 +6,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -129,6 +130,7 @@
      * @exception java.lang.NullPointerException If the parser parameter
      *            is null.
      */
+    @UnsupportedAppUsage
     private void setup (Parser parser)
     {
     if (parser == null) {
@@ -697,6 +699,7 @@
     /**
      * Initialize the parser before each run.
      */
+    @UnsupportedAppUsage
     private void setupParser ()
     {
     // catch an illegal "nonsense" state.
@@ -734,6 +737,7 @@
      * @exception SAXException The client may throw
      *            an exception if there is an error callback.
      */
+    @UnsupportedAppUsage
     private String [] processName (String qName, boolean isAttribute,
                    boolean useException)
     throws SAXException
@@ -759,6 +763,7 @@
      * @exception SAXException The client may throw
      *            an exception.
      */
+    @UnsupportedAppUsage
     void reportError (String message)
     throws SAXException
     {
@@ -772,6 +777,7 @@
      *
      * @param message The error message.
      */
+    @UnsupportedAppUsage
     private SAXParseException makeException (String message)
     {
     if (locator != null) {
@@ -793,6 +799,7 @@
      * @exception SAXNotSupportedException If a
      *            document is currently being parsed.
      */
+    @UnsupportedAppUsage
     private void checkNotParsing (String type, String name)
     throws SAXNotSupportedException
     {
@@ -810,29 +817,43 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     private NamespaceSupport nsSupport;
+    @UnsupportedAppUsage
     private AttributeListAdapter attAdapter;
 
+    @UnsupportedAppUsage
     private boolean parsing = false;
+    @UnsupportedAppUsage
     private String nameParts[] = new String[3];
 
+    @UnsupportedAppUsage
     private Parser parser = null;
 
+    @UnsupportedAppUsage
     private AttributesImpl atts = null;
 
                 // Features
+    @UnsupportedAppUsage
     private boolean namespaces = true;
+    @UnsupportedAppUsage
     private boolean prefixes = false;
+    @UnsupportedAppUsage
     private boolean uris = false;
 
                 // Properties
 
                 // Handlers
+    @UnsupportedAppUsage
     Locator locator;
 
+    @UnsupportedAppUsage
     EntityResolver entityResolver = null;
+    @UnsupportedAppUsage
     DTDHandler dtdHandler = null;
+    @UnsupportedAppUsage
     ContentHandler contentHandler = null;
+    @UnsupportedAppUsage
     ErrorHandler errorHandler = null;
 
 
@@ -859,6 +880,7 @@
     /**
      * Construct a new adapter.
      */
+    @UnsupportedAppUsage
     AttributeListAdapter ()
     {
     }
diff --git a/luni/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java b/luni/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
index 4b4dd71..95ae356 100644
--- a/luni/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
+++ b/luni/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
@@ -6,6 +6,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.IOException;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -683,6 +684,7 @@
      * non-null, and re-register the filter for all of the
      * events.</p>
      */
+    @UnsupportedAppUsage
     private void setupParse ()
     {
     if (parent == null) {
@@ -700,11 +702,17 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     private XMLReader parent = null;
+    @UnsupportedAppUsage
     private Locator locator = null;
+    @UnsupportedAppUsage
     private EntityResolver entityResolver = null;
+    @UnsupportedAppUsage
     private DTDHandler dtdHandler = null;
+    @UnsupportedAppUsage
     private ContentHandler contentHandler = null;
+    @UnsupportedAppUsage
     private ErrorHandler errorHandler = null;
 
 }
diff --git a/luni/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java b/luni/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
index c683229..0ef4d6f 100644
--- a/luni/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
+++ b/luni/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
@@ -6,6 +6,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.IOException;
 import java.util.Locale;
 import org.xml.sax.AttributeList;
@@ -95,6 +96,7 @@
      *
      * @param xmlReader The embedded XMLReader.
      */
+    @UnsupportedAppUsage
     private void setup (XMLReader xmlReader)
     {
     if (xmlReader == null) {
@@ -227,6 +229,7 @@
     /**
      * Set up the XML reader.
      */
+    @UnsupportedAppUsage
     private void setupXMLReader ()
     throws SAXException
     {
@@ -425,8 +428,11 @@
     // Internal state.
     ////////////////////////////////////////////////////////////////////
 
+    @UnsupportedAppUsage
     XMLReader xmlReader;
+    @UnsupportedAppUsage
     DocumentHandler documentHandler;
+    @UnsupportedAppUsage
     AttributesAdapter qAtts;
 
 
diff --git a/luni/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java b/luni/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
index 39dd367..b95728f 100644
--- a/luni/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
+++ b/luni/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
@@ -7,6 +7,7 @@
 
 package org.xml.sax.helpers;
 
+import dalvik.annotation.compat.UnsupportedAppUsage;
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -185,6 +186,7 @@
     return loadClass (NewInstance.getClassLoader (), className);
     }
 
+    @UnsupportedAppUsage
     private static XMLReader loadClass (ClassLoader loader, String className)
     throws SAXException
     {
diff --git a/luni/src/main/native/Android.bp b/luni/src/main/native/Android.bp
index 8526ce8..8621752 100644
--- a/luni/src/main/native/Android.bp
+++ b/luni/src/main/native/Android.bp
@@ -3,6 +3,7 @@
     srcs: [
         "ExecStrings.cpp",
         "IcuUtilities.cpp",
+        "JniConstants.cpp",
         "JniException.cpp",
         "NetworkUtilities.cpp",
         "Register.cpp",
@@ -27,3 +28,10 @@
         "valueOf.cpp",
     ],
 }
+
+filegroup {
+    name: "libandroidio_srcs",
+    srcs: [
+        "AsynchronousCloseMonitor.cpp",
+    ],
+}
diff --git a/luni/src/main/native/AsynchronousCloseMonitor.cpp b/luni/src/main/native/AsynchronousCloseMonitor.cpp
new file mode 100644
index 0000000..7fea936
--- /dev/null
+++ b/luni/src/main/native/AsynchronousCloseMonitor.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AsynchronousCloseMonitor"
+
+#include <log/log.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <mutex>
+
+#include "AsynchronousCloseMonitor.h"
+
+namespace {
+
+class AsynchronousCloseMonitorImpl {
+public:
+    explicit AsynchronousCloseMonitorImpl(int fd);
+    ~AsynchronousCloseMonitorImpl();
+    bool wasSignaled() const;
+
+    static void init();
+
+    static void signalBlockedThreads(int fd);
+
+private:
+    AsynchronousCloseMonitorImpl(const AsynchronousCloseMonitorImpl&) = delete;
+    AsynchronousCloseMonitorImpl& operator=(const AsynchronousCloseMonitorImpl&) = delete;
+
+    AsynchronousCloseMonitorImpl* mPrev;
+    AsynchronousCloseMonitorImpl* mNext;
+    pthread_t mThread;
+    int mFd;
+    bool mSignaled;
+};
+
+/**
+ * We use an intrusive doubly-linked list to keep track of blocked threads.
+ * This gives us O(1) insertion and removal, and means we don't need to do any allocation.
+ * (The objects themselves are stack-allocated.)
+ * Waking potentially-blocked threads when a file descriptor is closed is O(n) in the total number
+ * of blocked threads (not the number of threads actually blocked on the file descriptor in
+ * question). For now at least, this seems like a good compromise for Android.
+ */
+static std::mutex blockedThreadListMutex;
+static AsynchronousCloseMonitorImpl* blockedThreadList = NULL;
+
+/**
+ * The specific signal chosen here is arbitrary, but bionic needs to know so that SIGRTMIN
+ * starts at a higher value.
+ */
+#if defined(__Fuchsia__)
+static const int BLOCKED_THREAD_SIGNAL = SIGRTMIN + 2;
+#else
+static const int BLOCKED_THREAD_SIGNAL = __SIGRTMIN + 2;
+#endif
+
+static void blockedThreadSignalHandler(int /*signal*/) {
+    // Do nothing. We only sent this signal for its side-effect of interrupting syscalls.
+}
+
+void AsynchronousCloseMonitorImpl::init() {
+    // Ensure that the signal we send interrupts system calls but doesn't kill threads.
+    // Using sigaction(2) lets us ensure that the SA_RESTART flag is not set.
+    // (The whole reason we're sending this signal is to unblock system calls!)
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = blockedThreadSignalHandler;
+    sa.sa_flags = 0;
+    int rc = sigaction(BLOCKED_THREAD_SIGNAL, &sa, NULL);
+    if (rc == -1) {
+        ALOGE("setting blocked thread signal handler failed: %s", strerror(errno));
+    }
+}
+
+void AsynchronousCloseMonitorImpl::signalBlockedThreads(int fd) {
+    std::lock_guard<std::mutex> lock(blockedThreadListMutex);
+    for (AsynchronousCloseMonitorImpl* it = blockedThreadList; it != NULL; it = it->mNext) {
+        if (it->mFd == fd) {
+            it->mSignaled = true;
+            pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL);
+            // Keep going, because there may be more than one thread...
+        }
+    }
+}
+
+bool AsynchronousCloseMonitorImpl::wasSignaled() const {
+    return mSignaled;
+}
+
+AsynchronousCloseMonitorImpl::AsynchronousCloseMonitorImpl(int fd) {
+    std::lock_guard<std::mutex> lock(blockedThreadListMutex);
+    // Who are we, and what are we waiting for?
+    mThread = pthread_self();
+    mFd = fd;
+    mSignaled = false;
+    // Insert ourselves at the head of the intrusive doubly-linked list...
+    mPrev = NULL;
+    mNext = blockedThreadList;
+    if (mNext != NULL) {
+        mNext->mPrev = this;
+    }
+    blockedThreadList = this;
+}
+
+AsynchronousCloseMonitorImpl::~AsynchronousCloseMonitorImpl() {
+    std::lock_guard<std::mutex> lock(blockedThreadListMutex);
+    // Unlink ourselves from the intrusive doubly-linked list...
+    if (mNext != NULL) {
+        mNext->mPrev = mPrev;
+    }
+    if (mPrev == NULL) {
+        blockedThreadList = mNext;
+    } else {
+        mPrev->mNext = mNext;
+    }
+}
+
+}  // namespace
+
+//
+// C ABI and API boundary
+//
+
+extern "C" {
+void async_close_monitor_static_init() {
+  AsynchronousCloseMonitorImpl::init();
+}
+
+void async_close_monitor_signal_blocked_threads(int fd) {
+  AsynchronousCloseMonitorImpl::signalBlockedThreads(fd);
+}
+
+void* async_close_monitor_create(int fd) {
+  return new AsynchronousCloseMonitorImpl(fd);
+}
+
+void async_close_monitor_destroy(void* instance) {
+  auto monitor = reinterpret_cast<AsynchronousCloseMonitorImpl*>(instance);
+  delete monitor;
+}
+
+int async_close_monitor_was_signalled(const void* instance) {
+  auto monitor = reinterpret_cast<const AsynchronousCloseMonitorImpl*>(instance);
+  return monitor->wasSignaled() ? 1 : 0;
+}
+}
diff --git a/luni/src/main/native/AsynchronousCloseMonitor.h b/luni/src/main/native/AsynchronousCloseMonitor.h
new file mode 100644
index 0000000..5bccf3d
--- /dev/null
+++ b/luni/src/main/native/AsynchronousCloseMonitor.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifndef ASYNCHRONOUS_CLOSE_MONITOR_H_included
+#define ASYNCHRONOUS_CLOSE_MONITOR_H_included
+
+#include <pthread.h>
+
+// Public API for library function.
+extern "C" {
+void async_close_monitor_destroy(void* instance);
+void async_close_monitor_static_init();
+void async_close_monitor_signal_blocked_threads(int fd);
+int async_close_monitor_was_signalled(const void* instance);
+void* async_close_monitor_create(int fd);
+}
+
+/**
+ * AsynchronousCloseMonitor helps implement Java's asynchronous close semantics.
+ *
+ * AsynchronousCloseMonitor::init must be called before anything else.
+ *
+ * Every blocking I/O operation must be surrounded by an AsynchronousCloseMonitor
+ * instance. For example:
+ *
+ *   {
+ *     AsynchronousCloseMonitor monitor(fd);
+ *     byteCount = ::read(fd, buf, sizeof(buf));
+ *   }
+ *
+ * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads:
+ *
+ *   AsynchronousCloseMonitor::signalBlockedThreads(fd);
+ *
+ * To test to see if the interruption was due to the signalBlockedThreads call:
+ *
+ *   monitor.wasSignaled();
+ */
+class AsynchronousCloseMonitor {
+public:
+    explicit AsynchronousCloseMonitor(int fd) {
+        instance_ = async_close_monitor_create(fd);
+    }
+    ~AsynchronousCloseMonitor() {
+        async_close_monitor_destroy(instance_);
+    }
+    bool wasSignaled() const {
+        return async_close_monitor_was_signalled(instance_) != 0;
+    }
+
+    static void init() {
+        async_close_monitor_static_init();
+    }
+
+    static void signalBlockedThreads(int fd) {
+        async_close_monitor_signal_blocked_threads(fd);
+    }
+
+private:
+    AsynchronousCloseMonitor(const AsynchronousCloseMonitor&) = delete;
+    AsynchronousCloseMonitor& operator=(const AsynchronousCloseMonitor&) = delete;
+
+    void* instance_;
+};
+
+#endif  // ASYNCHRONOUS_CLOSE_MONITOR_H_included
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp
index 43b2f27..ed10d04 100644
--- a/luni/src/main/native/IcuUtilities.cpp
+++ b/luni/src/main/native/IcuUtilities.cpp
@@ -17,13 +17,13 @@
 #define LOG_TAG "IcuUtilities"
 
 #include <android/log.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
 
 #include "IcuUtilities.h"
 
+#include "JniConstants.h"
 #include "JniException.h"
 #include "unicode/strenum.h"
 #include "unicode/ustring.h"
@@ -39,7 +39,7 @@
     return NULL;
   }
 
-  jobjectArray result = env->NewObjectArray(count, JniConstants::stringClass, NULL);
+  jobjectArray result = env->NewObjectArray(count, JniConstants::GetStringClass(env), NULL);
   for (int32_t i = 0; i < count; ++i) {
     const icu::UnicodeString* string = se->snext(status);
     if (maybeThrowIcuException(env, "StringEnumeration::snext", status)) {
diff --git a/luni/src/main/native/JniConstants.cpp b/luni/src/main/native/JniConstants.cpp
new file mode 100644
index 0000000..8427353
--- /dev/null
+++ b/luni/src/main/native/JniConstants.cpp
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "JniConstants"
+
+#include "JniConstants.h"
+
+#include <atomic>
+#include <mutex>
+#include <stdlib.h>
+
+#include <log/log.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace {
+
+jclass findClass(JNIEnv* env, const char* name) {
+    ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
+    jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
+    if (result == NULL) {
+        ALOGE("failed to find class '%s'", name);
+        abort();
+    }
+    return result;
+}
+
+// Mutex protecting static variables
+static std::mutex g_constants_mutex;
+
+// Flag indicating whether cached constants are valid
+static bool g_constants_valid = false;
+
+// Constants
+jclass booleanClass;
+jclass charsetICUClass;
+jclass doubleClass;
+jclass errnoExceptionClass;
+jclass fileDescriptorClass;
+jclass gaiExceptionClass;
+jclass inet6AddressClass;
+jclass inet6AddressHolderClass;
+jclass inetAddressClass;
+jclass inetAddressHolderClass;
+jclass inetSocketAddressClass;
+jclass inetSocketAddressHolderClass;
+jclass integerClass;
+jclass localeDataClass;
+jclass longClass;
+jclass netlinkSocketAddressClass;
+jclass packetSocketAddressClass;
+jclass patternSyntaxExceptionClass;
+jclass stringClass;
+jclass structAddrinfoClass;
+jclass structFlockClass;
+jclass structGroupReqClass;
+jclass structIfaddrsClass;
+jclass structLingerClass;
+jclass structPasswdClass;
+jclass structPollfdClass;
+jclass structStatClass;
+jclass structStatVfsClass;
+jclass structTimespecClass;
+jclass structTimevalClass;
+jclass structUcredClass;
+jclass structUtsnameClass;
+jclass unixSocketAddressClass;
+
+// EnsureJniConstantsInitialized initializes cached constants. It should be
+// called before returning a heap object from the cache to ensure cache is
+// initialized. This pattern is only necessary because if a process finishes one
+// runtime and starts another then JNI_OnLoad may not be called.
+void EnsureJniConstantsInitialized(JNIEnv* env) {
+    if (g_constants_valid) {
+        return;
+    }
+
+    std::lock_guard guard(g_constants_mutex);
+    if (g_constants_valid) {
+        return;
+    }
+
+    booleanClass = findClass(env, "java/lang/Boolean");
+    charsetICUClass = findClass(env, "java/nio/charset/CharsetICU");
+    doubleClass = findClass(env, "java/lang/Double");
+    errnoExceptionClass = findClass(env, "android/system/ErrnoException");
+    fileDescriptorClass = findClass(env, "java/io/FileDescriptor");
+    gaiExceptionClass = findClass(env, "android/system/GaiException");
+    inet6AddressClass = findClass(env, "java/net/Inet6Address");
+    inet6AddressHolderClass = findClass(env, "java/net/Inet6Address$Inet6AddressHolder");
+    inetAddressClass = findClass(env, "java/net/InetAddress");
+    inetAddressHolderClass = findClass(env, "java/net/InetAddress$InetAddressHolder");
+    inetSocketAddressClass = findClass(env, "java/net/InetSocketAddress");
+    inetSocketAddressHolderClass = findClass(env, "java/net/InetSocketAddress$InetSocketAddressHolder");
+    integerClass = findClass(env, "java/lang/Integer");
+    localeDataClass = findClass(env, "libcore/icu/LocaleData");
+    longClass = findClass(env, "java/lang/Long");
+    netlinkSocketAddressClass = findClass(env, "android/system/NetlinkSocketAddress");
+    packetSocketAddressClass = findClass(env, "android/system/PacketSocketAddress");
+    patternSyntaxExceptionClass = findClass(env, "java/util/regex/PatternSyntaxException");
+    stringClass = findClass(env, "java/lang/String");
+    structAddrinfoClass = findClass(env, "android/system/StructAddrinfo");
+    structFlockClass = findClass(env, "android/system/StructFlock");
+    structGroupReqClass = findClass(env, "android/system/StructGroupReq");
+    structIfaddrsClass = findClass(env, "android/system/StructIfaddrs");
+    structLingerClass = findClass(env, "android/system/StructLinger");
+    structPasswdClass = findClass(env, "android/system/StructPasswd");
+    structPollfdClass = findClass(env, "android/system/StructPollfd");
+    structStatClass = findClass(env, "android/system/StructStat");
+    structStatVfsClass = findClass(env, "android/system/StructStatVfs");
+    structTimevalClass = findClass(env, "android/system/StructTimeval");
+    structTimespecClass = findClass(env, "android/system/StructTimespec");
+    structUcredClass = findClass(env, "android/system/StructUcred");
+    structUtsnameClass = findClass(env, "android/system/StructUtsname");
+    unixSocketAddressClass = findClass(env, "android/system/UnixSocketAddress");
+
+    g_constants_valid = true;
+}
+
+}  // namespace
+
+void JniConstants::Initialize(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+}
+
+void JniConstants::Invalidate() {
+    std::lock_guard guard(g_constants_mutex);
+    g_constants_valid = false;
+}
+
+jclass JniConstants::GetBooleanClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return booleanClass;
+}
+
+jclass JniConstants::GetCharsetICUClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return charsetICUClass;
+}
+
+jclass JniConstants::GetDoubleClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return doubleClass;
+}
+
+jclass JniConstants::GetErrnoExceptionClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return errnoExceptionClass;
+}
+
+jclass JniConstants::GetFileDescriptorClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return fileDescriptorClass;
+}
+
+jclass JniConstants::GetGaiExceptionClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return gaiExceptionClass;
+}
+
+jclass JniConstants::GetInet6AddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inet6AddressClass;
+}
+
+jclass JniConstants::GetInet6AddressHolderClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inet6AddressHolderClass;
+}
+
+jclass JniConstants::GetInetAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inetAddressClass;
+}
+
+jclass JniConstants::GetInetAddressHolderClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inetAddressHolderClass;
+}
+
+jclass JniConstants::GetInetSocketAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inetSocketAddressClass;
+}
+
+jclass JniConstants::GetInetSocketAddressHolderClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return inetSocketAddressHolderClass;
+}
+
+jclass JniConstants::GetIntegerClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return integerClass;
+}
+
+jclass JniConstants::GetLocaleDataClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return localeDataClass;
+}
+
+jclass JniConstants::GetLongClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return longClass;
+}
+
+jclass JniConstants::GetNetlinkSocketAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return netlinkSocketAddressClass;
+}
+
+jclass JniConstants::GetPacketSocketAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return packetSocketAddressClass;
+}
+
+jclass JniConstants::GetPatternSyntaxExceptionClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return patternSyntaxExceptionClass;
+}
+
+jclass JniConstants::GetStringClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return stringClass;
+}
+
+jclass JniConstants::GetStructAddrinfoClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structAddrinfoClass;
+}
+
+jclass JniConstants::GetStructFlockClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structFlockClass;
+}
+
+jclass JniConstants::GetStructGroupReqClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structGroupReqClass;
+}
+
+jclass JniConstants::GetStructIfaddrsClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structIfaddrsClass;
+}
+
+jclass JniConstants::GetStructLingerClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structLingerClass;
+}
+
+jclass JniConstants::GetStructPasswdClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structPasswdClass;
+}
+
+jclass JniConstants::GetStructPollfdClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structPollfdClass;
+}
+
+jclass JniConstants::GetStructStatClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structStatClass;
+}
+
+jclass JniConstants::GetStructStatVfsClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structStatVfsClass;
+}
+
+jclass JniConstants::GetStructTimespecClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structTimespecClass;
+}
+
+jclass JniConstants::GetStructTimevalClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structTimevalClass;
+}
+
+jclass JniConstants::GetStructUcredClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structUcredClass;
+}
+
+jclass JniConstants::GetStructUtsnameClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structUtsnameClass;
+}
+
+jclass JniConstants::GetUnixSocketAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return unixSocketAddressClass;
+}
diff --git a/luni/src/main/native/JniConstants.h b/luni/src/main/native/JniConstants.h
new file mode 100644
index 0000000..021dc53
--- /dev/null
+++ b/luni/src/main/native/JniConstants.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef JNI_CONSTANTS_H_included
+#define JNI_CONSTANTS_H_included
+
+#include <jni.h>
+
+/**
+ * A cache to avoid calling FindClass at runtime.
+ */
+struct JniConstants {
+    // Initialized cached heap objects. This should be called in JNI_OnLoad.
+    static void Initialize(JNIEnv* env);
+
+    // Invalidate cached heap objects. This should be called in JNI_OnUnload.
+    static void Invalidate();
+
+    static jclass GetBooleanClass(JNIEnv* env);
+    static jclass GetCharsetICUClass(JNIEnv* env);
+    static jclass GetDoubleClass(JNIEnv* env);
+    static jclass GetErrnoExceptionClass(JNIEnv* env);
+    static jclass GetFileDescriptorClass(JNIEnv* env);
+    static jclass GetGaiExceptionClass(JNIEnv* env);
+    static jclass GetInet6AddressClass(JNIEnv* env);
+    static jclass GetInet6AddressHolderClass(JNIEnv* env);
+    static jclass GetInetAddressClass(JNIEnv* env);
+    static jclass GetInetAddressHolderClass(JNIEnv* env);
+    static jclass GetInetSocketAddressClass(JNIEnv* env);
+    static jclass GetInetSocketAddressHolderClass(JNIEnv* env);
+    static jclass GetIntegerClass(JNIEnv* env);
+    static jclass GetLocaleDataClass(JNIEnv* env);
+    static jclass GetLongClass(JNIEnv* env);
+    static jclass GetNetlinkSocketAddressClass(JNIEnv* env);
+    static jclass GetPacketSocketAddressClass(JNIEnv* env);
+    static jclass GetPatternSyntaxExceptionClass(JNIEnv* env);
+    static jclass GetStringClass(JNIEnv* env);
+    static jclass GetStructAddrinfoClass(JNIEnv* env);
+    static jclass GetStructFlockClass(JNIEnv* env);
+    static jclass GetStructGroupReqClass(JNIEnv* env);
+    static jclass GetStructIfaddrsClass(JNIEnv* env);
+    static jclass GetStructLingerClass(JNIEnv* env);
+    static jclass GetStructPasswdClass(JNIEnv* env);
+    static jclass GetStructPollfdClass(JNIEnv* env);
+    static jclass GetStructStatClass(JNIEnv* env);
+    static jclass GetStructStatVfsClass(JNIEnv* env);
+    static jclass GetStructTimespecClass(JNIEnv* env);
+    static jclass GetStructTimevalClass(JNIEnv* env);
+    static jclass GetStructUcredClass(JNIEnv* env);
+    static jclass GetStructUtsnameClass(JNIEnv* env);
+    static jclass GetUnixSocketAddressClass(JNIEnv* env);
+};
+
+#endif  // JNI_CONSTANTS_H_included
diff --git a/luni/src/main/native/NetFd.h b/luni/src/main/native/NetFd.h
deleted file mode 100644
index ae4e5ab..0000000
--- a/luni/src/main/native/NetFd.h
+++ /dev/null
@@ -1,72 +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.
- */
-
-#ifndef NET_FD_H_included
-#define NET_FD_H_included
-
-#include <nativehelper/JNIHelp.h>
-
-/**
- * Wraps access to the int inside a java.io.FileDescriptor, taking care of throwing exceptions.
- */
-class NetFd {
-public:
-    NetFd(JNIEnv* env, jobject fileDescriptor)
-        : mEnv(env), mFileDescriptor(fileDescriptor), mFd(-1)
-    {
-    }
-
-    bool isClosed() {
-        mFd = jniGetFDFromFileDescriptor(mEnv, mFileDescriptor);
-        bool closed = (mFd == -1);
-        if (closed) {
-            jniThrowException(mEnv, "java/net/SocketException", "Socket closed");
-        }
-        return closed;
-    }
-
-    int get() const {
-        return mFd;
-    }
-
-private:
-    JNIEnv* mEnv;
-    jobject mFileDescriptor;
-    int mFd;
-
-    // Disallow copy and assignment.
-    NetFd(const NetFd&);
-    void operator=(const NetFd&);
-};
-
-/**
- * Used to retry syscalls that can return EINTR. This differs from TEMP_FAILURE_RETRY in that
- * it also considers the case where the reason for failure is that another thread called
- * Socket.close.
- */
-#define NET_FAILURE_RETRY(fd, exp) ({               \
-    typeof (exp) _rc;                               \
-    do {                                            \
-        _rc = (exp);                                \
-        if (_rc == -1) {                            \
-            if (fd.isClosed() || errno != EINTR) {  \
-                break;                              \
-            }                                       \
-        }                                           \
-    } while (_rc == -1);                            \
-    _rc; })
-
-#endif // NET_FD_H_included
diff --git a/luni/src/main/native/NetworkUtilities.cpp b/luni/src/main/native/NetworkUtilities.cpp
index 66daf9c..b765c4e 100644
--- a/luni/src/main/native/NetworkUtilities.cpp
+++ b/luni/src/main/native/NetworkUtilities.cpp
@@ -17,9 +17,6 @@
 #define LOG_TAG "NetworkUtilities"
 
 #include "NetworkUtilities.h"
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
-#include <nativehelper/ScopedLocalRef.h>
 
 #include <arpa/inet.h>
 #include <fcntl.h>
@@ -28,6 +25,11 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "JniConstants.h"
+
 jobject sockaddrToInetAddress(JNIEnv* env, const sockaddr_storage& ss, jint* port) {
     // Convert IPv4-mapped IPv6 addresses to IPv4 addresses.
     // The RI states "Java will never return an IPv4-mapped address".
@@ -79,12 +81,12 @@
     env->SetByteArrayRegion(byteArray.get(), 0, addressLength,
             reinterpret_cast<const jbyte*>(rawAddress));
 
-    static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inetAddressClass,
+    static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::GetInetAddressClass(env),
             "getByAddress", "(Ljava/lang/String;[BI)Ljava/net/InetAddress;");
     if (getByAddressMethod == NULL) {
         return NULL;
     }
-    return env->CallStaticObjectMethod(JniConstants::inetAddressClass, getByAddressMethod,
+    return env->CallStaticObjectMethod(JniConstants::GetInetAddressClass(env), getByAddressMethod,
             NULL, byteArray.get(), scope_id);
 }
 
@@ -98,13 +100,13 @@
     }
 
     // Get holder.
-    static jfieldID holderFid = env->GetFieldID(JniConstants::inetAddressClass, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
+    static jfieldID holderFid = env->GetFieldID(JniConstants::GetInetAddressClass(env), "holder", "Ljava/net/InetAddress$InetAddressHolder;");
     if (holderFid == NULL) {
         return false;
     }
     ScopedLocalRef<jobject> holder(env, env->GetObjectField(inetAddress, holderFid));
     // Get the address family.
-    static jfieldID familyFid = env->GetFieldID(JniConstants::inetAddressHolderClass, "family", "I");
+    static jfieldID familyFid = env->GetFieldID(JniConstants::GetInetAddressHolderClass(env), "family", "I");
     if (familyFid == NULL) {
         return false;
     }
@@ -122,7 +124,7 @@
     }
 
     // Get the byte array that stores the IP address bytes in the InetAddress.
-    static jmethodID bytesMid = env->GetMethodID(JniConstants::inetAddressClass, "getAddress", "()[B");
+    static jmethodID bytesMid = env->GetMethodID(JniConstants::GetInetAddressClass(env), "getAddress", "()[B");
     if (bytesMid == NULL) {
         return false;
     }
@@ -149,14 +151,16 @@
         jbyte* dst = reinterpret_cast<jbyte*>(&sin6.sin6_addr.s6_addr);
         env->GetByteArrayRegion(addressBytes.get(), 0, 16, dst);
         // ...and set the scope id...
-        static jfieldID holder6Fid = env->GetFieldID(JniConstants::inet6AddressClass,
+        static jfieldID holder6Fid = env->GetFieldID(JniConstants::GetInet6AddressClass(env),
                                                      "holder6",
                                                      "Ljava/net/Inet6Address$Inet6AddressHolder;");
         if (holder6Fid == NULL) {
             return false;
         }
         ScopedLocalRef<jobject> holder6(env, env->GetObjectField(inetAddress, holder6Fid));
-        static jfieldID scopeFid = env->GetFieldID(JniConstants::inet6AddressHolderClass, "scope_id", "I");
+        static jfieldID scopeFid = env->GetFieldID(JniConstants::GetInet6AddressHolderClass(env),
+                                                   "scope_id",
+                                                   "I");
         sin6.sin6_scope_id = env->GetIntField(holder6.get(), scopeFid);
         sa_len = sizeof(sockaddr_in6);
         return true;
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index bd8c116..0b4a94a 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -18,12 +18,12 @@
 
 #include <stdlib.h>
 
-#include "log/log.h"
-
-#include <nativehelper/JniConstants.h>
-#include "nativehelper/JniConstants-priv.h"
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedLocalFrame.h>
 
+#include "JniConstants.h"
+
 // DalvikVM calls this on startup, so we can statically register all our native methods.
 jint JNI_OnLoad(JavaVM* vm, void*) {
     JNIEnv* env;
@@ -31,7 +31,6 @@
         ALOGE("JavaVM::GetEnv() failed");
         abort();
     }
-    JniConstants::init(env);
 
     ScopedLocalFrame localFrame(env);
 
@@ -55,26 +54,19 @@
     REGISTER(register_sun_misc_Unsafe);
 #undef REGISTER
 
+    JniConstants::Initialize(env);
     return JNI_VERSION_1_6;
 }
 
-// DalvikVM calls this on shutdown, do any global cleanup here.
-// -- Very important if we restart multiple DalvikVMs in the same process to reset the state.
-void JNI_OnUnload(JavaVM* vm, void*) {
-    JNIEnv* env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        ALOGE("JavaVM::GetEnv() failed");
-        abort();
-    }
+// ART calls this on shutdown, do any global cleanup here.
+// -- Very important if we restart multiple ART runtimes in the same process to reset the state.
+void JNI_OnUnload(JavaVM*, void*) {
+    // Don't use the JavaVM in this method. ART only calls this once all threads are
+    // unregistered.
     ALOGV("libjavacore JNI_OnUnload");
-
-    ScopedLocalFrame localFrame(env);
-
-#define UNREGISTER(FN) extern void FN(JNIEnv*); FN(env)
+#define UNREGISTER(FN) extern void FN(); FN()
     UNREGISTER(unregister_libcore_icu_ICU);
 #undef UNREGISTER
-
-    // Ensure that libnativehelper caching is invalidated, in case a new runtime is to be brought
-    // up later.
-    android::ClearJniConstantsCache();
+    JniConstants::Invalidate();
+    jniUninitializeConstants();
 }
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/ZipUtilities.cpp b/luni/src/main/native/ZipUtilities.cpp
index 9fd32b5..82f8c07 100644
--- a/luni/src/main/native/ZipUtilities.cpp
+++ b/luni/src/main/native/ZipUtilities.cpp
@@ -15,12 +15,11 @@
  * limitations under the License.
  */
 
-#include <memory>
+#include "ZipUtilities.h"
 
-#include <nativehelper/JniConstants.h>
+#include <nativehelper/JNIHelp.h>
 
 #include "JniException.h"
-#include "ZipUtilities.h"
 
 void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int error,
     NativeZipStream* stream) {
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index e373a12..bb19f6e 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -16,10 +16,6 @@
 
 #define LOG_TAG "OsConstants"
 
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
-#include "Portability.h"
-
 #include <errno.h>
 #include <fcntl.h>
 #include <netdb.h>
@@ -57,6 +53,11 @@
 #include <linux/capability.h>
 #endif
 
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/jni_macros.h>
+
+#include "Portability.h"
+
 static void initConstant(JNIEnv* env, jclass c, const char* fieldName, int value) {
     jfieldID field = env->GetStaticFieldID(c, fieldName, "I");
     env->SetStaticIntField(c, field, value);
@@ -385,6 +386,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);
@@ -509,7 +511,9 @@
     initConstant(env, c, "SIOCGIFBRDADDR", SIOCGIFBRDADDR);
     initConstant(env, c, "SIOCGIFDSTADDR", SIOCGIFDSTADDR);
     initConstant(env, c, "SIOCGIFNETMASK", SIOCGIFNETMASK);
+    initConstant(env, c, "SOCK_CLOEXEC", SOCK_CLOEXEC);
     initConstant(env, c, "SOCK_DGRAM", SOCK_DGRAM);
+    initConstant(env, c, "SOCK_NONBLOCK", SOCK_NONBLOCK);
     initConstant(env, c, "SOCK_RAW", SOCK_RAW);
     initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
     initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
diff --git a/luni/src/main/native/java_lang_StringToReal.cpp b/luni/src/main/native/java_lang_StringToReal.cpp
index 7f368b1..7a49285 100644
--- a/luni/src/main/native/java_lang_StringToReal.cpp
+++ b/luni/src/main/native/java_lang_StringToReal.cpp
@@ -18,10 +18,13 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
+
 #include "cbigint.h"
+
 #include "JniException.h"
 
 /* ************************* Defines ************************* */
diff --git a/luni/src/main/native/java_lang_invoke_MethodHandle.cpp b/luni/src/main/native/java_lang_invoke_MethodHandle.cpp
index 4574f59..0441d45 100644
--- a/luni/src/main/native/java_lang_invoke_MethodHandle.cpp
+++ b/luni/src/main/native/java_lang_invoke_MethodHandle.cpp
@@ -14,17 +14,19 @@
  * limitations under the License.
  */
 
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/JNIHelp.h>
+#include <nativehelper/jni_macros.h>
 
-static void MethodHandle_invokeExact(JNIEnv* env, jobject, jobjectArray) {
+static jobject MethodHandle_invokeExact(JNIEnv* env, jobject, jobjectArray) {
     jniThrowException(env, "java/lang/UnsupportedOperationException",
             "MethodHandle.invokeExact cannot be invoked reflectively.");
+    return nullptr;
 }
 
-static void MethodHandle_invoke(JNIEnv* env, jobject, jobjectArray) {
+static jobject MethodHandle_invoke(JNIEnv* env, jobject, jobjectArray) {
     jniThrowException(env, "java/lang/UnsupportedOperationException",
             "MethodHandle.invoke cannot be invoked reflectively.");
+    return nullptr;
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/luni/src/main/native/java_lang_invoke_VarHandle.cpp b/luni/src/main/native/java_lang_invoke_VarHandle.cpp
index 46ea8ff..e1cc1c7 100644
--- a/luni/src/main/native/java_lang_invoke_VarHandle.cpp
+++ b/luni/src/main/native/java_lang_invoke_VarHandle.cpp
@@ -14,18 +14,8 @@
  * limitations under the License.
  */
 
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/JNIHelp.h>
-
-/** Signature for VarHandle access mode methods with a void return type. */
-static const char* kVarHandleVoidSignature = "([Ljava/lang/Object;)V";
-
-/** Signature for VarHandle access mode methods returning an object reference. */
-static const char* kVarHandleBooleanSignature = "([Ljava/lang/Object;)Z";
-
-/** Signature for VarHandle access mode methods returning a boolean value. */
-static const char* kVarHandleObjectSignature = "([Ljava/lang/Object;)Ljava/lang/Object;";
-
+#include <nativehelper/jni_macros.h>
 
 static void ThrowUnsupportedOperationForAccessMode(JNIEnv* env, const char* accessMode) {
   // VarHandle access mode methods should be dispatched by the
@@ -38,119 +28,142 @@
                        accessMode);
 }
 
-static void VarHandle_compareAndExchange(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_compareAndExchange(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchange");
+  return nullptr;
 }
 
-static void VarHandle_compareAndExchangeAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_compareAndExchangeAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeAcquire");
+  return nullptr;
 }
 
-static void VarHandle_compareAndExchangeRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_compareAndExchangeRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeRelease");
+  return nullptr;
 }
 
-static void VarHandle_compareAndSet(JNIEnv* env, jobject, jobjectArray) {
+static jboolean VarHandle_compareAndSet(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "compareAndSet");
+  return JNI_FALSE;
 }
 
-static void VarHandle_get(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_get(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "get");
+  return nullptr;
 }
 
-static void VarHandle_getAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndAdd(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndAdd(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndAdd");
+  return nullptr;
 }
 
-static void VarHandle_getAndAddAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndAddAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndAddAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndAddRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndAddRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndAddRelease");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseAnd(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseAnd(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAnd");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseAndAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseAndAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseAndRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseAndRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndRelease");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseOr(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseOr(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOr");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseOrAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseOrAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseOrRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseOrRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrRelease");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseXor(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseXor(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXor");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseXorAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseXorAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndBitwiseXorRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndBitwiseXorRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorRelease");
+  return nullptr;
 }
 
-static void VarHandle_getAndSet(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndSet(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndSet");
+  return nullptr;
 }
 
-static void VarHandle_getAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndSetAcquire");
+  return nullptr;
 }
 
-static void VarHandle_getAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getAndSetRelease");
+  return nullptr;
 }
 
-static void VarHandle_getOpaque(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getOpaque(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getOpaque");
+  return nullptr;
 }
 
-static void VarHandle_getVolatile(JNIEnv* env, jobject, jobjectArray) {
+static jobject VarHandle_getVolatile(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "getVolatile");
+  return nullptr;
 }
 
 static void VarHandle_set(JNIEnv* env, jobject, jobjectArray) {
@@ -173,58 +186,62 @@
   ThrowUnsupportedOperationForAccessMode(env, "setVolatile");
 }
 
-static void VarHandle_weakCompareAndSet(JNIEnv* env, jobject, jobjectArray) {
+static jboolean VarHandle_weakCompareAndSet(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSet");
+  return JNI_FALSE;
 }
 
-static void VarHandle_weakCompareAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
+static jboolean VarHandle_weakCompareAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetAcquire");
+  return JNI_FALSE;
 }
 
-static void VarHandle_weakCompareAndSetPlain(JNIEnv* env, jobject, jobjectArray) {
+static jboolean VarHandle_weakCompareAndSetPlain(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetPlain");
+  return JNI_FALSE;
 }
 
-static void VarHandle_weakCompareAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
+static jboolean VarHandle_weakCompareAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetRelease");
+  return JNI_FALSE;
 }
 
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(VarHandle, compareAndExchange, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, compareAndExchangeAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, compareAndExchangeRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, compareAndSet, kVarHandleBooleanSignature),
-  NATIVE_METHOD(VarHandle, get, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndAdd, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndAddAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndAddRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseAnd, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseAndAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseAndRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseOr, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseOrAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseOrRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseXor, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseXorAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndBitwiseXorRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndSet, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndSetAcquire, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getAndSetRelease, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getOpaque, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, getVolatile, kVarHandleObjectSignature),
-  NATIVE_METHOD(VarHandle, set, kVarHandleVoidSignature),
-  NATIVE_METHOD(VarHandle, setOpaque, kVarHandleVoidSignature),
-  NATIVE_METHOD(VarHandle, setRelease, kVarHandleVoidSignature),
-  NATIVE_METHOD(VarHandle, setVolatile, kVarHandleVoidSignature),
-  NATIVE_METHOD(VarHandle, weakCompareAndSet, kVarHandleBooleanSignature),
-  NATIVE_METHOD(VarHandle, weakCompareAndSetAcquire, kVarHandleBooleanSignature),
-  NATIVE_METHOD(VarHandle, weakCompareAndSetPlain, kVarHandleBooleanSignature),
-  NATIVE_METHOD(VarHandle, weakCompareAndSetRelease, kVarHandleBooleanSignature),
+  NATIVE_METHOD(VarHandle, compareAndExchange, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, compareAndExchangeAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, compareAndExchangeRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, compareAndSet, "([Ljava/lang/Object;)Z"),
+  NATIVE_METHOD(VarHandle, get, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndAdd, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndAddAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndAddRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseAnd, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseAndAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseAndRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseOr, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseOrAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseOrRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseXor, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseXorAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndBitwiseXorRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndSet, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndSetAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getAndSetRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getOpaque, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, getVolatile, "([Ljava/lang/Object;)Ljava/lang/Object;"),
+  NATIVE_METHOD(VarHandle, set, "([Ljava/lang/Object;)V"),
+  NATIVE_METHOD(VarHandle, setOpaque, "([Ljava/lang/Object;)V"),
+  NATIVE_METHOD(VarHandle, setRelease, "([Ljava/lang/Object;)V"),
+  NATIVE_METHOD(VarHandle, setVolatile, "([Ljava/lang/Object;)V"),
+  NATIVE_METHOD(VarHandle, weakCompareAndSet, "([Ljava/lang/Object;)Z"),
+  NATIVE_METHOD(VarHandle, weakCompareAndSetAcquire, "([Ljava/lang/Object;)Z"),
+  NATIVE_METHOD(VarHandle, weakCompareAndSetPlain, "([Ljava/lang/Object;)Z"),
+  NATIVE_METHOD(VarHandle, weakCompareAndSetRelease, "([Ljava/lang/Object;)Z"),
 };
 
 void register_java_lang_invoke_VarHandle(JNIEnv* env) {
diff --git a/luni/src/main/native/java_math_NativeBN.cpp b/luni/src/main/native/java_math_NativeBN.cpp
index 066f77e..5d085ec 100644
--- a/luni/src/main/native/java_math_NativeBN.cpp
+++ b/luni/src/main/native/java_math_NativeBN.cpp
@@ -16,19 +16,21 @@
 
 #define LOG_TAG "NativeBN"
 
-#include "JniException.h"
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
-#include <nativehelper/ScopedPrimitiveArray.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
 #include <stdio.h>
 #include <algorithm>
 #include <memory>
 
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
+
+#include "JniException.h"
+
 struct BN_CTX_Deleter {
   void operator()(BN_CTX* p) const {
     BN_CTX_free(p);
@@ -409,21 +411,21 @@
   }
 }
 
-static void NativeBN_BN_add_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) {
+static void NativeBN_BN_add_word(JNIEnv* env, jclass, jlong a, jint w) {
   if (!oneValidHandle(env, a)) return;
   if (!BN_add_word(toBigNum(a), w)) {
     throwException(env);
   }
 }
 
-static void NativeBN_BN_mul_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) {
+static void NativeBN_BN_mul_word(JNIEnv* env, jclass, jlong a, jint w) {
   if (!oneValidHandle(env, a)) return;
   if (!BN_mul_word(toBigNum(a), w)) {
     throwException(env);
   }
 }
 
-static BN_ULONG NativeBN_BN_mod_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) {
+static jint NativeBN_BN_mod_word(JNIEnv* env, jclass, jlong a, jint w) {
   if (!oneValidHandle(env, a)) return 0;
   BN_ULONG result = BN_mod_word(toBigNum(a), w);
   if (result == (BN_ULONG)-1) {
diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp
index 11af4bd..12fb764 100644
--- a/luni/src/main/native/java_util_regex_Matcher.cpp
+++ b/luni/src/main/native/java_util_regex_Matcher.cpp
@@ -21,14 +21,13 @@
 
 #include <android-base/logging.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedStringChars.h>
+#include <nativehelper/jni_macros.h>
 
 #include "IcuUtilities.h"
 #include "JniException.h"
 #include "ScopedJavaUnicodeString.h"
-#include "jni.h"
 #include "unicode/parseerr.h"
 #include "unicode/regex.h"
 
@@ -158,28 +157,26 @@
     return reinterpret_cast<jlong>(&Matcher_free);
 }
 
-// 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.
-}
-
-static jint Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jint startIndex, jintArray offsets) {
+static jboolean Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jint startIndex, jintArray offsets) {
     MatcherState* state = toMatcherState(addr);
     UBool result = state->matcher()->find(startIndex, state->status());
     if (result) {
         state->updateOffsets(env, offsets);
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
     }
-    return result;
 }
 
-static jint Matcher_findNextImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
+static jboolean Matcher_findNextImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
     MatcherState* state = toMatcherState(addr);
     UBool result = state->matcher()->find();
     if (result) {
         state->updateOffsets(env, offsets);
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
     }
-    return result;
 }
 
 static jint Matcher_groupCountImpl(JNIEnv*, jclass, jlong addr) {
@@ -187,27 +184,35 @@
     return state->matcher()->groupCount();
 }
 
-static jint Matcher_hitEndImpl(JNIEnv*, jclass, jlong addr) {
+static jboolean Matcher_hitEndImpl(JNIEnv*, jclass, jlong addr) {
     MatcherState* state = toMatcherState(addr);
-    return state->matcher()->hitEnd();
+    if (state->matcher()->hitEnd() != 0) {
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
+    }
 }
 
-static jint Matcher_lookingAtImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
+static jboolean Matcher_lookingAtImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
     MatcherState* state = toMatcherState(addr);
     UBool result = state->matcher()->lookingAt(state->status());
     if (result) {
         state->updateOffsets(env, offsets);
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
     }
-    return result;
 }
 
-static jint Matcher_matchesImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
+static jboolean Matcher_matchesImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) {
     MatcherState* state = toMatcherState(addr);
     UBool result = state->matcher()->matches(state->status());
     if (result) {
         state->updateOffsets(env, offsets);
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
     }
-    return result;
 }
 
 static jlong Matcher_openImpl(JNIEnv* env, jclass, jlong patternAddr) {
@@ -221,9 +226,13 @@
     return reinterpret_cast<uintptr_t>(new MatcherState(result));
 }
 
-static jint Matcher_requireEndImpl(JNIEnv*, jclass, jlong addr) {
+static jboolean Matcher_requireEndImpl(JNIEnv*, jclass, jlong addr) {
     MatcherState* state = toMatcherState(addr);
-    return state->matcher()->requireEnd();
+    if (state->matcher()->requireEnd() != 0) {
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
+    }
 }
 
 static void Matcher_setInputImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jint start, jint end) {
@@ -269,7 +278,6 @@
     NATIVE_METHOD(Matcher, hitEndImpl, "(J)Z"),
     NATIVE_METHOD(Matcher, lookingAtImpl, "(J[I)Z"),
     NATIVE_METHOD(Matcher, matchesImpl, "(J[I)Z"),
-    NATIVE_METHOD(Matcher, nativeSize, "()I"),
     NATIVE_METHOD(Matcher, openImpl, "(J)J"),
     NATIVE_METHOD(Matcher, requireEndImpl, "(J)Z"),
     NATIVE_METHOD(Matcher, setInputImpl, "(JLjava/lang/String;II)V"),
diff --git a/luni/src/main/native/java_util_regex_Pattern.cpp b/luni/src/main/native/java_util_regex_Pattern.cpp
index f4d23cb..a893bab 100644
--- a/luni/src/main/native/java_util_regex_Pattern.cpp
+++ b/luni/src/main/native/java_util_regex_Pattern.cpp
@@ -19,12 +19,14 @@
 #include <stdlib.h>
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
-#include "ScopedJavaUnicodeString.h"
-#include "jni.h"
+#include <nativehelper/jni_macros.h>
+
 #include "unicode/parseerr.h"
 #include "unicode/regex.h"
 
+#include "JniConstants.h"
+#include "ScopedJavaUnicodeString.h"
+
 // ICU documentation: http://icu-project.org/apiref/icu4c/classRegexPattern.html
 
 static const char* regexDetailMessage(UErrorCode status) {
@@ -59,10 +61,10 @@
 }
 
 static void throwPatternSyntaxException(JNIEnv* env, UErrorCode status, jstring pattern, UParseError error) {
-    static jmethodID method = env->GetMethodID(JniConstants::patternSyntaxExceptionClass,
+    static jmethodID method = env->GetMethodID(JniConstants::GetPatternSyntaxExceptionClass(env),
             "<init>", "(Ljava/lang/String;Ljava/lang/String;I)V");
     jstring message = env->NewStringUTF(regexDetailMessage(status));
-    jclass exceptionClass = JniConstants::patternSyntaxExceptionClass;
+    jclass exceptionClass = JniConstants::GetPatternSyntaxExceptionClass(env);
     jobject exception = env->NewObject(exceptionClass, method, message, pattern, error.offset);
     env->Throw(reinterpret_cast<jthrowable>(exception));
 }
@@ -75,12 +77,6 @@
     return reinterpret_cast<jlong>(&Pattern_free);
 }
 
-// Return a guess of the amount of native memory to be deallocated by a typical call to
-// Pattern_free().
-static jint Pattern_nativeSize(JNIEnv*, jclass) {
-    return 500;  // Very rough guess based on a quick look at the implementation.
-}
-
 static jlong Pattern_compileImpl(JNIEnv* env, jclass, jstring javaRegex, jint flags) {
     flags |= UREGEX_ERROR_ON_UNKNOWN_ESCAPES;
 
@@ -103,7 +99,6 @@
 static JNINativeMethod gMethods[] = {
     NATIVE_METHOD(Pattern, compileImpl, "(Ljava/lang/String;I)J"),
     NATIVE_METHOD(Pattern, getNativeFinalizer, "()J"),
-    NATIVE_METHOD(Pattern, nativeSize, "()I"),
 };
 
 void register_java_util_regex_Pattern(JNIEnv* env) {
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index 48f1ba2..8a571fd 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -35,12 +35,13 @@
 #include <android-base/unique_fd.h>
 #include <log/log.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
 #include <nativehelper/toStringArray.h>
 
 #include "IcuUtilities.h"
+#include "JniConstants.h"
 #include "JniException.h"
 #include "ScopedIcuLocale.h"
 #include "ScopedJavaUnicodeString.h"
@@ -328,24 +329,24 @@
 static bool setIntegerField(JNIEnv* env, jobject obj, const char* fieldName, int value) {
     ScopedLocalRef<jobject> integerValue(env, integerValueOf(env, value));
     if (integerValue.get() == NULL) return false;
-    jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "Ljava/lang/Integer;");
+    jfieldID fid = env->GetFieldID(JniConstants::GetLocaleDataClass(env), fieldName, "Ljava/lang/Integer;");
     env->SetObjectField(obj, fid, integerValue.get());
     return true;
 }
 
 static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, jstring value) {
-    jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "Ljava/lang/String;");
+    jfieldID fid = env->GetFieldID(JniConstants::GetLocaleDataClass(env), fieldName, "Ljava/lang/String;");
     env->SetObjectField(obj, fid, value);
     env->DeleteLocalRef(value);
 }
 
 static void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, jobjectArray value) {
-    jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "[Ljava/lang/String;");
+    jfieldID fid = env->GetFieldID(JniConstants::GetLocaleDataClass(env), fieldName, "[Ljava/lang/String;");
     env->SetObjectField(obj, fid, value);
 }
 
 static void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString* valueArray, int32_t size) {
-    ScopedLocalRef<jobjectArray> result(env, env->NewObjectArray(size, JniConstants::stringClass, NULL));
+    ScopedLocalRef<jobjectArray> result(env, env->NewObjectArray(size, JniConstants::GetStringClass(env), NULL));
     for (int32_t i = 0; i < size ; i++) {
         ScopedLocalRef<jstring> s(env, jniCreateString(env, valueArray[i].getBuffer(),valueArray[i].length()));
         if (env->ExceptionCheck()) {
@@ -389,7 +390,7 @@
     if (value.length() == 0) {
         return;
     }
-    jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "C");
+    jfieldID fid = env->GetFieldID(JniConstants::GetLocaleDataClass(env), fieldName, "C");
     env->SetCharField(obj, fid, value.charAt(0));
 }
 
@@ -761,7 +762,7 @@
   return env->NewStringUTF(version);
 }
 
-static jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) {
+static jobjectArray ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) {
   UErrorCode status = U_ZERO_ERROR;
   icu::UStringEnumeration e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status));
   return fromStringEnumeration(env, status, "ucurr_openISOCurrencies", &e);
@@ -949,25 +950,40 @@
     // Tell ICU it can *only* use our memory-mapped data.
     udata_setFileAccess(UDATA_NO_FILES, &status);
     if (status != U_ZERO_ERROR) {
-        ALOGE("Couldn't initialize ICU (s_setFileAccess): %s", u_errorName(status)); 
+        ALOGE("Couldn't initialize ICU (s_setFileAccess): %s", u_errorName(status));
         abort();
     }
 
-    std::string dataPath = getTzDataOverridePath();
-
-    // Map in optional TZ data files.
-    struct stat sb;
-    if (stat(dataPath.c_str(), &sb) == 0) {
-        ALOGD("Timezone override file found: %s", dataPath.c_str());
+    // Check the timezone /data override file exists from the "Time zone update via APK" feature.
+    // https://source.android.com/devices/tech/config/timezone-rules
+    // If it does, map it first so we use its data in preference to later ones.
+    std::string dataPath = getDataTimeZonePath();
+    if (pathExists(dataPath)) {
+        ALOGD("Time zone override file found: %s", dataPath.c_str());
         if ((icu_datamap_from_data_ = IcuDataMap::Create(dataPath)) == nullptr) {
-            ALOGW("TZ override file %s exists but could not be loaded. Skipping.", dataPath.c_str());
+            ALOGW("TZ override /data file %s exists but could not be loaded. Skipping.",
+                    dataPath.c_str());
         }
     } else {
-        ALOGV("No timezone override file found: %s", dataPath.c_str());
+        ALOGV("No timezone override /data file found: %s", dataPath.c_str());
     }
 
-    // Use the ICU data files that shipped with the device for everything else.
-    if ((icu_datamap_from_system_ = IcuDataMap::Create(getSystemPath())) == nullptr) {
+    // Check the timezone override file exists from a mounted APEX file.
+    // If it does, map it next so we use its data in preference to later ones.
+    std::string tzModulePath = getTimeZoneModulePath();
+    if (pathExists(tzModulePath)) {
+        ALOGD("Time zone APEX file found: %s", tzModulePath.c_str());
+        if ((icu_datamap_from_tz_module_ = IcuDataMap::Create(tzModulePath)) == nullptr) {
+            ALOGW("TZ module override file %s exists but could not be loaded. Skipping.",
+                    tzModulePath.c_str());
+        }
+    } else {
+        ALOGV("No time zone module override file found: %s", tzModulePath.c_str());
+    }
+
+    // Use the ICU data files that shipped with the runtime module for everything else.
+    icu_datamap_from_runtime_module_ = IcuDataMap::Create(getRuntimeModulePath());
+    if (icu_datamap_from_runtime_module_ == nullptr) {
         abort();
     }
 
@@ -990,18 +1006,25 @@
     // Reset libicu state to before it was loaded.
     u_cleanup();
 
-    // Unmap ICU data files that shipped with the device for everything else.
-    icu_datamap_from_system_.reset();
+    // Unmap ICU data files from the runtime module.
+    icu_datamap_from_runtime_module_.reset();
 
-    // Unmap optional TZ data files.
+    // Unmap optional TZ module files from /apex.
+    icu_datamap_from_tz_module_.reset();
+
+    // Unmap optional TZ /data file.
     icu_datamap_from_data_.reset();
 
     // We don't need to call udata_setFileAccess because u_cleanup takes care of it.
   }
 
-  // Check the timezone override file exists. If it does, map it first so we use it in preference
-  // to the one that shipped with the device.
-  static std::string getTzDataOverridePath() {
+  static bool pathExists(const std::string path) {
+    struct stat sb;
+    return stat(path.c_str(), &sb) == 0;
+  }
+
+  // Returns a string containing the expected path of the (optional) /data tz data file
+  static std::string getDataTimeZonePath() {
     const char* dataPathPrefix = getenv("ANDROID_DATA");
     if (dataPathPrefix == NULL) {
       ALOGE("ANDROID_DATA environment variable not set"); \
@@ -1014,23 +1037,38 @@
     return dataPath;
   }
 
-  static std::string getSystemPath() {
-    const char* systemPathPrefix = getenv("ANDROID_ROOT");
-    if (systemPathPrefix == NULL) {
-      ALOGE("ANDROID_ROOT environment variable not set"); \
+  // Returns a string containing the expected path of the (optional) /apex tz module data file
+  static std::string getTimeZoneModulePath() {
+    const char* tzdataModulePathPrefix = getenv("ANDROID_TZDATA_ROOT");
+    if (tzdataModulePathPrefix == NULL) {
+      ALOGE("ANDROID_TZDATA_ROOT environment variable not set"); \
       abort();
     }
 
-    std::string systemPath;
-    systemPath = systemPathPrefix;
-    systemPath += "/usr/icu/";
-    systemPath += U_ICUDATA_NAME;
-    systemPath += ".dat";
-    return systemPath;
+    std::string tzdataModulePath;
+    tzdataModulePath = tzdataModulePathPrefix;
+    tzdataModulePath += "/etc/icu/icu_tzdata.dat";
+    return tzdataModulePath;
+  }
+
+  static std::string getRuntimeModulePath() {
+    const char* runtimeModulePathPrefix = getenv("ANDROID_RUNTIME_ROOT");
+    if (runtimeModulePathPrefix == NULL) {
+      ALOGE("ANDROID_RUNTIME_ROOT environment variable not set"); \
+      abort();
+    }
+
+    std::string runtimeModulePath;
+    runtimeModulePath = runtimeModulePathPrefix;
+    runtimeModulePath += "/etc/icu/";
+    runtimeModulePath += U_ICUDATA_NAME;
+    runtimeModulePath += ".dat";
+    return runtimeModulePath;
   }
 
   std::unique_ptr<IcuDataMap> icu_datamap_from_data_;
-  std::unique_ptr<IcuDataMap> icu_datamap_from_system_;
+  std::unique_ptr<IcuDataMap> icu_datamap_from_tz_module_;
+  std::unique_ptr<IcuDataMap> icu_datamap_from_runtime_module_;
 };
 
 // Use RAII-style initialization/teardown so that we can get unregistered
@@ -1043,7 +1081,7 @@
 }
 
 // De-init ICU, unloading the data files. Do the opposite of the above function.
-void unregister_libcore_icu_ICU(JNIEnv*) {
+void unregister_libcore_icu_ICU() {
   // Explicitly calling this is optional. Dlclose will take care of it as well.
   sIcuRegistration.reset();
 }
diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp
index b98c79c..9ccfabd 100644
--- a/luni/src/main/native/libcore_icu_NativeConverter.cpp
+++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp
@@ -23,14 +23,15 @@
 
 #include <android/log.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedStringChars.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
 #include <nativehelper/toStringArray.h>
 
 #include "IcuUtilities.h"
+#include "JniConstants.h"
 #include "JniException.h"
 #include "unicode/ucnv.h"
 #include "unicode/ucnv_cb.h"
@@ -351,7 +352,7 @@
 
 static jobjectArray NativeConverter_getAvailableCharsetNames(JNIEnv* env, jclass) {
     int32_t num = ucnv_countAvailable();
-    jobjectArray result = env->NewObjectArray(num, JniConstants::stringClass, NULL);
+    jobjectArray result = env->NewObjectArray(num, JniConstants::GetStringClass(env), NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -645,7 +646,7 @@
     }
 
     // Construct the CharsetICU object.
-    static jmethodID charsetConstructor = env->GetMethodID(JniConstants::charsetICUClass, "<init>",
+    static jmethodID charsetConstructor = env->GetMethodID(JniConstants::GetCharsetICUClass(env), "<init>",
             "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
     if (env->ExceptionCheck()) {
         return NULL;
@@ -657,7 +658,7 @@
         return NULL;
     }
 
-    return env->NewObject(JniConstants::charsetICUClass, charsetConstructor,
+    return env->NewObject(JniConstants::GetCharsetICUClass(env), charsetConstructor,
             javaCanonicalName, versionedIcuCanonicalNameStr, javaAliases);
 }
 
@@ -669,8 +670,7 @@
     return reinterpret_cast<jlong>(&FreeNativeConverter);
 }
 
-
-static jlong NativeConverter_getNativeSize(JNIEnv*, jclass, jstring) {
+static jlong NativeConverter_getNativeSize(JNIEnv*, jclass) {
     // TODO: Improve estimate.
     return 200;
 }
diff --git a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
index cea595d..db4c6f2 100644
--- a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
+++ b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
@@ -19,9 +19,9 @@
 #include <memory>
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
 
 #include "IcuUtilities.h"
 #include "JniException.h"
diff --git a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
index bf2d3a8..55803b8 100644
--- a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
+++ b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
@@ -16,11 +16,10 @@
 
 #define LOG_TAG "AsynchronousCloseMonitor"
 
-#include <nativehelper/AsynchronousCloseMonitor.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
+#include <nativehelper/jni_macros.h>
 
-#include "jni.h"
+#include "AsynchronousCloseMonitor.h"
 
 static void AsynchronousCloseMonitor_signalBlockedThreads(JNIEnv* env, jclass, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index 30da35c..6b8ee08 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -49,20 +49,26 @@
 
 #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>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedBytes.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
 #include <nativehelper/toStringArray.h>
 
+#include "AsynchronousCloseMonitor.h"
 #include "ExecStrings.h"
+#include "JniConstants.h"
 #include "JniException.h"
 #include "NetworkUtilities.h"
 #include "Portability.h"
@@ -250,18 +256,20 @@
 
 static void throwErrnoException(JNIEnv* env, const char* functionName) {
     int error = errno;
-    static jmethodID ctor3 = env->GetMethodID(JniConstants::errnoExceptionClass,
+    jclass errnoExceptionClass = JniConstants::GetErrnoExceptionClass(env);
+    static jmethodID ctor3 = env->GetMethodID(errnoExceptionClass,
             "<init>", "(Ljava/lang/String;ILjava/lang/Throwable;)V");
-    static jmethodID ctor2 = env->GetMethodID(JniConstants::errnoExceptionClass,
+    static jmethodID ctor2 = env->GetMethodID(errnoExceptionClass,
             "<init>", "(Ljava/lang/String;I)V");
-    throwException(env, JniConstants::errnoExceptionClass, ctor3, ctor2, functionName, error);
+    throwException(env, errnoExceptionClass, ctor3, ctor2, functionName, error);
 }
 
 static void throwGaiException(JNIEnv* env, const char* functionName, int error) {
+  jclass gaiExceptionClass = JniConstants::GetGaiExceptionClass(env);
   // Cache the methods ids before we throw, so we don't call GetMethodID with a pending exception.
-  static jmethodID ctor3 = env->GetMethodID(JniConstants::gaiExceptionClass, "<init>",
+  static jmethodID ctor3 = env->GetMethodID(gaiExceptionClass, "<init>",
                                             "(Ljava/lang/String;ILjava/lang/Throwable;)V");
-  static jmethodID ctor2 = env->GetMethodID(JniConstants::gaiExceptionClass, "<init>",
+  static jmethodID ctor2 = env->GetMethodID(gaiExceptionClass, "<init>",
                                             "(Ljava/lang/String;I)V");
   if (errno != 0) {
         // EAI_SYSTEM should mean "look at errno instead", but both glibc and bionic seem to
@@ -272,7 +280,7 @@
         throwErrnoException(env, functionName);
         // Deliberately fall through to throw another exception...
     }
-    throwException(env, JniConstants::gaiExceptionClass, ctor3, ctor2, functionName, error);
+    throwException(env, gaiExceptionClass, ctor3, ctor2, functionName, error);
 }
 
 template <typename rc_t>
@@ -380,14 +388,14 @@
         if (inetAddress == NULL) {
             return NULL;  // Exception already thrown.
         }
-        static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass,
+        static jmethodID ctor = env->GetMethodID(JniConstants::GetInetSocketAddressClass(env),
                 "<init>", "(Ljava/net/InetAddress;I)V");
         if (ctor == NULL) {
             return NULL;
         }
-        return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port);
+        return env->NewObject(JniConstants::GetInetSocketAddressClass(env), ctor, inetAddress, port);
     } else if (ss.ss_family == AF_UNIX) {
-        static jmethodID ctor = env->GetMethodID(JniConstants::unixSocketAddressClass,
+        static jmethodID ctor = env->GetMethodID(JniConstants::GetUnixSocketAddressClass(env),
                 "<init>", "([B)V");
         if (ctor == NULL) {
             return NULL;
@@ -396,20 +404,20 @@
         if (!javaSunPath) {
             return NULL;
         }
-        return env->NewObject(JniConstants::unixSocketAddressClass, ctor, javaSunPath);
+        return env->NewObject(JniConstants::GetUnixSocketAddressClass(env), ctor, javaSunPath);
     } else if (ss.ss_family == AF_NETLINK) {
         const struct sockaddr_nl* nl_addr = reinterpret_cast<const struct sockaddr_nl*>(&ss);
-        static jmethodID ctor = env->GetMethodID(JniConstants::netlinkSocketAddressClass,
+        static jmethodID ctor = env->GetMethodID(JniConstants::GetNetlinkSocketAddressClass(env),
                 "<init>", "(II)V");
         if (ctor == NULL) {
             return NULL;
         }
-        return env->NewObject(JniConstants::netlinkSocketAddressClass, ctor,
+        return env->NewObject(JniConstants::GetNetlinkSocketAddressClass(env), ctor,
                 static_cast<jint>(nl_addr->nl_pid),
                 static_cast<jint>(nl_addr->nl_groups));
     } else if (ss.ss_family == AF_PACKET) {
         const struct sockaddr_ll* sll = reinterpret_cast<const struct sockaddr_ll*>(&ss);
-        static jmethodID ctor = env->GetMethodID(JniConstants::packetSocketAddressClass,
+        static jmethodID ctor = env->GetMethodID(JniConstants::GetPacketSocketAddressClass(env),
                 "<init>", "(SISB[B)V");
         if (ctor == NULL) {
             return NULL;
@@ -420,7 +428,7 @@
         }
         env->SetByteArrayRegion(byteArray.get(), 0, sll->sll_halen,
                 reinterpret_cast<const jbyte*>(sll->sll_addr));
-        jobject packetSocketAddress = env->NewObject(JniConstants::packetSocketAddressClass, ctor,
+        jobject packetSocketAddress = env->NewObject(JniConstants::GetPacketSocketAddressClass(env), ctor,
                 static_cast<jshort>(ntohs(sll->sll_protocol)),
                 static_cast<jint>(sll->sll_ifindex),
                 static_cast<jshort>(sll->sll_hatype),
@@ -437,27 +445,27 @@
     TO_JAVA_STRING(pw_name, pw.pw_name);
     TO_JAVA_STRING(pw_dir, pw.pw_dir);
     TO_JAVA_STRING(pw_shell, pw.pw_shell);
-    static jmethodID ctor = env->GetMethodID(JniConstants::structPasswdClass, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructPasswdClass(env), "<init>",
             "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structPasswdClass, ctor,
+    return env->NewObject(JniConstants::GetStructPasswdClass(env), ctor,
             pw_name, static_cast<jint>(pw.pw_uid), static_cast<jint>(pw.pw_gid), pw_dir, pw_shell);
 }
 
 static jobject makeStructTimespec(JNIEnv* env, const struct timespec& ts) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structTimespecClass, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructTimespecClass(env), "<init>",
             "(JJ)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structTimespecClass, ctor,
+    return env->NewObject(JniConstants::GetStructTimespecClass(env), ctor,
             static_cast<jlong>(ts.tv_sec), static_cast<jlong>(ts.tv_nsec));
 }
 
 static jobject makeStructStat(JNIEnv* env, const struct stat64& sb) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structStatClass, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructStatClass(env), "<init>",
             "(JJIJIIJJLandroid/system/StructTimespec;Landroid/system/StructTimespec;Landroid/system/StructTimespec;JJ)V");
     if (ctor == NULL) {
         return NULL;
@@ -476,7 +484,7 @@
         return NULL;
     }
 
-    return env->NewObject(JniConstants::structStatClass, ctor,
+    return env->NewObject(JniConstants::GetStructStatClass(env), ctor,
             static_cast<jlong>(sb.st_dev), static_cast<jlong>(sb.st_ino),
             static_cast<jint>(sb.st_mode), static_cast<jlong>(sb.st_nlink),
             static_cast<jint>(sb.st_uid), static_cast<jint>(sb.st_gid),
@@ -486,13 +494,13 @@
 }
 
 static jobject makeStructStatVfs(JNIEnv* env, const struct statvfs& sb) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structStatVfsClass, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructStatVfsClass(env), "<init>",
             "(JJJJJJJJJJJ)V");
     if (ctor == NULL) {
         return NULL;
     }
 
-    return env->NewObject(JniConstants::structStatVfsClass, ctor,
+    return env->NewObject(JniConstants::GetStructStatVfsClass(env), ctor,
                           static_cast<jlong>(sb.f_bsize),
                           static_cast<jlong>(sb.f_frsize),
                           static_cast<jlong>(sb.f_blocks),
@@ -507,28 +515,28 @@
 }
 
 static jobject makeStructLinger(JNIEnv* env, const struct linger& l) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structLingerClass, "<init>", "(II)V");
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructLingerClass(env), "<init>", "(II)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structLingerClass, ctor, l.l_onoff, l.l_linger);
+    return env->NewObject(JniConstants::GetStructLingerClass(env), ctor, l.l_onoff, l.l_linger);
 }
 
 static jobject makeStructTimeval(JNIEnv* env, const struct timeval& tv) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structTimevalClass, "<init>", "(JJ)V");
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructTimevalClass(env), "<init>", "(JJ)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structTimevalClass, ctor,
+    return env->NewObject(JniConstants::GetStructTimevalClass(env), ctor,
             static_cast<jlong>(tv.tv_sec), static_cast<jlong>(tv.tv_usec));
 }
 
 static jobject makeStructUcred(JNIEnv* env, const struct ucred& u __unused) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structUcredClass, "<init>", "(III)V");
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructUcredClass(env), "<init>", "(III)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structUcredClass, ctor, u.pid, u.uid, u.gid);
+    return env->NewObject(JniConstants::GetStructUcredClass(env), ctor, u.pid, u.uid, u.gid);
 }
 
 static jobject makeStructUtsname(JNIEnv* env, const struct utsname& buf) {
@@ -537,12 +545,12 @@
     TO_JAVA_STRING(release, buf.release);
     TO_JAVA_STRING(version, buf.version);
     TO_JAVA_STRING(machine, buf.machine);
-    static jmethodID ctor = env->GetMethodID(JniConstants::structUtsnameClass, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructUtsnameClass(env), "<init>",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
     if (ctor == NULL) {
         return NULL;
     }
-    return env->NewObject(JniConstants::structUtsnameClass, ctor,
+    return env->NewObject(JniConstants::GetStructUtsnameClass(env), ctor,
             sysname, nodename, release, version, machine);
 };
 
@@ -568,7 +576,7 @@
     }
 
     static jfieldID sunPathFid =
-            env->GetFieldID(JniConstants::unixSocketAddressClass, "sun_path", "[B");
+        env->GetFieldID(JniConstants::GetUnixSocketAddressClass(env), "sun_path", "[B");
     env->SetObjectField(javaUnixSocketAddress, sunPathFid, javaSunPath);
     return true;
 }
@@ -584,13 +592,13 @@
     if (sender == NULL) {
         return false;
     }
-    static jfieldID holderFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "holder",
+    static jfieldID holderFid = env->GetFieldID(JniConstants::GetInetSocketAddressClass(env), "holder",
                                                 "Ljava/net/InetSocketAddress$InetSocketAddressHolder;");
     jobject holder = env->GetObjectField(javaInetSocketAddress, holderFid);
 
-    static jfieldID addressFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass,
+    static jfieldID addressFid = env->GetFieldID(JniConstants::GetInetSocketAddressHolderClass(env),
                                                  "addr", "Ljava/net/InetAddress;");
-    static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass, "port", "I");
+    static jfieldID portFid = env->GetFieldID(JniConstants::GetInetSocketAddressHolderClass(env), "port", "I");
     env->SetObjectField(holder, addressFid, sender);
     env->SetIntField(holder, portFid, port);
     return true;
@@ -602,9 +610,9 @@
         return true;
     }
 
-    if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
+    if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetInetSocketAddressClass(env))) {
         return fillInetSocketAddress(env, javaSocketAddress, ss);
-    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
+    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetUnixSocketAddressClass(env))) {
         return fillUnixSocketAddress(env, javaSocketAddress, ss, sa_len);
     }
     jniThrowException(env, "java/lang/UnsupportedOperationException",
@@ -615,13 +623,13 @@
 
 static void javaInetSocketAddressToInetAddressAndPort(
         JNIEnv* env, jobject javaInetSocketAddress, jobject& javaInetAddress, jint& port) {
-    static jfieldID holderFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "holder",
+    static jfieldID holderFid = env->GetFieldID(JniConstants::GetInetSocketAddressClass(env), "holder",
                                                 "Ljava/net/InetSocketAddress$InetSocketAddressHolder;");
     jobject holder = env->GetObjectField(javaInetSocketAddress, holderFid);
 
     static jfieldID addressFid = env->GetFieldID(
-            JniConstants::inetSocketAddressHolderClass, "addr", "Ljava/net/InetAddress;");
-    static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass, "port", "I");
+            JniConstants::GetInetSocketAddressHolderClass(env), "addr", "Ljava/net/InetAddress;");
+    static jfieldID portFid = env->GetFieldID(JniConstants::GetInetSocketAddressHolderClass(env), "port", "I");
 
     javaInetAddress = env->GetObjectField(holder, addressFid);
     port = env->GetIntField(holder, portFid);
@@ -638,9 +646,9 @@
 static bool javaNetlinkSocketAddressToSockaddr(
         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
     static jfieldID nlPidFid = env->GetFieldID(
-            JniConstants::netlinkSocketAddressClass, "nlPortId", "I");
+            JniConstants::GetNetlinkSocketAddressClass(env), "nlPortId", "I");
     static jfieldID nlGroupsFid = env->GetFieldID(
-            JniConstants::netlinkSocketAddressClass, "nlGroupsMask", "I");
+            JniConstants::GetNetlinkSocketAddressClass(env), "nlGroupsMask", "I");
 
     sockaddr_nl *nlAddr = reinterpret_cast<sockaddr_nl *>(&ss);
     nlAddr->nl_family = AF_NETLINK;
@@ -653,7 +661,7 @@
 static bool javaUnixSocketAddressToSockaddr(
         JNIEnv* env, jobject javaUnixSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
     static jfieldID sunPathFid = env->GetFieldID(
-            JniConstants::unixSocketAddressClass, "sun_path", "[B");
+            JniConstants::GetUnixSocketAddressClass(env), "sun_path", "[B");
 
     struct sockaddr_un* un_addr = reinterpret_cast<struct sockaddr_un*>(&ss);
     memset (un_addr, 0, sizeof(sockaddr_un));
@@ -678,15 +686,15 @@
 static bool javaPacketSocketAddressToSockaddr(
         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
     static jfieldID protocolFid = env->GetFieldID(
-            JniConstants::packetSocketAddressClass, "sll_protocol", "S");
+            JniConstants::GetPacketSocketAddressClass(env), "sll_protocol", "S");
     static jfieldID ifindexFid = env->GetFieldID(
-            JniConstants::packetSocketAddressClass, "sll_ifindex", "I");
+            JniConstants::GetPacketSocketAddressClass(env), "sll_ifindex", "I");
     static jfieldID hatypeFid = env->GetFieldID(
-            JniConstants::packetSocketAddressClass, "sll_hatype", "S");
+            JniConstants::GetPacketSocketAddressClass(env), "sll_hatype", "S");
     static jfieldID pkttypeFid = env->GetFieldID(
-            JniConstants::packetSocketAddressClass, "sll_pkttype", "B");
+            JniConstants::GetPacketSocketAddressClass(env), "sll_pkttype", "B");
     static jfieldID addrFid = env->GetFieldID(
-            JniConstants::packetSocketAddressClass, "sll_addr", "[B");
+            JniConstants::GetPacketSocketAddressClass(env), "sll_addr", "[B");
 
     sockaddr_ll *sll = reinterpret_cast<sockaddr_ll *>(&ss);
     sll->sll_family = AF_PACKET;
@@ -718,13 +726,13 @@
         return false;
     }
 
-    if (env->IsInstanceOf(javaSocketAddress, JniConstants::netlinkSocketAddressClass)) {
+    if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetNetlinkSocketAddressClass(env))) {
         return javaNetlinkSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
-    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
+    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetInetSocketAddressClass(env))) {
         return javaInetSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
-    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::packetSocketAddressClass)) {
+    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetPacketSocketAddressClass(env))) {
         return javaPacketSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
-    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
+    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetUnixSocketAddressClass(env))) {
         return javaUnixSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
     }
     jniThrowException(env, "java/lang/UnsupportedOperationException",
@@ -978,7 +986,16 @@
 }
 
 static void Linux_bindSocketAddress(
-        JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+        JNIEnv* env, jobject thisObj, jobject javaFd, jobject javaSocketAddress) {
+    if (javaSocketAddress != NULL &&
+            env->IsInstanceOf(javaSocketAddress, JniConstants::GetInetSocketAddressClass(env))) {
+        // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
+        jobject javaInetAddress;
+        jint port;
+        javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
+        Linux_bind(env, thisObj, javaFd, javaInetAddress, port);
+        return;
+    }
     sockaddr_storage ss;
     socklen_t sa_len;
     if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
@@ -1086,13 +1103,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) {
@@ -1100,7 +1169,16 @@
 }
 
 static void Linux_connectSocketAddress(
-        JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+        JNIEnv* env, jobject thisObj, jobject javaFd, jobject javaSocketAddress) {
+    if (javaSocketAddress != NULL &&
+            env->IsInstanceOf(javaSocketAddress, JniConstants::GetInetSocketAddressClass(env))) {
+        // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
+        jobject javaInetAddress;
+        jint port;
+        javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
+        Linux_connect(env, thisObj, javaFd, javaInetAddress, port);
+        return;
+    }
     sockaddr_storage ss;
     socklen_t sa_len;
     if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
@@ -1165,11 +1243,11 @@
 }
 
 static jint Linux_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
-    static jfieldID typeFid = env->GetFieldID(JniConstants::structFlockClass, "l_type", "S");
-    static jfieldID whenceFid = env->GetFieldID(JniConstants::structFlockClass, "l_whence", "S");
-    static jfieldID startFid = env->GetFieldID(JniConstants::structFlockClass, "l_start", "J");
-    static jfieldID lenFid = env->GetFieldID(JniConstants::structFlockClass, "l_len", "J");
-    static jfieldID pidFid = env->GetFieldID(JniConstants::structFlockClass, "l_pid", "I");
+    static jfieldID typeFid = env->GetFieldID(JniConstants::GetStructFlockClass(env), "l_type", "S");
+    static jfieldID whenceFid = env->GetFieldID(JniConstants::GetStructFlockClass(env), "l_whence", "S");
+    static jfieldID startFid = env->GetFieldID(JniConstants::GetStructFlockClass(env), "l_start", "J");
+    static jfieldID lenFid = env->GetFieldID(JniConstants::GetStructFlockClass(env), "l_len", "J");
+    static jfieldID pidFid = env->GetFieldID(JniConstants::GetStructFlockClass(env), "l_pid", "I");
 
     struct flock64 lock;
     memset(&lock, 0, sizeof(lock));
@@ -1248,10 +1326,10 @@
         return NULL;
     }
 
-    static jfieldID flagsFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_flags", "I");
-    static jfieldID familyFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_family", "I");
-    static jfieldID socktypeFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_socktype", "I");
-    static jfieldID protocolFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_protocol", "I");
+    static jfieldID flagsFid = env->GetFieldID(JniConstants::GetStructAddrinfoClass(env), "ai_flags", "I");
+    static jfieldID familyFid = env->GetFieldID(JniConstants::GetStructAddrinfoClass(env), "ai_family", "I");
+    static jfieldID socktypeFid = env->GetFieldID(JniConstants::GetStructAddrinfoClass(env), "ai_socktype", "I");
+    static jfieldID protocolFid = env->GetFieldID(JniConstants::GetStructAddrinfoClass(env), "ai_protocol", "I");
 
     addrinfo hints;
     memset(&hints, 0, sizeof(hints));
@@ -1283,7 +1361,7 @@
     }
 
     // Prepare output array.
-    jobjectArray result = env->NewObjectArray(addressCount, JniConstants::inetAddressClass, NULL);
+    jobjectArray result = env->NewObjectArray(addressCount, JniConstants::GetInetAddressClass(env), NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -1447,6 +1525,13 @@
         throwErrnoException(env, "getsockopt");
         return NULL;
     }
+    // If we didn't get the buffer size we expected then error. If other structures are the same
+    // size as timeval we might not detect an issue and could return junk.
+    if (size != sizeof(tv)) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                "getsockoptTimeval() unsupported with level %i and option %i", level, option);
+        return NULL;
+    }
     return makeStructTimeval(env, tv);
 }
 
@@ -1515,7 +1600,7 @@
 }
 
 static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::structIfaddrs, "<init>",
+    static jmethodID ctor = env->GetMethodID(JniConstants::GetStructIfaddrsClass(env), "<init>",
             "(Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V");
     if (ctor == NULL) {
         return NULL;
@@ -1536,7 +1621,7 @@
     }
 
     // Prepare output array.
-    jobjectArray result = env->NewObjectArray(ifCount, JniConstants::structIfaddrs, NULL);
+    jobjectArray result = env->NewObjectArray(ifCount, JniConstants::GetStructIfaddrsClass(env), NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -1604,8 +1689,8 @@
             addr = netmask = broad = NULL;
         }
 
-        jobject o = env->NewObject(JniConstants::structIfaddrs, ctor, name, flags, addr, netmask,
-                                   broad, hwaddr);
+        jobject o = env->NewObject(JniConstants::GetStructIfaddrsClass(env), ctor, name, flags,
+                                   addr, netmask, broad, hwaddr);
         if (o == NULL) {
             return NULL;
         }
@@ -1640,8 +1725,14 @@
     }
     sockaddr_storage ss;
     memset(&ss, 0, sizeof(ss));
-    // sockaddr_in and sockaddr_in6 are at the same address, so we can use either here.
-    void* dst = &reinterpret_cast<sockaddr_in*>(&ss)->sin_addr;
+    void* dst;
+    if (family == AF_INET) {
+      dst = &reinterpret_cast<sockaddr_in*>(&ss)->sin_addr;
+    } else if (family == AF_INET6) {
+      dst = &reinterpret_cast<sockaddr_in6*>(&ss)->sin6_addr;
+    } else {
+      return NULL;
+    }
     if (inet_pton(family, name.c_str(), dst) != 1) {
         return NULL;
     }
@@ -1843,7 +1934,7 @@
     if (pipe2_result == -1) {
         return NULL;
     }
-    jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL);
+    jobjectArray result = env->NewObjectArray(2, JniConstants::GetFileDescriptorClass(env), NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -1861,9 +1952,9 @@
 }
 
 static jint Linux_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
-    static jfieldID fdFid = env->GetFieldID(JniConstants::structPollfdClass, "fd", "Ljava/io/FileDescriptor;");
-    static jfieldID eventsFid = env->GetFieldID(JniConstants::structPollfdClass, "events", "S");
-    static jfieldID reventsFid = env->GetFieldID(JniConstants::structPollfdClass, "revents", "S");
+    static jfieldID fdFid = env->GetFieldID(JniConstants::GetStructPollfdClass(env), "fd", "Ljava/io/FileDescriptor;");
+    static jfieldID eventsFid = env->GetFieldID(JniConstants::GetStructPollfdClass(env), "events", "S");
+    static jfieldID reventsFid = env->GetFieldID(JniConstants::GetStructPollfdClass(env), "revents", "S");
 
     // Turn the Java android.system.StructPollfd[] into a C++ struct pollfd[].
     size_t arrayLength = env->GetArrayLength(javaStructs);
@@ -1969,7 +2060,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, pread64, javaFd, bytes.get() + byteOffset, byteCount, offset);
 }
 
-static jint Linux_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
+static jint Linux_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -2111,7 +2202,8 @@
 }
 
 static jint Linux_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
-    if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
+    if (javaSocketAddress != NULL &&
+            env->IsInstanceOf(javaSocketAddress, JniConstants::GetInetSocketAddressClass(env))) {
         // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
         jobject javaInetAddress;
         jint port;
@@ -2127,11 +2219,19 @@
 
     sockaddr_storage ss;
     socklen_t sa_len;
-    if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
-        return -1;
+    const sockaddr* sa;
+
+    if (javaSocketAddress != NULL) {
+        if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
+            return -1;
+        }
+
+        sa = reinterpret_cast<const sockaddr*>(&ss);
+    } else {
+        sa = NULL;
+        sa_len = 0;
     }
 
-    const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
     // We don't need the return value because we'll already have thrown.
     return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, sa, sa_len);
 }
@@ -2208,10 +2308,10 @@
     struct group_req req;
     memset(&req, 0, sizeof(req));
 
-    static jfieldID grInterfaceFid = env->GetFieldID(JniConstants::structGroupReqClass, "gr_interface", "I");
+    static jfieldID grInterfaceFid = env->GetFieldID(JniConstants::GetStructGroupReqClass(env), "gr_interface", "I");
     req.gr_interface = env->GetIntField(javaGroupReq, grInterfaceFid);
     // Get the IPv4 or IPv6 multicast address to join or leave.
-    static jfieldID grGroupFid = env->GetFieldID(JniConstants::structGroupReqClass, "gr_group", "Ljava/net/InetAddress;");
+    static jfieldID grGroupFid = env->GetFieldID(JniConstants::GetStructGroupReqClass(env), "gr_group", "Ljava/net/InetAddress;");
     ScopedLocalRef<jobject> javaGroup(env, env->GetObjectField(javaGroupReq, grGroupFid));
     socklen_t sa_len;
     if (!inetAddressToSockaddrVerbatim(env, javaGroup.get(), 0, req.gr_group, sa_len)) {
@@ -2238,8 +2338,8 @@
 }
 
 static void Linux_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
-    static jfieldID lOnoffFid = env->GetFieldID(JniConstants::structLingerClass, "l_onoff", "I");
-    static jfieldID lLingerFid = env->GetFieldID(JniConstants::structLingerClass, "l_linger", "I");
+    static jfieldID lOnoffFid = env->GetFieldID(JniConstants::GetStructLingerClass(env), "l_onoff", "I");
+    static jfieldID lLingerFid = env->GetFieldID(JniConstants::GetStructLingerClass(env), "l_linger", "I");
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct linger value;
     value.l_onoff = env->GetIntField(javaLinger, lOnoffFid);
@@ -2248,8 +2348,13 @@
 }
 
 static void Linux_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
-    static jfieldID tvSecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_sec", "J");
-    static jfieldID tvUsecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_usec", "J");
+    if (javaTimeval == nullptr) {
+        jniThrowNullPointerException(env, "null javaTimeval");
+        return;
+    }
+
+    static jfieldID tvSecFid = env->GetFieldID(JniConstants::GetStructTimevalClass(env), "tv_sec", "J");
+    static jfieldID tvUsecFid = env->GetFieldID(JniConstants::GetStructTimevalClass(env), "tv_usec", "J");
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct timeval value;
     value.tv_sec = env->GetLongField(javaTimeval, tvSecFid);
@@ -2297,10 +2402,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]);
+        }
     }
 }
 
@@ -2445,7 +2558,7 @@
     return rc;
 }
 
-static jint Linux_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
+static jint Linux_writeBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -2467,6 +2580,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/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp
index 5f50751..a5b7b72 100644
--- a/luni/src/main/native/libcore_io_Memory.cpp
+++ b/luni/src/main/native/libcore_io_Memory.cpp
@@ -22,11 +22,11 @@
 #include <sys/mman.h>
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedBytes.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
+#include <nativehelper/jni_macros.h>
 
-#include "nativehelper/jni_macros.h"
+#include "JniConstants.h"
 #include "Portability.h"
 
 // Use packed structures for access to unaligned data on targets with alignment restrictions.
diff --git a/luni/src/main/native/libcore_util_NativeAllocationRegistry.cpp b/luni/src/main/native/libcore_util_NativeAllocationRegistry.cpp
index 59bed74..ded578a 100644
--- a/luni/src/main/native/libcore_util_NativeAllocationRegistry.cpp
+++ b/luni/src/main/native/libcore_util_NativeAllocationRegistry.cpp
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include <nativehelper/JniConstants.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/jni_macros.h>
 
 typedef void (*FreeFunction)(void*);
 
diff --git a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index 22496bf..9d23837 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -23,18 +23,18 @@
 
 #include <android/log.h>
 #include <android-base/stringprintf.h>
+
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedStringChars.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
 
-#include "jni.h"
+#include "JniConstants.h"
 #include "JniException.h"
 #include "unicode/unistr.h"
 
-
 #define BUCKET_COUNT 128
 
 /**
@@ -1346,7 +1346,7 @@
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
     if (unparsedEntityDeclMethod == NULL) return;
 
-    internMethod = env->GetMethodID(JniConstants::stringClass, "intern", "()Ljava/lang/String;");
+    internMethod = env->GetMethodID(JniConstants::GetStringClass(env), "intern", "()Ljava/lang/String;");
     if (internMethod == NULL) return;
 
     // Reference to "".
diff --git a/luni/src/main/native/sun_misc_Unsafe.cpp b/luni/src/main/native/sun_misc_Unsafe.cpp
index 67925b0..49848a2 100644
--- a/luni/src/main/native/sun_misc_Unsafe.cpp
+++ b/luni/src/main/native/sun_misc_Unsafe.cpp
@@ -17,7 +17,7 @@
 #define LOG_TAG "Unsafe"
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
+#include <nativehelper/jni_macros.h>
 
 static jobject Unsafe_allocateInstance(JNIEnv* env, jclass, jclass c) {
   return env->AllocObject(c);
diff --git a/luni/src/main/native/valueOf.cpp b/luni/src/main/native/valueOf.cpp
index fdd2502..aa5893c 100644
--- a/luni/src/main/native/valueOf.cpp
+++ b/luni/src/main/native/valueOf.cpp
@@ -17,8 +17,10 @@
 #define LOG_TAG "valueOf"
 
 #include "valueOf.h"
+
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
+
+#include "JniConstants.h"
 
 template <typename T>
 static jobject valueOf(JNIEnv* env, jclass c, const char* signature, const T& value) {
@@ -34,27 +36,27 @@
 }
 
 jobject booleanValueOf(JNIEnv* env, jboolean value) {
-    return valueOf(env, JniConstants::booleanClass, "(Z)Ljava/lang/Boolean;", value);
+    return valueOf(env, JniConstants::GetBooleanClass(env), "(Z)Ljava/lang/Boolean;", value);
 }
 
 jobject doubleValueOf(JNIEnv* env, jdouble value) {
-    return valueOf(env, JniConstants::doubleClass, "(D)Ljava/lang/Double;", value);
+    return valueOf(env, JniConstants::GetDoubleClass(env), "(D)Ljava/lang/Double;", value);
 }
 
 jobject integerValueOf(JNIEnv* env, jint value) {
-    return valueOf(env, JniConstants::integerClass, "(I)Ljava/lang/Integer;", value);
+    return valueOf(env, JniConstants::GetIntegerClass(env), "(I)Ljava/lang/Integer;", value);
 }
 
 jobject longValueOf(JNIEnv* env, jlong value) {
-    return valueOf(env, JniConstants::longClass, "(J)Ljava/lang/Long;", value);
+    return valueOf(env, JniConstants::GetLongClass(env), "(J)Ljava/lang/Long;", value);
 }
 
 jboolean booleanValue(JNIEnv* env, jobject javaLangBoolean) {
-    static jfieldID fid = env->GetFieldID(JniConstants::booleanClass, "value", "Z");
+    static jfieldID fid = env->GetFieldID(JniConstants::GetBooleanClass(env), "value", "Z");
     return env->GetBooleanField(javaLangBoolean, fid);
 }
 
 jint intValue(JNIEnv* env, jobject javaLangInteger) {
-    static jfieldID fid = env->GetFieldID(JniConstants::integerClass, "value", "I");
+    static jfieldID fid = env->GetFieldID(JniConstants::GetIntegerClass(env), "value", "I");
     return env->GetIntField(javaLangInteger, fid);
 }
diff --git a/luni/src/module/java/module-info.java b/luni/src/module/java/module-info.java
index cafcf9b..8a290d9 100644
--- a/luni/src/module/java/module-info.java
+++ b/luni/src/module/java/module-info.java
@@ -118,6 +118,7 @@
     exports libcore.net.event;
     exports libcore.net.http;
     exports libcore.reflect;
+    exports libcore.timezone;
     exports libcore.util;
     exports org.json;
 }
diff --git a/luni/src/test/etc/loading-test-jar/build.sh b/luni/src/test/etc/loading-test-jar/build.sh
index 4737f14..71630bf 100755
--- a/luni/src/test/etc/loading-test-jar/build.sh
+++ b/luni/src/test/etc/loading-test-jar/build.sh
@@ -47,7 +47,7 @@
 
 mkdir classes
 javac -classpath classes2 -d classes *.java
-dx --dex --output=classes.dex classes
+d8 --output . --classpath classes2 $(find classes -type f) # Creates classes.dex
 jar cf loading-test.jar classes.dex -C resources .
 
 rm -rf classes
diff --git a/luni/src/test/etc/loading-test2-jar/build.sh b/luni/src/test/etc/loading-test2-jar/build.sh
index 0d98a2a..ef5f129 100755
--- a/luni/src/test/etc/loading-test2-jar/build.sh
+++ b/luni/src/test/etc/loading-test2-jar/build.sh
@@ -41,7 +41,7 @@
 
 mkdir classes
 javac -d classes *.java
-dx --dex --output=classes.dex classes
+find classes -type f | xargs d8 --output . # Creates classes.dex
 jar cf loading-test2.jar classes.dex -C resources .
 
 rm -rf classes
diff --git a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java b/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
deleted file mode 100644
index ec5ca03..0000000
--- a/luni/src/test/java/com/android/org/bouncycastle/crypto/digests/DigestTest.java
+++ /dev/null
@@ -1,142 +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 com.android.org.bouncycastle.crypto.digests;
-
-import junit.framework.TestCase;
-import com.android.org.bouncycastle.crypto.Digest;
-import com.android.org.bouncycastle.crypto.ExtendedDigest;
-import tests.util.SummaryStatistics;
-
-/**
- * Implements unit tests for our JNI wrapper around OpenSSL. We use the
- * existing Bouncy Castle implementation as our test oracle.
- */
-public class DigestTest extends TestCase {
-
-    /**
-     * Processes the two given message digests for the same data and checks
-     * the results. Requirement is that the results must be equal, the digest
-     * implementations must have the same properties, and the new implementation
-     * must be faster than the old one.
-     *
-     * @param oldDigest The old digest implementation, provided by Bouncy Castle
-     * @param newDigest The new digest implementation, provided by OpenSSL
-     */
-    public void doTestMessageDigest(Digest oldDigest, Digest newDigest) {
-        final int WARMUP = 10;
-        final int ITERATIONS = 100;
-
-        byte[] data = new byte[1024];
-
-        byte[] oldHash = new byte[oldDigest.getDigestSize()];
-        byte[] newHash = new byte[newDigest.getDigestSize()];
-
-        assertEquals("Hash names must be equal",
-                     oldDigest.getAlgorithmName(), newDigest.getAlgorithmName());
-        assertEquals("Hash sizes must be equal",
-                     oldHash.length, newHash.length);
-        assertEquals("Hash block sizes must be equal",
-                     ((ExtendedDigest)oldDigest).getByteLength(),
-                     ((ExtendedDigest)newDigest).getByteLength());
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte)i;
-        }
-
-        SummaryStatistics oldTime = new SummaryStatistics();
-        SummaryStatistics newTime = new SummaryStatistics();
-
-        for (int j = 0; j < ITERATIONS + WARMUP; j++) {
-            long t0 = System.nanoTime();
-            for (int i = 0; i < 4; i++) {
-                oldDigest.update(data, 0, data.length);
-            }
-            int oldLength = oldDigest.doFinal(oldHash, 0);
-            long t1 = System.nanoTime();
-
-            if (j >= WARMUP) {
-                oldTime.add(t1 - t0);
-            }
-
-            long t2 = System.nanoTime();
-            for (int i = 0; i < 4; i++) {
-                newDigest.update(data, 0, data.length);
-            }
-            int newLength = newDigest.doFinal(newHash, 0);
-            long t3 = System.nanoTime();
-
-            if (j >= WARMUP) {
-              newTime.add(t3 - t2);
-            }
-
-            assertEquals("Hash sizes must be equal", oldLength, newLength);
-
-            for (int i = 0; i < oldLength; i++) {
-                assertEquals("Hashes[" + i + "] must be equal", oldHash[i], newHash[i]);
-            }
-        }
-
-        System.out.println("Time for " + ITERATIONS + " x old hash processing: "
-                + oldTime.toString());
-        System.out.println("Time for " + ITERATIONS + " x new hash processing: "
-                + newTime.toString());
-    }
-
-    /**
-     * Tests the MD5 implementation.
-     */
-    public void testMD5() {
-        Digest oldDigest = new MD5Digest();
-        Digest newDigest = new OpenSSLDigest.MD5();
-        doTestMessageDigest(oldDigest, newDigest);
-    }
-
-    /**
-     * Tests the SHA-1 implementation.
-     */
-    public void testSHA1() {
-        Digest oldDigest = new SHA1Digest();
-        Digest newDigest = new OpenSSLDigest.SHA1();
-        doTestMessageDigest(oldDigest, newDigest);
-    }
-
-    /**
-     * Tests the SHA-256 implementation.
-     */
-    public void testSHA256() {
-        Digest oldDigest = new SHA256Digest();
-        Digest newDigest = new OpenSSLDigest.SHA256();
-        doTestMessageDigest(oldDigest, newDigest);
-    }
-
-    /**
-     * Tests the SHA-384 implementation.
-     */
-    public void testSHA384() {
-        Digest oldDigest = new SHA384Digest();
-        Digest newDigest = new OpenSSLDigest.SHA384();
-        doTestMessageDigest(oldDigest, newDigest);
-    }
-
-    /**
-     * Tests the SHA-512 implementation.
-     */
-    public void testSHA512() {
-        Digest oldDigest = new SHA512Digest();
-        Digest newDigest = new OpenSSLDigest.SHA512();
-        doTestMessageDigest(oldDigest, newDigest);
-    }
-}
diff --git a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
deleted file mode 100644
index 48a175c..0000000
--- a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2012 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.org.bouncycastle.jce.provider;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.cert.CertificateFactory;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.security.MessageDigest;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.HashSet;
-import java.util.Set;
-import junit.framework.TestCase;
-import com.android.org.bouncycastle.jce.provider.CertBlacklist;
-import com.android.org.bouncycastle.crypto.Digest;
-import com.android.org.bouncycastle.util.encoders.Base64;
-import com.android.org.bouncycastle.util.encoders.Hex;
-
-public class CertBlacklistTest extends TestCase {
-
-    private File tmpFile;
-
-    private Set<String> DEFAULT_PUBKEYS;
-    private Set<String> DEFAULT_SERIALS;
-
-    public static final String TEST_CERT = "" +
-                    "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" +
-                    "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" +
-                    "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" +
-                    "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" +
-                    "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" +
-                    "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" +
-                    "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" +
-                    "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" +
-                    "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" +
-                    "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" +
-                    "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" +
-                    "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" +
-                    "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" +
-                    "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" +
-                    "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" +
-                    "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" +
-                    "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM=";
-
-    public static final String TURKTRUST_1 = "" +
-                    "MIIFPTCCBCWgAwIBAgICCCcwDQYJKoZIhvcNAQEFBQAwgawxPTA7BgNVBAMMNFTDnFJLVFJVU1Qg" +
-                    "RWxla3Ryb25payBTdW51Y3UgU2VydGlmaWthc8SxIEhpem1ldGxlcmkxCzAJBgNVBAYTAlRSMV4w" +
-                    "XAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE" +
-                    "n2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtICAyMDA1MB4XDTExMDgwODA3MDc1MVoXDTIx" +
-                    "MDcwNjA3MDc1MVowbjELMAkGA1UEBhMCVFIxDzANBgNVBAgMBkFOS0FSQTEPMA0GA1UEBwwGQU5L" +
-                    "QVJBMQwwCgYDVQQKDANFR08xGDAWBgNVBAsMD0VHTyBCSUxHSSBJU0xFTTEVMBMGA1UEAwwMKi5F" +
-                    "R08uR09WLlRSMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5zoj2Bpdl7R1M/zF6Qf" +
-                    "4su2F8vDqISKvuTuyJhNAHhFGHCsHjaixGMHspuz0l3V50kq/ECWbN8kKaeTrB112QOrWTU276iu" +
-                    "p1Gh+OlEOiR9vlQ4VAP00dWUjD6z9HQFCi8W3EsEtiiHiYOU9BcPpPkaUbECwP4nGVwR8aPwhB5P" +
-                    "GBJc98romdvciYkUpSOOwkuSRtooA7tRlLFu72QaNpXN1NueB36I3aajPk0YyiXy2w8XlgK7QI4P" +
-                    "SSBnSq+QblFocWVmLhF94je7py6lCnllrIFXpR3FWZLD5GcI6HKlBS78AQ+IMBLFHhsEVw5NQj90" +
-                    "chSZClfBWBZzIaV9RwIDAQABo4IBpDCCAaAwHwYDVR0jBBgwFoAUq042AzDS29UKaL6HpVBs/PZw" +
-                    "pSUwHQYDVR0OBBYEFGT7G4Y9uEryRIL5Vj3qJsD047M0MA4GA1UdDwEB/wQEAwIBBjBFBgNVHSAE" +
-                    "PjA8MDoGCWCGGAMAAwEBATAtMCsGCCsGAQUFBwIBFh9odHRwOi8vd3d3LnR1cmt0cnVzdC5jb20u" +
-                    "dHIvc3VlMA8GA1UdEwEB/wQFMAMBAf8wSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL3d3dy50dXJr" +
-                    "dHJ1c3QuY29tLnRyL3NpbC9UVVJLVFJVU1RfU1NMX1NJTF9zMi5jcmwwgaoGCCsGAQUFBwEBBIGd" +
-                    "MIGaMG4GCCsGAQUFBzAChmJodHRwOi8vd3d3LnR1cmt0cnVzdC5jb20udHIvc2VydGlmaWthbGFy" +
-                    "L1RVUktUUlVTVF9FbGVrdHJvbmlrX1N1bnVjdV9TZXJ0aWZpa2FzaV9IaXptZXRsZXJpX3MyLmNy" +
-                    "dDAoBggrBgEFBQcwAYYcaHR0cDovL29jc3AudHVya3RydXN0LmNvbS50cjANBgkqhkiG9w0BAQUF" +
-                    "AAOCAQEAj89QCCyoW0S20EcYDZAnvFLFmougK97Bt68iV1OM622+Cyeyf4Sz+1LBk1f9ni3fGT0Q" +
-                    "+RWZJYWq5YuSBiLVgk3NLcxnwe3wmnvErUgq1QDtAaNlBWMEMklOlWGfJ0eWaillUskJbDd4KwgZ" +
-                    "HDEj7g/jYEQqU1t0zoJdwM/zNsnLHkhwcWZ5PQnnbpff1Ct/1LH/8pdy2eRDmRmqniLUh8r2lZfJ" +
-                    "eudVZG6yIbxsqP3t2JCq5c2P1jDhAGF3g9DiskH0CzsRdbVpoWdr+PY1Xz/19G8XEpX9r+IBJhLd" +
-                    "bkpVo0Qh0A10mzFP/GUk5f/8nho2HvLaVMhWv1qKcF8IhQ==";
-
-    public static final String TURKTRUST_2 = "" +
-                    "MIID8DCCAtigAwIBAgICCGQwDQYJKoZIhvcNAQEFBQAwgawxPTA7BgNVBAMMNFTDnFJLVFJVU1Qg" +
-                    "RWxla3Ryb25payBTdW51Y3UgU2VydGlmaWthc8SxIEhpem1ldGxlcmkxCzAJBgNVBAYTAlRSMV4w" +
-                    "XAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE" +
-                    "n2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtICAyMDA1MB4XDTExMDgwODA3MDc1MVoXDTIx" +
-                    "MDgwNTA3MDc1MVowgaMxCzAJBgNVBAYTAlRSMRAwDgYDVQQIEwdMZWZrb3NhMRAwDgYDVQQHEwdM" +
-                    "ZWZrb3NhMRwwGgYDVQQKExNLS1RDIE1lcmtleiBCYW5rYXNpMSYwJAYDVQQDEx1lLWlzbGVtLmtr" +
-                    "dGNtZXJrZXpiYW5rYXNpLm9yZzEqMCgGCSqGSIb3DQEJARYbaWxldGlAa2t0Y21lcmtlemJhbmth" +
-                    "c2kub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1hUpuRFY67NsZ6C9rzRAPCb" +
-                    "9RVpi4nZzJIA1TvIfr4hMPM0X5jseMf5GvgJQ+cBMZtooDd7BbZNy2z7O5A+8PYFaMDdokCENx2e" +
-                    "PIqAVuO6C5UAqM7J3n6RrhjOvqiw6dTQMbtXhjFao+YMuBVvRuuhGHBDK3Je64T/KLzcmAUlRJEu" +
-                    "y+ZMe7AatUaSDr/jy5DMA5xEYOdsnS5Zo30lRG+9vqbxb8CQi+E97sNjY+W4lEgJKQWMNh5rCxo4" +
-                    "Hinkm3CKyKX3PAS+DDVI3LQiCiIQUOMA2+1P5aTPTkpqlbjqhbWTWAPWOKCF9d83p3RMXOYt5Gah" +
-                    "S8rg5u6+toEC1QIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkq" +
-                    "hkiG9w0BAQUFAAOCAQEAwjWz5tsUvYORVW8KJSK/biHFrAnFotMtoTKEewRmnYaYjwXIr1IPaBqh" +
-                    "jkGGviLN2eOH/v97Uli6HC4lzhKHfMQUS9KF/f5nGcH8iQBy/gmFsfJQ1KDC6GNM4CfMGIzyxjYh" +
-                    "P0VzdUtKX3PAl5EqgMUcdqRDy6Ruz55+JkdvCL1nAC7xH+czJcZVwysTdGfLTCh6VtYPgIkeL6U8" +
-                    "3xQAyMuOHm72exJljYFqIsiNvGE0KufCqCuH1PD97IXMrLlwGmKKg5jP349lySBpJjm6RDqCTT+6" +
-                    "dUl2jkVbeNmco99Y7AOdtLsOdXBMCo5x8lK8zwQWFrzEms0joHXCpWfGWA==";
-
-    public static final String ANSSI = "" +
-                    "MIIDbDCCAlSgAwIBAgIDAx2nMA0GCSqGSIb3DQEBBQUAMEsxCzAJBgNVBAYTAkZSMQ4wDAYDVQQK" +
-                    "EwVER1RQRTEsMCoGA1UEAxMjQUMgREdUUEUgU2lnbmF0dXJlIEF1dGhlbnRpZmljYXRpb24wHhcN" +
-                    "MTMwNzE4MTAwNTI4WhcNMTQwNzE4MTAwNTI4WjA+MQswCQYDVQQGEwJGUjETMBEGA1UECgwKREcg" +
-                    "VHLDqXNvcjEaMBgGA1UEAwwRQUMgREcgVHLDqXNvciBTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IB" +
-                    "DwAwggEKAoIBAQDI0WFSUyY+MmtFkqFjTefoFyDgh9b1C/2YvSIvT8oCH62JWT5rpeTCZwaXbqWc" +
-                    "jaNfzggqaFsokqfhBif43HNHNtNJmvKE32VcuLB0SpsLR/1VeTd9F99C1JeHVa+nelumOHEfouX8" +
-                    "rRFrxNXNIYTVeiENT8Y2YqRb/XAril9g7i674uFzLiNR/t/N/F8Exujv9U8m8rmgud/+tG9WDRaD" +
-                    "Jwoj3ZFCOnL5qLnSUEcS6TzWpozLmC2JVO5GZKGGd7qC9FjdBkVilkbVIEGSrYvz2Uz2v5IGqMBI" +
-                    "QaFL/kSYWxGTaedTOk2drFEApp9AEPTfv1NwCWBfegsGQrHUROM3AgMBAAGjZjBkMBIGA1UdEwEB" +
-                    "/wQIMAYBAf8CAQQwHQYDVR0OBBYEFAAMW8lJqJW0DtAv5p3Mjogxvh9lMB8GA1UdIwQYMBaAFOnb" +
-                    "kI/9W5nkFTvwYlyn5A1Y6IeZMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAtDfG" +
-                    "HkHOLW2d9fiMtwtkEwDauISJLJyCjoRmawzmQbIZXq7HaLliVfE0sdfKUm0iQ0im1/CpnJLPoTeK" +
-                    "yBHvNu1ubLc2m+9dabAYhF3pVdKC+gNaAzBXZ9Gt0p1CLk1lf8Hg+R10HN2IPCv7V/crz2Ga+c23" +
-                    "4P3pfwYW8+Nd7alGCuvqot6UYXOlheF7zWUkHn6z6tvY+9oMDHKSUAthhA/FB50JgJU89zyTv1eg" +
-                    "Y3ldKwvYBW3W3yNZdTHbPyNsPJdhqA55mDNsteE5YTp1PyySDb1MSVrbxDEruoH6ZE99Hob4Ih8A" +
-                    "mn7MHZatGClECgjXWFZ2Gxa7OUCaQpcH8g==";
-
-    public CertBlacklistTest() throws IOException {
-        tmpFile = File.createTempFile("test", "");
-        DEFAULT_PUBKEYS = getDefaultPubkeys();
-        DEFAULT_SERIALS = getDefaultSerials();
-        tmpFile.delete();
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        tmpFile = File.createTempFile("test", "");
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            tmpFile.delete();
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    private Set<String> getPubkeyBlacklist(String path) throws IOException {
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist(path, "");
-        // call readPubkeyBlacklist
-        Set<byte[]> arr = bl.pubkeyBlacklist;
-        // convert the results to a hashset of strings
-        Set<String> results = new HashSet<String>();
-        for (byte[] value: arr) {
-            results.add(new String(value));
-        }
-        return results;
-    }
-
-    private Set<String> getSerialBlacklist(String path) throws IOException {
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist("", path);
-        // call readPubkeyBlacklist
-        Set<BigInteger> arr = bl.serialBlacklist;
-        // convert the results to a hashset of strings
-        Set<String> results = new HashSet<String>();
-        for (BigInteger value: arr) {
-            results.add(value.toString(16));
-        }
-        return results;
-    }
-
-    private static String getHash(PublicKey publicKey) throws Exception {
-        byte[] encoded = publicKey.getEncoded();
-        MessageDigest digest = MessageDigest.getInstance("SHA1");
-        byte[] hexlifiedHash = Hex.encode(digest.digest(encoded));
-        return new String(hexlifiedHash);
-    }
-
-    private Set<String> getDefaultPubkeys() throws IOException {
-        return getPubkeyBlacklist("");
-    }
-
-    private Set<String> getDefaultSerials() throws IOException {
-        return getSerialBlacklist("");
-    }
-
-    private Set<String> getCurrentPubkeyBlacklist() throws IOException {
-        return getPubkeyBlacklist(tmpFile.getCanonicalPath());
-    }
-
-    private Set<String> getCurrentSerialBlacklist() throws IOException {
-        return getSerialBlacklist(tmpFile.getCanonicalPath());
-    }
-
-    private void blacklistToFile(String blacklist) throws IOException {
-        FileOutputStream out = new FileOutputStream(tmpFile);
-        out.write(blacklist.toString().getBytes());
-        out.close();
-    }
-
-    private void writeBlacklist(HashSet<String> values) throws IOException {
-        StringBuilder result = new StringBuilder();
-        // join the values into a string
-        for (String value : values) {
-            if (result.length() != 0) {
-                result.append(",");
-            }
-            result.append(value);
-        }
-        blacklistToFile(result.toString());
-    }
-
-    private static PublicKey createPublicKey(String cert) throws Exception {
-        byte[] derCert = Base64.decode(cert.getBytes());
-        InputStream istream = new ByteArrayInputStream(derCert);
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        return cf.generateCertificate(istream).getPublicKey();
-    }
-
-    private static BigInteger createSerialNumber(String cert) throws Exception {
-        byte[] derCert = Base64.decode(cert.getBytes());
-        InputStream istream = new ByteArrayInputStream(derCert);
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        X509Certificate xCert = (X509Certificate)cf.generateCertificate(istream);
-        return xCert.getSerialNumber();
-    }
-
-    public void testPubkeyBlacklistLegit() throws Exception {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default pubkeys into the bl
-        bl.addAll(DEFAULT_PUBKEYS);
-        // do the test
-        assertEquals(bl, getCurrentPubkeyBlacklist());
-    }
-
-    public void testLegitPubkeyIsntBlacklisted() throws Exception {
-        // build the public key
-        PublicKey pk = createPublicKey(TEST_CERT);
-        // write that to the test blacklist
-        writeBlacklist(new HashSet<String>());
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), "");
-        // check to make sure it isn't blacklisted
-        assertEquals(bl.isPublicKeyBlackListed(pk), false);
-    }
-
-    public void testPubkeyIsBlacklisted() throws Exception {
-        // build the public key
-        PublicKey pk = createPublicKey(TEST_CERT);
-        // get its hash
-        String hash = getHash(pk);
-        // write that to the test blacklist
-        HashSet<String> testBlackList = new HashSet<String>();
-        testBlackList.add(hash);
-        writeBlacklist(testBlackList);
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), "");
-        // check to make sure it isn't blacklited
-        assertTrue(bl.isPublicKeyBlackListed(pk));
-    }
-
-    public void testSerialBlacklistLegit() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default serials into the bl
-        bl.addAll(DEFAULT_SERIALS);
-        // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
-    }
-
-    public void testPubkeyBlacklistMultipleLegit() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default pubkeys into the bl
-        bl.addAll(DEFAULT_PUBKEYS);
-        // do the test
-        assertEquals(bl, getCurrentPubkeyBlacklist());
-    }
-
-    public void testSerialBlacklistMultipleLegit() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
-        bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default serials into the bl
-        bl.addAll(DEFAULT_SERIALS);
-        // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
-    }
-
-    public void testPubkeyBlacklistMultipleBad() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
-        bl.add("");
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default pubkeys into the bl
-        bl.addAll(DEFAULT_PUBKEYS);
-        // remove the bad one
-        bl.remove("");
-        // do the test- results should be all but the bad one are handled
-        assertEquals(bl, getCurrentPubkeyBlacklist());
-    }
-
-    public void testSerialBlacklistMultipleBad() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
-        bl.add("");
-        bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default serials into the bl
-        bl.addAll(DEFAULT_SERIALS);
-        // remove the bad one
-        bl.remove("");
-        // do the test- results should be all but the bad one are handled
-        assertEquals(bl, getCurrentSerialBlacklist());
-    }
-
-    public void testPubkeyBlacklistDoesntExist() throws IOException {
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
-    }
-
-    public void testSerialBlacklistDoesntExist() throws IOException {
-        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
-    }
-
-    public void testPubkeyBlacklistNotHexValues() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
-        // write the blacklist
-        writeBlacklist(bl);
-        // do the test
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
-    }
-
-    public void testSerialBlacklistNotHexValues() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
-        // write the blacklist
-        writeBlacklist(bl);
-        // do the test
-        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
-    }
-
-    public void testPubkeyBlacklistIncorrectLength() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091cc");
-        // write the blacklist
-        writeBlacklist(bl);
-        // do the test
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
-    }
-
-    public void testSerialBlacklistZero() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("0");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default serials
-        bl.addAll(DEFAULT_SERIALS);
-        // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
-    }
-
-    public void testSerialBlacklistNegative() throws IOException {
-        // build the blacklist
-        HashSet<String> bl = new HashSet<String>();
-        bl.add("-1");
-        // write the blacklist
-        writeBlacklist(bl);
-        // add the default serials
-        bl.addAll(DEFAULT_SERIALS);
-        // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
-    }
-
-    public void testTurkTrustIntermediate1PubkeyBlacklist() throws Exception {
-        // build the public key
-        PublicKey pk = createPublicKey(TURKTRUST_1);
-        // write that to the test blacklist
-        writeBlacklist(new HashSet<String>());
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist();
-        // check to make sure it isn't blacklisted
-        assertEquals(bl.isPublicKeyBlackListed(pk), true);
-    }
-
-    public void testTurkTrustIntermediate2PubkeyBlacklist() throws Exception {
-        // build the public key
-        PublicKey pk = createPublicKey(TURKTRUST_2);
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist();
-        // check to make sure it isn't blacklisted
-        assertEquals(bl.isPublicKeyBlackListed(pk), true);
-    }
-
-    public void testANSSIIntermediatePubkeyBlacklist() throws Exception {
-        // build the public key
-        PublicKey pk = createPublicKey(ANSSI);
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist();
-        // check to make sure it isn't blacklisted
-        assertEquals(bl.isPublicKeyBlackListed(pk), true);
-    }
-
-    private static void printHash(String cert) throws Exception {
-        System.out.println("CERTIFICATE PUBLIC KEY HASH: " + getHash(createPublicKey(cert)));
-    }
-
-    private static void printSerial(String cert) throws Exception {
-        System.out.println("CERTIFICATE SERIAL NUMBER: " + createSerialNumber(cert).toString(16));
-    }
-}
diff --git a/luni/src/test/java/dalvik/system/create_test_jar.sh b/luni/src/test/java/dalvik/system/create_test_jar.sh
index 7042328..6ae59b6 100755
--- a/luni/src/test/java/dalvik/system/create_test_jar.sh
+++ b/luni/src/test/java/dalvik/system/create_test_jar.sh
@@ -3,6 +3,7 @@
 
 # Create the child JAR
 # --------------------------------------
+rm -rf /tmp/delegate_last_child
 mkdir -p /tmp/delegate_last_child/libcore/test/delegatelast;
 pushd /tmp/delegate_last_child
 echo "package libcore.test.delegatelast;\
@@ -18,14 +19,16 @@
           }\
       }" > libcore/test/delegatelast/Child.java
 javac libcore/test/delegatelast/*.java
-dx --dex --output=./child.jar --verbose libcore/test/delegatelast/*.class
+
+d8 --output . libcore/test/delegatelast/*.class # Creates ./classes.dex
 echo -ne "child" > ./resource.txt
-jar uf ./child.jar resource.txt
+jar cf ./child.jar classes.dex resource.txt
 cp ./child.jar $ANDROID_BUILD_TOP/libcore/luni/src/test/resources/dalvik/system/child.jar
 popd
 
 # Create the parent JAR
 # --------------------------------------
+rm -rf /tmp/delegate_last_parent
 mkdir -p /tmp/delegate_last_parent/libcore/test/delegatelast;
 pushd /tmp/delegate_last_parent
 echo "package libcore.test.delegatelast;\
@@ -41,15 +44,17 @@
           }\
       }" > libcore/test/delegatelast/Parent.java
 javac libcore/test/delegatelast/*.java
-dx --dex --output=./parent.jar --verbose libcore/test/delegatelast/*.class
+d8 --output . libcore/test/delegatelast/*.class # Creates ./classes.dex
 echo -ne "parent" > ./resource.txt
-jar uf ./parent.jar resource.txt
+echo -ne "parent2" > ./resource2.txt
+jar cf ./parent.jar classes.dex resource.txt resource2.txt
 cp ./parent.jar $ANDROID_BUILD_TOP/libcore/luni/src/test/resources/dalvik/system/parent.jar
 popd
 
 
 # Create a jar that overloads boot classpath classes and resources
 # ----------------------------------------------------------------
+rm -rf /tmp/delegate_last_bootoverride
 mkdir -p /tmp/delegate_last_bootoverride/java/util;
 pushd /tmp/delegate_last_bootoverride
 echo "package java.util;\
@@ -58,11 +63,10 @@
               return \"I'm not really a HashMap\";\
           }\
       }" > java/util/HashMap.java
-javac java/util/HashMap.java
-dx --dex --core-library --output=./bootoverride.jar --verbose java/util/HashMap.class
-
+javac --patch-module=java.base=. java/util/HashMap.java
+d8 --output . java/util/HashMap.class # Creates ./classes.dex
 mkdir -p android/icu
 echo -ne "NOT ICU" > android/icu/ICUConfig.properties
-jar uf ./bootoverride.jar android/icu/ICUConfig.properties
+jar cf ./bootoverride.jar classes.dex android/icu/ICUConfig.properties
 cp ./bootoverride.jar $ANDROID_BUILD_TOP/libcore/luni/src/test/resources/dalvik/system/bootoverride.jar
 popd
diff --git a/luni/src/test/java/libcore/android/system/ErrnoExceptionTest.java b/luni/src/test/java/libcore/android/system/ErrnoExceptionTest.java
new file mode 100644
index 0000000..59cdb4b
--- /dev/null
+++ b/luni/src/test/java/libcore/android/system/ErrnoExceptionTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 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.android.system;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import android.system.ErrnoException;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+import static android.system.OsConstants.EBADF;
+import static android.system.OsConstants.EINVAL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+@RunWith(JUnit4.class)
+public class ErrnoExceptionTest {
+
+    @Test public void messageErrnoAndCause() {
+        // For simplicitly, we hard-code "EINVAL (Invalid argument)" here even though
+        // strictly speaking, those only need to be consistent with errnoName() and
+        // strerror().
+        check_messageErrnoAndCause("null failed: EINVAL (Invalid argument)", null, EINVAL);
+        check_messageErrnoAndCause("name failed: EINVAL (Invalid argument)", "name", EINVAL);
+        check_messageErrnoAndCause("name failed: EBADF (Bad file descriptor)", "name", EBADF);
+    }
+
+    private static void check_messageErrnoAndCause(String msg, String nameOrNull, int errno) {
+        Throwable cause = new Throwable("cause msg");
+        assertMessageErrnoAndCause(msg, errno, null, new ErrnoException(nameOrNull, errno));
+        assertMessageErrnoAndCause(msg, errno, null, new ErrnoException(nameOrNull, errno, null));
+        assertMessageErrnoAndCause(msg, errno, cause, new ErrnoException(nameOrNull, errno, cause));
+    }
+
+    private static void assertMessageErrnoAndCause(String message, int errno, Throwable cause,
+            ErrnoException e) {
+        assertEquals(message, e.getMessage());
+        assertEquals(errno, e.errno);
+        assertEquals(cause, e.getCause());
+    }
+
+    @Test public void rethrow() {
+        check_rethrow(new ErrnoException(null, EINVAL));
+        check_rethrow(new ErrnoException(null, EINVAL, null));
+        check_rethrow(new ErrnoException(null, EINVAL, new Throwable("cause msg")));
+
+        check_rethrow(new ErrnoException("name", EINVAL));
+        check_rethrow(new ErrnoException("name", EINVAL, null));
+        check_rethrow(new ErrnoException("name", EINVAL, new Throwable("cause msg")));
+    }
+
+    private void check_rethrow(ErrnoException cause) {
+        try {
+            cause.rethrowAsIOException();
+            fail();
+        } catch (IOException e) {
+            assertEquals(cause.getMessage(), e.getMessage());
+            assertEquals(cause, e.getCause());
+            assertEquals(IOException.class, e.getClass());
+        }
+
+        try {
+            cause.rethrowAsSocketException();
+            fail();
+        } catch (SocketException e) {
+            assertEquals(cause.getMessage(), e.getMessage());
+            assertEquals(cause, e.getCause());
+            assertEquals(SocketException.class, e.getClass());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/android/system/OsConstantsTest.java b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
index a98707c..a2dc744 100644
--- a/luni/src/test/java/libcore/android/system/OsConstantsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
@@ -35,4 +35,13 @@
     public void testTcpUserTimeoutIsDefined() {
         assertTrue(OsConstants.TCP_USER_TIMEOUT > 0);
     }
+
+    /**
+     * Verifies equality assertions given in the documentation for
+     * {@link OsConstants#SOCK_CLOEXEC} and {@link OsConstants#SOCK_NONBLOCK}.
+     */
+    public void testConstantsEqual() {
+        assertEquals(OsConstants.O_CLOEXEC,  OsConstants.SOCK_CLOEXEC);
+        assertEquals(OsConstants.O_NONBLOCK, OsConstants.SOCK_NONBLOCK);
+    }
 }
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
new file mode 100644
index 0000000..7536885
--- /dev/null
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -0,0 +1,1417 @@
+/*
+ * Copyright (C) 2011 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.android.system;
+
+import android.system.ErrnoException;
+import android.system.Int64Ref;
+import android.system.NetlinkSocketAddress;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.PacketSocketAddress;
+import android.system.StructRlimit;
+import android.system.StructStat;
+import android.system.StructTimeval;
+import android.system.StructUcred;
+import android.system.UnixSocketAddress;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.DatagramPacket;
+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.ServerSocket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.atomic.AtomicReference;
+
+import junit.framework.TestCase;
+
+import libcore.io.IoUtils;
+
+import static android.system.OsConstants.*;
+
+public class OsTest extends TestCase {
+
+    public void testIsSocket() throws Exception {
+        File f = new File("/dev/null");
+        FileInputStream fis = new FileInputStream(f);
+        assertFalse(S_ISSOCK(Os.fstat(fis.getFD()).st_mode));
+        fis.close();
+
+        ServerSocket s = new ServerSocket();
+        assertTrue(S_ISSOCK(Os.fstat(s.getImpl().getFD$()).st_mode));
+        s.close();
+    }
+
+    public void testFcntlInt() throws Exception {
+        File f = File.createTempFile("OsTest", "tst");
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(f);
+            Os.fcntlInt(fis.getFD(), F_SETFD, FD_CLOEXEC);
+            int flags = Os.fcntlVoid(fis.getFD(), F_GETFD);
+            assertTrue((flags & FD_CLOEXEC) != 0);
+        } finally {
+            IoUtils.closeQuietly(fis);
+            f.delete();
+        }
+    }
+
+    public void testUnixDomainSockets_in_file_system() throws Exception {
+        String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket";
+        new File(path).delete();
+        checkUnixDomainSocket(UnixSocketAddress.createFileSystem(path), false);
+    }
+
+    public void testUnixDomainSocket_abstract_name() throws Exception {
+        // Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7).
+        checkUnixDomainSocket(UnixSocketAddress.createAbstract("/abstract_name_unix_socket"), true);
+    }
+
+    public void testUnixDomainSocket_unnamed() throws Exception {
+        final FileDescriptor fd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
+        // unix(7) says an unbound socket is unnamed.
+        checkNoSockName(fd);
+        Os.close(fd);
+    }
+
+    private void checkUnixDomainSocket(final UnixSocketAddress address, final boolean isAbstract)
+            throws Exception {
+        final FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
+        Os.bind(serverFd, address);
+        Os.listen(serverFd, 5);
+
+        checkSockName(serverFd, isAbstract, address);
+
+        Thread server = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    UnixSocketAddress peerAddress = UnixSocketAddress.createUnnamed();
+                    FileDescriptor clientFd = Os.accept(serverFd, peerAddress);
+                    checkSockName(clientFd, isAbstract, address);
+                    checkNoName(peerAddress);
+
+                    checkNoPeerName(clientFd);
+
+                    StructUcred credentials = Os.getsockoptUcred(clientFd, SOL_SOCKET, SO_PEERCRED);
+                    assertEquals(Os.getpid(), credentials.pid);
+                    assertEquals(Os.getuid(), credentials.uid);
+                    assertEquals(Os.getgid(), credentials.gid);
+
+                    byte[] request = new byte[256];
+                    Os.read(clientFd, request, 0, request.length);
+
+                    String s = new String(request, "UTF-8");
+                    byte[] response = s.toUpperCase(Locale.ROOT).getBytes("UTF-8");
+                    Os.write(clientFd, response, 0, response.length);
+
+                    Os.close(clientFd);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        });
+        server.start();
+
+        FileDescriptor clientFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
+
+        Os.connect(clientFd, address);
+        checkNoSockName(clientFd);
+
+        String string = "hello, world!";
+
+        byte[] request = string.getBytes("UTF-8");
+        assertEquals(request.length, Os.write(clientFd, request, 0, request.length));
+
+        byte[] response = new byte[request.length];
+        assertEquals(response.length, Os.read(clientFd, response, 0, response.length));
+
+        assertEquals(string.toUpperCase(Locale.ROOT), new String(response, "UTF-8"));
+
+        Os.close(clientFd);
+    }
+
+    private static void checkSockName(FileDescriptor fd, boolean isAbstract,
+            UnixSocketAddress address) throws Exception {
+        UnixSocketAddress isa = (UnixSocketAddress) Os.getsockname(fd);
+        assertEquals(address, isa);
+        if (isAbstract) {
+            assertEquals(0, isa.getSunPath()[0]);
+        }
+    }
+
+    private void checkNoName(UnixSocketAddress usa) {
+        assertEquals(0, usa.getSunPath().length);
+    }
+
+    private void checkNoPeerName(FileDescriptor fd) throws Exception {
+        checkNoName((UnixSocketAddress) Os.getpeername(fd));
+    }
+
+    private void checkNoSockName(FileDescriptor fd) throws Exception {
+        checkNoName((UnixSocketAddress) Os.getsockname(fd));
+    }
+
+    public void test_strsignal() throws Exception {
+        assertEquals("Killed", Os.strsignal(9));
+        assertEquals("Unknown signal -1", Os.strsignal(-1));
+    }
+
+    public void test_byteBufferPositions_write_pwrite() throws Exception {
+        FileOutputStream fos = new FileOutputStream(new File("/dev/null"));
+        FileDescriptor fd = fos.getFD();
+        final byte[] contents = new String("goodbye, cruel world")
+                .getBytes(StandardCharsets.US_ASCII);
+        ByteBuffer byteBuffer = ByteBuffer.wrap(contents);
+
+        byteBuffer.position(0);
+        int written = Os.write(fd, byteBuffer);
+        assertTrue(written > 0);
+        assertEquals(written, byteBuffer.position());
+
+        byteBuffer.position(4);
+        written = Os.write(fd, byteBuffer);
+        assertTrue(written > 0);
+        assertEquals(written + 4, byteBuffer.position());
+
+        byteBuffer.position(0);
+        written = Os.pwrite(fd, byteBuffer, 64 /* offset */);
+        assertTrue(written > 0);
+        assertEquals(written, byteBuffer.position());
+
+        byteBuffer.position(4);
+        written = Os.pwrite(fd, byteBuffer, 64 /* offset */);
+        assertTrue(written > 0);
+        assertEquals(written + 4, byteBuffer.position());
+
+        fos.close();
+    }
+
+    public void test_byteBufferPositions_read_pread() throws Exception {
+        FileInputStream fis = new FileInputStream(new File("/dev/zero"));
+        FileDescriptor fd = fis.getFD();
+        ByteBuffer byteBuffer = ByteBuffer.allocate(64);
+
+        byteBuffer.position(0);
+        int read = Os.read(fd, byteBuffer);
+        assertTrue(read > 0);
+        assertEquals(read, byteBuffer.position());
+
+        byteBuffer.position(4);
+        read = Os.read(fd, byteBuffer);
+        assertTrue(read > 0);
+        assertEquals(read + 4, byteBuffer.position());
+
+        byteBuffer.position(0);
+        read = Os.pread(fd, byteBuffer, 64 /* offset */);
+        assertTrue(read > 0);
+        assertEquals(read, byteBuffer.position());
+
+        byteBuffer.position(4);
+        read = Os.pread(fd, byteBuffer, 64 /* offset */);
+        assertTrue(read > 0);
+        assertEquals(read + 4, byteBuffer.position());
+
+        fis.close();
+    }
+
+    static void checkByteBufferPositions_sendto_recvfrom(
+            int family, InetAddress loopback) throws Exception {
+        final FileDescriptor serverFd = Os.socket(family, SOCK_STREAM, 0);
+        Os.bind(serverFd, loopback, 0);
+        Os.listen(serverFd, 5);
+
+        InetSocketAddress address = (InetSocketAddress) Os.getsockname(serverFd);
+
+        final Thread server = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    InetSocketAddress peerAddress = new InetSocketAddress();
+                    FileDescriptor clientFd = Os.accept(serverFd, peerAddress);
+
+                    // Attempt to receive a maximum of 24 bytes from the client, and then
+                    // close the connection.
+                    ByteBuffer buffer = ByteBuffer.allocate(16);
+                    int received = Os.recvfrom(clientFd, buffer, 0, null);
+                    assertTrue(received > 0);
+                    assertEquals(received, buffer.position());
+
+                    ByteBuffer buffer2 = ByteBuffer.allocate(16);
+                    buffer2.position(8);
+                    received = Os.recvfrom(clientFd, buffer2, 0, null);
+                    assertTrue(received > 0);
+                    assertEquals(received + 8, buffer.position());
+
+                    Os.close(clientFd);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        });
+
+        server.start();
+
+        FileDescriptor clientFd = Os.socket(family, SOCK_STREAM, 0);
+        Os.connect(clientFd, address.getAddress(), address.getPort());
+
+        final byte[] bytes = "good bye, cruel black hole with fancy distortion"
+                .getBytes(StandardCharsets.US_ASCII);
+        assertTrue(bytes.length > 24);
+
+        ByteBuffer input = ByteBuffer.wrap(bytes);
+        input.position(0);
+        input.limit(16);
+
+        int sent = Os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
+        assertTrue(sent > 0);
+        assertEquals(sent, input.position());
+
+        input.position(16);
+        input.limit(24);
+        sent = Os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
+        assertTrue(sent > 0);
+        assertEquals(sent + 16, input.position());
+
+        Os.close(clientFd);
+    }
+
+    interface ExceptionalRunnable {
+
+        public void run() throws Exception;
+    }
+
+    /**
+     * Expects that the given Runnable will throw an exception of the specified class. If the class
+     * is ErrnoException, and expectedErrno is non-null, also checks that the errno is equal to
+     * expectedErrno.
+     */
+    private static void expectException(ExceptionalRunnable r, Class<? extends Exception> exClass,
+            Integer expectedErrno, String msg) {
+        try {
+            r.run();
+            fail(msg + " did not throw exception");
+        } catch (Exception e) {
+            assertEquals(msg + " threw unexpected exception", exClass, e.getClass());
+
+            if (expectedErrno != null) {
+                if (e instanceof ErrnoException) {
+                    assertEquals(msg + "threw ErrnoException with unexpected error number",
+                            (int) expectedErrno, ((ErrnoException) e).errno);
+                } else {
+                    fail("Can only pass expectedErrno when expecting ErrnoException");
+                }
+            }
+
+        }
+    }
+
+    private static void expectBindException(FileDescriptor socket, SocketAddress addr,
+            Class exClass, Integer expectedErrno) {
+        String msg = String.format("bind(%s, %s)", socket, addr);
+        expectException(() -> {
+            Os.bind(socket, addr);
+        }, exClass, expectedErrno, msg);
+    }
+
+    private static void expectConnectException(FileDescriptor socket, SocketAddress addr,
+            Class exClass, Integer expectedErrno) {
+        String msg = String.format("connect(%s, %s)", socket, addr);
+        expectException(() -> {
+            Os.connect(socket, addr);
+        }, exClass, expectedErrno, msg);
+    }
+
+    private static void expectSendtoException(FileDescriptor socket, SocketAddress addr,
+            Class exClass, Integer expectedErrno) {
+        String msg = String.format("sendto(%s, %s)", socket, addr);
+        byte[] packet = new byte[42];
+        expectException(() -> {
+                    Os.sendto(socket, packet, 0, packet.length, 0, addr);
+                },
+                exClass, expectedErrno, msg);
+    }
+
+    private static void expectBindConnectSendtoSuccess(FileDescriptor socket, String socketDesc,
+            SocketAddress addr) {
+        String msg = socketDesc + " socket to " + addr.toString();
+
+        try {
+            try {
+                // Expect that bind throws when any of its arguments are null.
+                expectBindException(null, addr, ErrnoException.class, EBADF);
+                expectBindException(socket, null, NullPointerException.class, null);
+                expectBindException(null, null, NullPointerException.class, null);
+
+                // Expect bind to succeed.
+                Os.bind(socket, addr);
+
+                // Find out which port we're actually bound to, and use that in subsequent connect()
+                // and send() calls. We can't send to addr because that has a port of 0.
+                if (addr instanceof InetSocketAddress) {
+                    InetSocketAddress addrISA = (InetSocketAddress) addr;
+                    InetSocketAddress socknameISA = (InetSocketAddress) Os.getsockname(socket);
+
+                    assertEquals(addrISA.getAddress(), socknameISA.getAddress());
+                    assertEquals(0, addrISA.getPort());
+                    assertFalse(0 == socknameISA.getPort());
+                    addr = socknameISA;
+                }
+
+                // Expect sendto with a null address to throw because the socket is not connected,
+                // but to succeed with a non-null address.
+                byte[] packet = new byte[42];
+                Os.sendto(socket, packet, 0, packet.length, 0, addr);
+                // UNIX and IP sockets return different errors for this operation, so we can't check
+                // errno.
+                expectSendtoException(socket, null, ErrnoException.class, null);
+                expectSendtoException(null, null, ErrnoException.class, EBADF);
+
+                // Expect that connect throws when any of its arguments are null.
+                expectConnectException(null, addr, ErrnoException.class, EBADF);
+                expectConnectException(socket, null, NullPointerException.class, null);
+                expectConnectException(null, null, NullPointerException.class, null);
+
+                // Expect connect to succeed.
+                Os.connect(socket, addr);
+                assertEquals(Os.getsockname(socket), Os.getpeername(socket));
+
+                // Expect sendto to succeed both when given an explicit address and a null address.
+                Os.sendto(socket, packet, 0, packet.length, 0, addr);
+                Os.sendto(socket, packet, 0, packet.length, 0, null);
+            } catch (SocketException | ErrnoException e) {
+                fail("Expected success for " + msg + ", but got: " + e);
+            }
+
+        } finally {
+            IoUtils.closeQuietly(socket);
+        }
+    }
+
+    private static void expectBindConnectSendtoErrno(int bindErrno, int connectErrno,
+            int sendtoErrno, FileDescriptor socket, String socketDesc, SocketAddress addr) {
+        try {
+
+            // Expect bind to fail with bindErrno.
+            String msg = "bind " + socketDesc + " socket to " + addr.toString();
+            try {
+                Os.bind(socket, addr);
+                fail("Expected to fail " + msg);
+            } catch (ErrnoException e) {
+                assertEquals("Expected errno " + bindErrno + " " + msg, bindErrno, e.errno);
+            } catch (SocketException e) {
+                fail("Unexpected SocketException " + msg);
+            }
+
+            // Expect connect to fail with connectErrno.
+            msg = "connect " + socketDesc + " socket to " + addr.toString();
+            try {
+                Os.connect(socket, addr);
+                fail("Expected to fail " + msg);
+            } catch (ErrnoException e) {
+                assertEquals("Expected errno " + connectErrno + " " + msg, connectErrno, e.errno);
+            } catch (SocketException e) {
+                fail("Unexpected SocketException " + msg);
+            }
+
+            // Expect sendto to fail with sendtoErrno.
+            byte[] packet = new byte[42];
+            msg = "sendto " + socketDesc + " socket to " + addr.toString();
+            try {
+                Os.sendto(socket, packet, 0, packet.length, 0, addr);
+                fail("Expected to fail " + msg);
+            } catch (ErrnoException e) {
+                assertEquals("Expected errno " + sendtoErrno + " " + msg, sendtoErrno, e.errno);
+            } catch (SocketException e) {
+                fail("Unexpected SocketException " + msg);
+            }
+
+        } finally {
+            // No matter what happened, close the socket.
+            IoUtils.closeQuietly(socket);
+        }
+    }
+
+    private FileDescriptor makeIpv4Socket() throws Exception {
+        return Os.socket(AF_INET, SOCK_DGRAM, 0);
+    }
+
+    private FileDescriptor makeIpv6Socket() throws Exception {
+        return Os.socket(AF_INET6, SOCK_DGRAM, 0);
+    }
+
+    private FileDescriptor makeUnixSocket() throws Exception {
+        return Os.socket(AF_UNIX, SOCK_DGRAM, 0);
+    }
+
+    public void testCrossFamilyBindConnectSendto() throws Exception {
+        SocketAddress addrIpv4 = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
+        SocketAddress addrIpv6 = new InetSocketAddress(InetAddress.getByName("::1"), 0);
+        SocketAddress addrUnix = UnixSocketAddress.createAbstract("/abstract_name_unix_socket");
+
+        expectBindConnectSendtoSuccess(makeIpv4Socket(), "ipv4", addrIpv4);
+        expectBindConnectSendtoErrno(EAFNOSUPPORT, EAFNOSUPPORT, EAFNOSUPPORT,
+                makeIpv4Socket(), "ipv4", addrIpv6);
+        expectBindConnectSendtoErrno(EAFNOSUPPORT, EAFNOSUPPORT, EAFNOSUPPORT,
+                makeIpv4Socket(), "ipv4", addrUnix);
+
+        // This succeeds because Java always uses dual-stack sockets and all InetAddress and
+        // InetSocketAddress objects represent IPv4 addresses using IPv4-mapped IPv6 addresses.
+        expectBindConnectSendtoSuccess(makeIpv6Socket(), "ipv6", addrIpv4);
+        expectBindConnectSendtoSuccess(makeIpv6Socket(), "ipv6", addrIpv6);
+        expectBindConnectSendtoErrno(EAFNOSUPPORT, EAFNOSUPPORT, EINVAL,
+                makeIpv6Socket(), "ipv6", addrUnix);
+
+        expectBindConnectSendtoErrno(EINVAL, EINVAL, EINVAL,
+                makeUnixSocket(), "unix", addrIpv4);
+        expectBindConnectSendtoErrno(EINVAL, EINVAL, EINVAL,
+                makeUnixSocket(), "unix", addrIpv6);
+        expectBindConnectSendtoSuccess(makeUnixSocket(), "unix", addrUnix);
+    }
+
+    public void testUnknownSocketAddressSubclass() throws Exception {
+        class MySocketAddress extends SocketAddress {
+
+        }
+        MySocketAddress myaddr = new MySocketAddress();
+
+        for (int family : new int[] { AF_INET, AF_INET6, AF_NETLINK }) {
+            FileDescriptor s = Os.socket(family, SOCK_DGRAM, 0);
+            try {
+
+                try {
+                    Os.bind(s, myaddr);
+                    fail("bind socket family " + family
+                            + " to unknown SocketAddress subclass succeeded");
+                } catch (UnsupportedOperationException expected) {
+                }
+
+                try {
+                    Os.connect(s, myaddr);
+                    fail("connect socket family " + family
+                            + " to unknown SocketAddress subclass succeeded");
+                } catch (UnsupportedOperationException expected) {
+                }
+
+                byte[] msg = new byte[42];
+                try {
+                    Os.sendto(s, msg, 0, msg.length, 0, myaddr);
+                    fail("sendto socket family " + family
+                            + " to unknown SocketAddress subclass succeeded");
+                } catch (UnsupportedOperationException expected) {
+                }
+
+            } finally {
+                Os.close(s);
+            }
+        }
+    }
+
+    public void test_NetlinkSocket() throws Exception {
+        FileDescriptor nlSocket = Os.socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+        Os.bind(nlSocket, new NetlinkSocketAddress());
+        NetlinkSocketAddress address = (NetlinkSocketAddress) Os.getsockname(nlSocket);
+        assertTrue(address.getPortId() > 0);
+        assertEquals(0, address.getGroupsMask());
+
+        NetlinkSocketAddress nlKernel = new NetlinkSocketAddress();
+        Os.connect(nlSocket, nlKernel);
+        NetlinkSocketAddress nlPeer = (NetlinkSocketAddress) Os.getpeername(nlSocket);
+        assertEquals(0, nlPeer.getPortId());
+        assertEquals(0, nlPeer.getGroupsMask());
+        Os.close(nlSocket);
+    }
+
+    public void test_PacketSocketAddress() throws Exception {
+        NetworkInterface lo = NetworkInterface.getByName("lo");
+        FileDescriptor fd = Os.socket(AF_PACKET, SOCK_DGRAM, ETH_P_IPV6);
+        PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6, lo.getIndex());
+        Os.bind(fd, addr);
+
+        PacketSocketAddress bound = (PacketSocketAddress) Os.getsockname(fd);
+        assertEquals((short) ETH_P_IPV6, bound.sll_protocol);  // ETH_P_IPV6 is an int.
+        assertEquals(lo.getIndex(), bound.sll_ifindex);
+        assertEquals(ARPHRD_LOOPBACK, bound.sll_hatype);
+        assertEquals(0, bound.sll_pkttype);
+
+        // The loopback address is ETH_ALEN bytes long and is all zeros.
+        // http://lxr.free-electrons.com/source/drivers/net/loopback.c?v=3.10#L167
+        assertEquals(6, bound.sll_addr.length);
+        for (int i = 0; i < 6; i++) {
+            assertEquals(0, bound.sll_addr[i]);
+        }
+    }
+
+    public void test_byteBufferPositions_sendto_recvfrom_af_inet() throws Exception {
+        checkByteBufferPositions_sendto_recvfrom(AF_INET, InetAddress.getByName("127.0.0.1"));
+    }
+
+    public void test_byteBufferPositions_sendto_recvfrom_af_inet6() throws Exception {
+        checkByteBufferPositions_sendto_recvfrom(AF_INET6, InetAddress.getByName("::1"));
+    }
+
+    private void checkSendToSocketAddress(int family, InetAddress loopback) throws Exception {
+        FileDescriptor recvFd = Os.socket(family, SOCK_DGRAM, 0);
+        Os.bind(recvFd, loopback, 0);
+        StructTimeval tv = StructTimeval.fromMillis(20);
+        Os.setsockoptTimeval(recvFd, SOL_SOCKET, SO_RCVTIMEO, tv);
+
+        InetSocketAddress to = ((InetSocketAddress) Os.getsockname(recvFd));
+        FileDescriptor sendFd = Os.socket(family, SOCK_DGRAM, 0);
+        byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes("UTF-8");
+        int len = msg.length;
+
+        assertEquals(len, Os.sendto(sendFd, msg, 0, len, 0, to));
+        byte[] received = new byte[msg.length + 42];
+        InetSocketAddress from = new InetSocketAddress();
+        assertEquals(len, Os.recvfrom(recvFd, received, 0, received.length, 0, from));
+        assertEquals(loopback, from.getAddress());
+    }
+
+    public void test_sendtoSocketAddress_af_inet() throws Exception {
+        checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
+    }
+
+    public void test_sendtoSocketAddress_af_inet6() throws Exception {
+        checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
+    }
+
+    public void test_socketFamilies() throws Exception {
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        Os.bind(fd, InetAddress.getByName("::"), 0);
+        InetSocketAddress localSocketAddress = (InetSocketAddress) Os.getsockname(fd);
+        assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
+
+        fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        Os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
+        localSocketAddress = (InetSocketAddress) Os.getsockname(fd);
+        assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
+
+        fd = Os.socket(AF_INET, SOCK_STREAM, 0);
+        Os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
+        localSocketAddress = (InetSocketAddress) Os.getsockname(fd);
+        assertEquals(Inet4Address.ANY, localSocketAddress.getAddress());
+        try {
+            Os.bind(fd, InetAddress.getByName("::"), 0);
+            fail("Expected ErrnoException binding IPv4 socket to ::");
+        } catch (ErrnoException expected) {
+            assertEquals("Expected EAFNOSUPPORT binding IPv4 socket to ::", EAFNOSUPPORT,
+                    expected.errno);
+        }
+    }
+
+    private static void assertArrayEquals(byte[] expected, byte[] actual) {
+        assertTrue("Expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual),
+                Arrays.equals(expected, actual));
+    }
+
+    private static void checkSocketPing(FileDescriptor fd, InetAddress to, byte[] packet,
+            byte type, byte responseType, boolean useSendto) throws Exception {
+        int len = packet.length;
+        packet[0] = type;
+        if (useSendto) {
+            assertEquals(len, Os.sendto(fd, packet, 0, len, 0, to, 0));
+        } else {
+            Os.connect(fd, to, 0);
+            assertEquals(len, Os.sendto(fd, packet, 0, len, 0, null, 0));
+        }
+
+        int icmpId = ((InetSocketAddress) Os.getsockname(fd)).getPort();
+        byte[] received = new byte[4096];
+        InetSocketAddress srcAddress = new InetSocketAddress();
+        assertEquals(len, Os.recvfrom(fd, received, 0, received.length, 0, srcAddress));
+        assertEquals(to, srcAddress.getAddress());
+        assertEquals(responseType, received[0]);
+        assertEquals(received[4], (byte) (icmpId >> 8));
+        assertEquals(received[5], (byte) (icmpId & 0xff));
+
+        received = Arrays.copyOf(received, len);
+        received[0] = (byte) type;
+        received[2] = received[3] = 0;  // Checksum.
+        received[4] = received[5] = 0;  // ICMP ID.
+        assertArrayEquals(packet, received);
+    }
+
+    public void test_socketPing() throws Exception {
+        final byte ICMP_ECHO = 8, ICMP_ECHOREPLY = 0;
+        final byte ICMPV6_ECHO_REQUEST = (byte) 128, ICMPV6_ECHO_REPLY = (byte) 129;
+        final byte[] packet = ("\000\000\000\000" +  // ICMP type, code.
+                "\000\000\000\003" +  // ICMP ID (== port), sequence number.
+                "Hello myself").getBytes(StandardCharsets.US_ASCII);
+
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
+        InetAddress ipv6Loopback = InetAddress.getByName("::1");
+        checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, true);
+        checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, false);
+
+        fd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+        InetAddress ipv4Loopback = InetAddress.getByName("127.0.0.1");
+        checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, true);
+        checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
+    }
+
+    public void test_Ipv4Fallback() throws Exception {
+        // This number of iterations gives a ~60% chance of creating the conditions that caused
+        // http://b/23088314 without making test times too long. On a hammerhead running MRZ37C
+        // using vogar, this test takes about 4s.
+        final int ITERATIONS = 10000;
+        for (int i = 0; i < ITERATIONS; i++) {
+            FileDescriptor mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+            try {
+                Os.bind(mUdpSock, Inet4Address.ANY, 0);
+            } catch (ErrnoException e) {
+                fail("ErrnoException after " + i + " iterations: " + e);
+            } finally {
+                Os.close(mUdpSock);
+            }
+        }
+    }
+
+    public void test_unlink() throws Exception {
+        File f = File.createTempFile("OsTest", "tst");
+        assertTrue(f.exists());
+        Os.unlink(f.getAbsolutePath());
+        assertFalse(f.exists());
+
+        try {
+            Os.unlink(f.getAbsolutePath());
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(OsConstants.ENOENT, e.errno);
+        }
+    }
+
+    // b/27294715
+    public void test_recvfrom_concurrentShutdown() throws Exception {
+        final FileDescriptor serverFd = Os.socket(AF_INET, SOCK_DGRAM, 0);
+        Os.bind(serverFd, InetAddress.getByName("127.0.0.1"), 0);
+        // Set 4s timeout
+        StructTimeval tv = StructTimeval.fromMillis(4000);
+        Os.setsockoptTimeval(serverFd, SOL_SOCKET, SO_RCVTIMEO, tv);
+
+        final AtomicReference<Exception> killerThreadException = new AtomicReference<Exception>(
+                null);
+        final Thread killer = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    Thread.sleep(2000);
+                    try {
+                        Os.shutdown(serverFd, SHUT_RDWR);
+                    } catch (ErrnoException expected) {
+                        if (OsConstants.ENOTCONN != expected.errno) {
+                            killerThreadException.set(expected);
+                        }
+                    }
+                } catch (Exception ex) {
+                    killerThreadException.set(ex);
+                }
+            }
+        });
+        killer.start();
+
+        ByteBuffer buffer = ByteBuffer.allocate(16);
+        InetSocketAddress srcAddress = new InetSocketAddress();
+        int received = Os.recvfrom(serverFd, buffer, 0, srcAddress);
+        assertTrue(received == 0);
+        Os.close(serverFd);
+
+        killer.join();
+        assertNull(killerThreadException.get());
+    }
+
+    public void test_xattr() throws Exception {
+        final String NAME_TEST = "user.meow";
+
+        final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
+        final byte[] VALUE_PIE = "pie".getBytes(StandardCharsets.UTF_8);
+
+        File file = File.createTempFile("xattr", "test");
+        String path = file.getAbsolutePath();
+
+        try {
+            try {
+                Os.getxattr(path, NAME_TEST);
+                fail("Expected ENODATA");
+            } catch (ErrnoException e) {
+                assertEquals(OsConstants.ENODATA, e.errno);
+            }
+            assertFalse(Arrays.asList(Os.listxattr(path)).contains(NAME_TEST));
+
+            Os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
+            byte[] xattr_create = Os.getxattr(path, NAME_TEST);
+            assertTrue(Arrays.asList(Os.listxattr(path)).contains(NAME_TEST));
+            assertEquals(VALUE_CAKE.length, xattr_create.length);
+            assertStartsWith(VALUE_CAKE, xattr_create);
+
+            try {
+                Os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_CREATE);
+                fail("Expected EEXIST");
+            } catch (ErrnoException e) {
+                assertEquals(OsConstants.EEXIST, e.errno);
+            }
+
+            Os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_REPLACE);
+            byte[] xattr_replace = Os.getxattr(path, NAME_TEST);
+            assertTrue(Arrays.asList(Os.listxattr(path)).contains(NAME_TEST));
+            assertEquals(VALUE_PIE.length, xattr_replace.length);
+            assertStartsWith(VALUE_PIE, xattr_replace);
+
+            Os.removexattr(path, NAME_TEST);
+            try {
+                Os.getxattr(path, NAME_TEST);
+                fail("Expected ENODATA");
+            } catch (ErrnoException e) {
+                assertEquals(OsConstants.ENODATA, e.errno);
+            }
+            assertFalse(Arrays.asList(Os.listxattr(path)).contains(NAME_TEST));
+
+        } finally {
+            file.delete();
+        }
+    }
+
+    public void test_xattr_NPE() throws Exception {
+        File file = File.createTempFile("xattr", "test");
+        final String path = file.getAbsolutePath();
+        final String NAME_TEST = "user.meow";
+        final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
+
+        // getxattr
+        try {
+            Os.getxattr(null, NAME_TEST);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            Os.getxattr(path, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        // listxattr
+        try {
+            Os.listxattr(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        // removexattr
+        try {
+            Os.removexattr(null, NAME_TEST);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            Os.removexattr(path, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        // setxattr
+        try {
+            Os.setxattr(null, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            Os.setxattr(path, null, VALUE_CAKE, OsConstants.XATTR_CREATE);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            Os.setxattr(path, NAME_TEST, null, OsConstants.XATTR_CREATE);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void test_xattr_Errno() throws Exception {
+        final String NAME_TEST = "user.meow";
+        final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
+
+        // ENOENT, No such file or directory.
+        try {
+            Os.getxattr("", NAME_TEST);
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(ENOENT, e.errno);
+        }
+        try {
+            Os.listxattr("");
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(ENOENT, e.errno);
+        }
+        try {
+            Os.removexattr("", NAME_TEST);
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(ENOENT, e.errno);
+        }
+        try {
+            Os.setxattr("", NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(ENOENT, e.errno);
+        }
+
+        // ENOTSUP, Extended attributes are not supported by the filesystem, or are disabled.
+        // Since kernel version 4.9 (or some other version after 4.4), *xattr() methods
+        // may set errno to EACCESS instead. This behavior change is likely related to
+        // https://patchwork.kernel.org/patch/9294421/ which reimplemented getxattr, setxattr,
+        // and removexattr on top of generic handlers.
+        final String path = "/proc/self/stat";
+        try {
+            Os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
+            fail();
+        } catch (ErrnoException e) {
+            assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
+        }
+        try {
+            Os.getxattr(path, NAME_TEST);
+            fail();
+        } catch (ErrnoException e) {
+            assertEquals(ENOTSUP, e.errno);
+        }
+        try {
+            // Linux listxattr does not set errno.
+            Os.listxattr(path);
+        } catch (ErrnoException e) {
+            fail();
+        }
+        try {
+            Os.removexattr(path, NAME_TEST);
+            fail();
+        } catch (ErrnoException e) {
+            assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
+        }
+    }
+
+    public void test_realpath() throws Exception {
+        File tmpDir = new File(System.getProperty("java.io.tmpdir"));
+        // This is a chicken and egg problem. We have no way of knowing whether
+        // the temporary directory or one of its path elements were symlinked, so
+        // we'll need this call to realpath.
+        String canonicalTmpDir = Os.realpath(tmpDir.getAbsolutePath());
+
+        // Test that "." and ".." are resolved correctly.
+        assertEquals(canonicalTmpDir,
+                Os.realpath(canonicalTmpDir + "/./../" + tmpDir.getName()));
+
+        // Test that symlinks are resolved correctly.
+        File target = new File(tmpDir, "target");
+        File link = new File(tmpDir, "link");
+        try {
+            assertTrue(target.createNewFile());
+            Os.symlink(target.getAbsolutePath(), link.getAbsolutePath());
+
+            assertEquals(canonicalTmpDir + "/target",
+                    Os.realpath(canonicalTmpDir + "/link"));
+        } finally {
+            boolean deletedTarget = target.delete();
+            boolean deletedLink = link.delete();
+            // Asserting this here to provide a definitive reason for
+            // a subsequent failure on the same run.
+            assertTrue("deletedTarget = " + deletedTarget + ", deletedLink =" + deletedLink,
+                    deletedTarget && deletedLink);
+        }
+    }
+
+    /**
+     * Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
+     * that it behaves as expected.
+     */
+    public void test_socket_tcpUserTimeout_setAndGet() throws Exception {
+        final FileDescriptor fd = Os.socket(AF_INET, SOCK_STREAM, 0);
+        try {
+            int v = Os.getsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT);
+            assertEquals(0, v); // system default value
+            int newValue = 3000;
+            Os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
+                    newValue);
+            int actualValue = Os.getsockoptInt(fd, OsConstants.IPPROTO_TCP,
+                    OsConstants.TCP_USER_TIMEOUT);
+            // The kernel can round the requested value based on the HZ setting. We allow up to 10ms
+            // difference.
+            assertTrue("Returned incorrect timeout:" + actualValue,
+                    Math.abs(newValue - actualValue) <= 10);
+            // No need to reset the value to 0, since we're throwing the socket away
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_tcpUserTimeout_doesNotWorkOnDatagramSocket() throws Exception {
+        final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
+        try {
+            Os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
+                    3000);
+            fail("datagram (connectionless) sockets shouldn't support TCP_USER_TIMEOUT");
+        } catch (ErrnoException expected) {
+            // expected
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_sockoptTimeval_readWrite() throws Exception {
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        try {
+            StructTimeval v = Os.getsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO);
+            assertEquals(0, v.toMillis()); // system default value
+
+            StructTimeval newValue = StructTimeval.fromMillis(3000);
+            Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, newValue);
+
+            StructTimeval actualValue = Os.getsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO);
+
+            // The kernel can round the requested value based on the HZ setting. We allow up to 10ms
+            // difference.
+            assertTrue("Returned incorrect timeout:" + actualValue,
+                    Math.abs(newValue.toMillis() - actualValue.toMillis()) <= 10);
+            // No need to reset the value to 0, since we're throwing the socket away
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_setSockoptTimeval_effective() throws Exception {
+        int timeoutValueMillis = 50;
+        int allowedTimeoutMillis = 500;
+
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+        try {
+            StructTimeval tv = StructTimeval.fromMillis(timeoutValueMillis);
+            Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, tv);
+            Os.bind(fd, InetAddress.getByName("::1"), 0);
+
+            byte[] request = new byte[1];
+            long startTime = System.nanoTime();
+            expectException(() -> Os.read(fd, request, 0, request.length),
+                    ErrnoException.class, EAGAIN, "Expected timeout");
+            long endTime = System.nanoTime();
+            assertTrue(Duration.ofNanos(endTime - startTime).toMillis() < allowedTimeoutMillis);
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_setSockoptTimeval_nullFd() throws Exception {
+        StructTimeval tv = StructTimeval.fromMillis(500);
+        expectException(
+                () -> Os.setsockoptTimeval(null, SOL_SOCKET, SO_RCVTIMEO, tv),
+                ErrnoException.class, EBADF, "setsockoptTimeval(null, ...)");
+    }
+
+    public void test_socket_setSockoptTimeval_fileFd() throws Exception {
+        File testFile = createTempFile("test_socket_setSockoptTimeval_invalidFd", "");
+        try (FileInputStream fis = new FileInputStream(testFile)) {
+            final FileDescriptor fd = fis.getFD();
+
+            StructTimeval tv = StructTimeval.fromMillis(500);
+            expectException(
+                    () -> Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, tv),
+                    ErrnoException.class, ENOTSOCK, "setsockoptTimeval(<file fd>, ...)");
+        }
+    }
+
+    public void test_socket_setSockoptTimeval_badFd() throws Exception {
+        StructTimeval tv = StructTimeval.fromMillis(500);
+        FileDescriptor invalidFd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        Os.close(invalidFd);
+
+        expectException(
+                () -> Os.setsockoptTimeval(invalidFd, SOL_SOCKET, SO_RCVTIMEO, tv),
+                ErrnoException.class, EBADF, "setsockoptTimeval(<closed fd>, ...)");
+    }
+
+    public void test_socket_setSockoptTimeval_invalidLevel() throws Exception {
+        StructTimeval tv = StructTimeval.fromMillis(500);
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        try {
+            expectException(
+                    () -> Os.setsockoptTimeval(fd, -1, SO_RCVTIMEO, tv),
+                    ErrnoException.class, ENOPROTOOPT,
+                    "setsockoptTimeval(fd, <invalid level>, ...)");
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_setSockoptTimeval_invalidOpt() throws Exception {
+        StructTimeval tv = StructTimeval.fromMillis(500);
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        try {
+            expectException(
+                    () -> Os.setsockoptTimeval(fd, SOL_SOCKET, -1, tv),
+                    ErrnoException.class, ENOPROTOOPT,
+                    "setsockoptTimeval(fd, <invalid level>, ...)");
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_setSockoptTimeval_nullTimeVal() throws Exception {
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        try {
+            expectException(
+                    () -> Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, null),
+                    NullPointerException.class, null, "setsockoptTimeval(..., null)");
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_socket_getSockoptTimeval_invalidOption() throws Exception {
+        FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
+        try {
+            expectException(
+                    () -> Os.getsockoptTimeval(fd, SOL_SOCKET, SO_DEBUG),
+                    IllegalArgumentException.class, null,
+                    "getsockoptTimeval(..., <non-timeval option>)");
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    public void test_if_nametoindex_if_indextoname() throws Exception {
+        List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
+
+        assertTrue(nis.size() > 0);
+        for (NetworkInterface ni : nis) {
+            int index = ni.getIndex();
+            String name = ni.getName();
+            assertEquals(index, Os.if_nametoindex(name));
+            assertTrue(Os.if_indextoname(index).equals(name));
+        }
+
+        assertEquals(0, Os.if_nametoindex("this-interface-does-not-exist"));
+        assertEquals(null, Os.if_indextoname(-1000));
+
+        try {
+            Os.if_nametoindex(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    private static void assertStartsWith(byte[] expectedContents, byte[] container) {
+        for (int i = 0; i < expectedContents.length; i++) {
+            if (expectedContents[i] != container[i]) {
+                fail("Expected " + Arrays.toString(expectedContents) + " but found "
+                        + Arrays.toString(expectedContents));
+            }
+        }
+    }
+
+    public void test_readlink() throws Exception {
+        File path = new File(IoUtils.createTemporaryDirectory("test_readlink"), "symlink");
+
+        // ext2 and ext4 have PAGE_SIZE limits on symlink targets.
+        // If file encryption is enabled, there's extra overhead to store the
+        // size of the encrypted symlink target. There's also an off-by-one
+        // in current kernels (and marlin/sailfish where we're seeing this
+        // failure are still on 3.18, far from current). Given that we don't
+        // really care here, just use 2048 instead. http://b/33306057.
+        int size = 2048;
+        String xs = "";
+        for (int i = 0; i < size - 1; ++i) {
+            xs += "x";
+        }
+
+        Os.symlink(xs, path.getPath());
+
+        assertEquals(xs, Os.readlink(path.getPath()));
+    }
+
+    // Address should be correctly set for empty packets. http://b/33481605
+    public void test_recvfrom_EmptyPacket() throws Exception {
+        try (DatagramSocket ds = new DatagramSocket();
+             DatagramSocket srcSock = new DatagramSocket()) {
+            srcSock.send(new DatagramPacket(new byte[0], 0, ds.getLocalSocketAddress()));
+
+            byte[] recvBuf = new byte[16];
+            InetSocketAddress address = new InetSocketAddress();
+            int recvCount =
+                    android.system.Os.recvfrom(ds.getFileDescriptor$(), recvBuf, 0, 16, 0, address);
+            assertEquals(0, recvCount);
+            assertTrue(address.getAddress().isLoopbackAddress());
+            assertEquals(srcSock.getLocalPort(), address.getPort());
+        }
+    }
+
+    public void test_fstat_times() throws Exception {
+        File file = File.createTempFile("OsTest", "fstattest");
+        FileOutputStream fos = new FileOutputStream(file);
+        StructStat structStat1 = Os.fstat(fos.getFD());
+        assertEquals(structStat1.st_mtim.tv_sec, structStat1.st_mtime);
+        assertEquals(structStat1.st_ctim.tv_sec, structStat1.st_ctime);
+        assertEquals(structStat1.st_atim.tv_sec, structStat1.st_atime);
+        Thread.sleep(100);
+        fos.write(new byte[] { 1, 2, 3 });
+        fos.flush();
+        StructStat structStat2 = Os.fstat(fos.getFD());
+        fos.close();
+
+        assertEquals(-1, structStat1.st_mtim.compareTo(structStat2.st_mtim));
+        assertEquals(-1, structStat1.st_ctim.compareTo(structStat2.st_ctim));
+        assertEquals(0, structStat1.st_atim.compareTo(structStat2.st_atim));
+    }
+
+    public void test_getrlimit() throws Exception {
+        StructRlimit rlimit = Os.getrlimit(OsConstants.RLIMIT_NOFILE);
+        // We can't really make any assertions about these values since they might vary from
+        // device to device and even process to process. We do know that they will be greater
+        // than zero, though.
+        assertTrue(rlimit.rlim_cur > 0);
+        assertTrue(rlimit.rlim_max > 0);
+    }
+
+    // http://b/65051835
+    public void test_pipe2_errno() throws Exception {
+        try {
+            // flag=-1 is not a valid value for pip2, will EINVAL
+            Os.pipe2(-1);
+            fail();
+        } catch (ErrnoException expected) {
+        }
+    }
+
+    // http://b/65051835
+    public void test_sendfile_errno() throws Exception {
+        try {
+            // FileDescriptor.out is not open for input, will cause EBADF
+            Int64Ref offset = new Int64Ref(10);
+            Os.sendfile(FileDescriptor.out, FileDescriptor.out, offset, 10);
+            fail();
+        } catch (ErrnoException expected) {
+        }
+    }
+
+    public void test_sendfile_null() throws Exception {
+        File in = createTempFile("test_sendfile_null", "Hello, world!");
+        try {
+            int len = "Hello".length();
+            assertEquals("Hello", checkSendfile(in, null, len, null));
+        } finally {
+            in.delete();
+        }
+    }
+
+    public void test_sendfile_offset() throws Exception {
+        File in = createTempFile("test_sendfile_offset", "Hello, world!");
+        try {
+            // checkSendfile(sendFileImplToUse, in, startOffset, maxBytes, expectedEndOffset)
+            assertEquals("Hello", checkSendfile(in, 0L, 5, 5L));
+            assertEquals("ello,", checkSendfile(in, 1L, 5, 6L));
+            // At offset 9, only 4 bytes/chars available, even though we're asking for 5.
+            assertEquals("rld!", checkSendfile(in, 9L, 5, 13L));
+            assertEquals("", checkSendfile(in, 1L, 0, 1L));
+        } finally {
+            in.delete();
+        }
+    }
+
+    private static String checkSendfile(File in, Long startOffset,
+            int maxBytes, Long expectedEndOffset) throws IOException, ErrnoException {
+        File out = File.createTempFile(OsTest.class.getSimpleName() + "_checkSendFile", ".out");
+        try (FileInputStream inStream = new FileInputStream(in)) {
+            FileDescriptor inFd = inStream.getFD();
+            try (FileOutputStream outStream = new FileOutputStream(out)) {
+                FileDescriptor outFd = outStream.getFD();
+                Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
+                android.system.Os.sendfile(outFd, inFd, offset, maxBytes);
+                assertEquals(expectedEndOffset, offset == null ? null : offset.value);
+            }
+            return IoUtils.readFileAsString(out.getPath());
+        } finally {
+            out.delete();
+        }
+    }
+
+    private static File createTempFile(String namePart, String contents) throws IOException {
+        File f = File.createTempFile(OsTest.class.getSimpleName() + namePart, ".in");
+        try (FileWriter writer = new FileWriter(f)) {
+            writer.write(contents);
+        }
+        return f;
+    }
+
+    public void test_odirect() throws Exception {
+        File testFile = createTempFile("test_odirect", "");
+        try {
+            FileDescriptor fd =
+                    Os.open(testFile.toString(), O_WRONLY | O_DIRECT, S_IRUSR | S_IWUSR);
+            assertNotNull(fd);
+            assertTrue(fd.valid());
+            int flags = Os.fcntlVoid(fd, F_GETFL);
+            assertTrue("Expected file flags to include " + O_DIRECT + ", actual value: " + flags,
+                    0 != (flags & O_DIRECT));
+            Os.close(fd);
+        } finally {
+            testFile.delete();
+        }
+    }
+
+    public void test_splice() throws Exception {
+        FileDescriptor[] pipe = Os.pipe2(0);
+        File in = createTempFile("splice1", "foobar");
+        File out = createTempFile("splice2", "");
+
+        Int64Ref offIn = new Int64Ref(1);
+        Int64Ref offOut = new Int64Ref(0);
+
+        // Splice into pipe
+        try (FileInputStream streamIn = new FileInputStream(in)) {
+            FileDescriptor fdIn = streamIn.getFD();
+            long result = Os
+                    .splice(fdIn, offIn, pipe[1], null /* offOut */, 10 /* len */, 0 /* flags */);
+            assertEquals(5, result);
+            assertEquals(6, offIn.value);
+        }
+
+        // Splice from pipe
+        try (FileOutputStream streamOut = new FileOutputStream(out)) {
+            FileDescriptor fdOut = streamOut.getFD();
+            long result = Os
+                    .splice(pipe[0], null /* offIn */, fdOut, offOut, 10 /* len */, 0 /* flags */);
+            assertEquals(5, result);
+            assertEquals(5, offOut.value);
+        }
+
+        assertEquals("oobar", IoUtils.readFileAsString(out.getPath()));
+
+        Os.close(pipe[0]);
+        Os.close(pipe[1]);
+    }
+
+    public void test_splice_errors() throws Exception {
+        File in = createTempFile("splice3", "");
+        File out = createTempFile("splice4", "");
+        FileDescriptor[] pipe = Os.pipe2(0);
+
+        //.fdIn == null
+        try {
+            Os.splice(null /* fdIn */, null /* offIn */, pipe[1],
+                    null /*offOut*/, 10 /* len */, 0 /* flags */);
+            fail();
+        } catch (ErrnoException expected) {
+            assertEquals(EBADF, expected.errno);
+        }
+
+        //.fdOut == null
+        try {
+            Os.splice(pipe[0] /* fdIn */, null /* offIn */, null  /* fdOut */,
+                    null /*offOut*/, 10 /* len */, 0 /* flags */);
+            fail();
+        } catch (ErrnoException expected) {
+            assertEquals(EBADF, expected.errno);
+        }
+
+        // No pipe fd
+        try (FileOutputStream streamOut = new FileOutputStream(out)) {
+            try (FileInputStream streamIn = new FileInputStream(in)) {
+                FileDescriptor fdIn = streamIn.getFD();
+                FileDescriptor fdOut = streamOut.getFD();
+                Os.splice(fdIn, null  /* offIn */, fdOut, null /* offOut */, 10 /* len */,
+                        0 /* flags */);
+                fail();
+            } catch (ErrnoException expected) {
+                assertEquals(EINVAL, expected.errno);
+            }
+        }
+
+        Os.close(pipe[0]);
+        Os.close(pipe[1]);
+    }
+
+    public void testCloseNullFileDescriptor() throws Exception {
+        try {
+            Os.close(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testSocketpairNullFileDescriptor1() throws Exception {
+        try {
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, new FileDescriptor());
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testSocketpairNullFileDescriptor2() throws Exception {
+        try {
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, new FileDescriptor(), null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testSocketpairNullFileDescriptorBoth() throws Exception {
+        try {
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testInetPtonIpv4() {
+        String srcAddress = "127.0.0.1";
+        InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
+        assertEquals(srcAddress, inetAddress.getHostAddress());
+    }
+
+    public void testInetPtonIpv6() {
+        String srcAddress = "1123:4567:89ab:cdef:fedc:ba98:7654:3210";
+        InetAddress inetAddress = Os.inet_pton(AF_INET6, srcAddress);
+        assertEquals(srcAddress, inetAddress.getHostAddress());
+    }
+
+    public void testInetPtonInvalidFamily() {
+        String srcAddress = "127.0.0.1";
+        InetAddress inetAddress = Os.inet_pton(AF_UNIX, srcAddress);
+        assertNull(inetAddress);
+    }
+
+    public void testInetPtonWrongFamily() {
+        String srcAddress = "127.0.0.1";
+        InetAddress inetAddress = Os.inet_pton(AF_INET6, srcAddress);
+        assertNull(inetAddress);
+    }
+
+    public void testInetPtonInvalidData() {
+        String srcAddress = "10.1";
+        InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
+        assertNull(inetAddress);
+    }
+}
diff --git a/luni/src/test/java/libcore/android/system/StructTimevalTest.java b/luni/src/test/java/libcore/android/system/StructTimevalTest.java
new file mode 100644
index 0000000..f427980
--- /dev/null
+++ b/luni/src/test/java/libcore/android/system/StructTimevalTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 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.android.system;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.system.StructTimeval;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+
+/**
+ * Unit test for {@link StructTimeval}
+ */
+@RunWith(JUnitParamsRunner.class)
+public class StructTimevalTest {
+
+    private static final long MS_PER_SEC = 1000L;
+    private static final long US_PER_MS = 1000L;
+    private static final long US_PER_SEC = US_PER_MS * MS_PER_SEC;
+
+    public static Object[][] interestingMillisValues() {
+        // An array of { testMillisValue, expectedSeconds, expectedMicros }
+        return new Object[][] {
+                { 0L, 0L, 0L },
+
+                // +ve and -ve cases close to zero seconds.
+                { 23L, 0L, 23L * US_PER_MS /* 23000 */ },
+                { -23L, -1L, US_PER_SEC - (23L * US_PER_MS) /* 977000 */ },
+
+                // +ve and -ve cases with non-zero seconds.
+                { 2003L, 2L, 3L * US_PER_MS /* 3000 */ },
+                { -2003L, -3L, US_PER_SEC - (3L * US_PER_MS) /* 997000 */ },
+
+                // Check for overflow.
+                { Long.MAX_VALUE, /* 9223372036854775807 */
+                        Long.MAX_VALUE / MS_PER_SEC, /* 9223372036854775 */
+                        (Long.MAX_VALUE % MS_PER_SEC) * US_PER_MS, /* 807000 */
+                },
+
+                // Check for underflow. [Note: In Java (-ve % +ve) generates a -ve result]
+                { Long.MIN_VALUE, /* -9223372036854775808 */
+                        (Long.MIN_VALUE / MS_PER_SEC) - 1L, /* -9223372036854776 */
+                        US_PER_SEC - (-(Long.MIN_VALUE % MS_PER_SEC) * US_PER_MS), /* 192000 */
+                },
+        };
+    }
+
+    @Parameters(method = "interestingMillisValues")
+    @Test
+    public void fromToMillis(long millisValue, long expectedSeconds, long expectedMicros) {
+        StructTimeval val = StructTimeval.fromMillis(millisValue);
+
+        assertEquals(expectedSeconds, val.tv_sec);
+        assertEquals(expectedMicros, val.tv_usec);
+
+        assertEquals(millisValue, val.toMillis());
+    }
+
+    @Test
+    public void testEqualsAndHashcode() {
+        Object[][] millisValues = interestingMillisValues();
+        StructTimeval[] timeVals = new StructTimeval[millisValues.length];
+
+        for (int i = 0; i < millisValues.length; i++) {
+            long millisValue = (long) millisValues[i][0];
+            StructTimeval value1 = StructTimeval.fromMillis(millisValue);
+            StructTimeval value2 = StructTimeval.fromMillis(millisValue);
+
+            assertEquals("value1.equals(value1)", value1, value1);
+            assertEquals("value1.equals(value2)", value1, value2);
+            assertEquals("value2.equals(value1)", value2, value1);
+
+            assertEquals("value1.hashCode() == value2.hashCode()",
+                    value1.hashCode(), value2.hashCode());
+
+            timeVals[i] = value1;
+        }
+
+        for (int i = 0; i < millisValues.length; i++) {
+            StructTimeval iVal = timeVals[i];
+            for (int j = i + 1; j < millisValues.length; j++) {
+                StructTimeval jVal = timeVals[j];
+                assertFalse(iVal.equals(jVal));
+                assertFalse(jVal.equals(iVal));
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
index e7421b7..84f7f71 100644
--- a/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/BaseDexClassLoaderTest.java
@@ -16,72 +16,325 @@
 
 package libcore.dalvik.system;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import dalvik.system.BaseDexClassLoader;
+import dalvik.system.DelegateLastClassLoader;
 import dalvik.system.PathClassLoader;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.InputStream;
-import java.util.List;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
 
 import libcore.io.Streams;
 
-import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
-public final class BaseDexClassLoaderTest extends TestCase {
+@RunWith(JUnit4.class)
+public final class BaseDexClassLoaderTest {
     private static class Reporter implements BaseDexClassLoader.Reporter {
-        public List<BaseDexClassLoader> classLoaders = new ArrayList<>();
-        public List<String> loadedDexPaths = new ArrayList<>();
+        public final List<ClassLoader> classLoaders = new ArrayList<>();
+        public final List<String> loadedDexPaths = new ArrayList<>();
 
         @Override
-        public void report(List<BaseDexClassLoader> loaders, List<String> dexPaths) {
+        public void report(List<ClassLoader> loaders, List<String> dexPaths) {
             classLoaders.addAll(loaders);
             loadedDexPaths.addAll(dexPaths);
         }
+
+        void reset() {
+            classLoaders.clear();
+            loadedDexPaths.clear();
+        }
     }
 
-    public void testReporting() throws Exception {
+    private ClassLoader pcl;
+    private File jar;
+    private Reporter reporter;
+
+    // For resources that we will load in this test. We're re-using parent.jar and child.jar
+    // from DelegateLastClassLoaderTest for convenience.
+    private Map<String, File> resourcesMap;
+
+    @Before
+    public void setupResourcesMap() throws Exception {
+        resourcesMap = ClassLoaderTestSupport.setupAndCopyResources(
+                Arrays.asList("parent.jar", "child.jar"));
+    }
+
+    @After
+    public void cleanupResourcesMap() throws Exception {
+        ClassLoaderTestSupport.cleanUpResources(resourcesMap);
+    }
+
+    @Before
+    public void extractTestJar() throws Exception {
         // Extract loading-test.jar from the resource.
-        ClassLoader pcl = BaseDexClassLoaderTest.class.getClassLoader();
-        File jar = File.createTempFile("loading-test", ".jar");
+        pcl = BaseDexClassLoaderTest.class.getClassLoader();
+        jar = File.createTempFile("loading-test", ".jar");
         try (InputStream in = pcl.getResourceAsStream("dalvik/system/loading-test.jar");
              FileOutputStream out = new FileOutputStream(jar)) {
           Streams.copy(in, out);
         }
+    }
 
-        // Set the reporter.
-        Reporter reporter = new Reporter();
+    @Before
+    public void registerReporter() {
+        reporter = new Reporter();
         BaseDexClassLoader.setReporter(reporter);
+    }
+
+    @After
+    public void unregisterReporter() {
+        BaseDexClassLoader.setReporter(null);
+    }
+
+    @After
+    public void deleteTestJar() throws Exception {
+        assertTrue(jar.delete());
+    }
+
+    @Test
+    public void testReporting() throws Exception {
         // Load the jar file using a PathClassLoader.
         BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(),
             ClassLoader.getSystemClassLoader());
 
-        // Verify the reporter files.
+        // Verify the reported data.
         assertEquals(2, reporter.loadedDexPaths.size());
         assertEquals(2, reporter.classLoaders.size());
 
         // First class loader should be the one loading the files
         assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
         assertEquals(cl1, reporter.classLoaders.get(0));
+
         // Second class loader should be the system class loader.
         // Don't check the actual classpath as that might vary based on system properties.
         assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(1));
+    }
 
-        // Reset the reporter and check we don't report anymore.
-        BaseDexClassLoader.setReporter(null);
+    @Test
+    public void testReportingUnknownLoader() throws Exception {
+        // Add an unknown classloader between cl1 and the system
+        ClassLoader unknownLoader = new ClassLoader(ClassLoader.getSystemClassLoader()) {};
+        BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(), unknownLoader);
+
+        assertEquals(3, reporter.loadedDexPaths.size());
+        assertEquals(3, reporter.classLoaders.size());
+
+        assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
+        assertEquals(cl1, reporter.classLoaders.get(0));
+
+        assertNull(reporter.loadedDexPaths.get(1));
+        assertEquals(unknownLoader, reporter.classLoaders.get(1));
+
+        assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(2));
+    }
+
+    @Test
+    public void testNoReportingAfterResetting() throws Exception {
+        BaseDexClassLoader cl1 = new PathClassLoader(jar.getPath(),
+            ClassLoader.getSystemClassLoader());
+
+        assertEquals(2, reporter.loadedDexPaths.size());
+        assertEquals(2, reporter.classLoaders.size());
+
+        // Check we don't report after the reporter is unregistered.
+        unregisterReporter();
+        reporter.reset();
 
         // Load the jar file using another PathClassLoader.
         BaseDexClassLoader cl2 = new PathClassLoader(jar.getPath(), pcl);
 
-        // Verify the list reporter files did not change.
-        assertEquals(2, reporter.loadedDexPaths.size());
-        assertEquals(2, reporter.classLoaders.size());
+        // Verify nothing reported
+        assertEquals(0, reporter.loadedDexPaths.size());
+        assertEquals(0, reporter.classLoaders.size());
+    }
 
-        assertEquals(jar.getPath(), reporter.loadedDexPaths.get(0));
-        assertEquals(cl1, reporter.classLoaders.get(0));
-        assertEquals(ClassLoader.getSystemClassLoader(), reporter.classLoaders.get(1));
+    /* package */ static List<String> readResources(ClassLoader cl, String resourceName)
+            throws Exception {
+        Enumeration<URL> resources = cl.getResources(resourceName);
 
-        // Clean up the extracted jar file.
-        assertTrue(jar.delete());
+        List<String> contents = new ArrayList<>();
+        while (resources.hasMoreElements()) {
+            URL url = resources.nextElement();
+
+            try (InputStream is = url.openStream()) {
+                byte[] bytes = Streams.readFully(is);
+                contents.add(new String(bytes, StandardCharsets.UTF_8));
+            }
+        }
+
+        return contents;
+    }
+
+    /* package */ static String readResource(ClassLoader cl, String resourceName) throws Exception {
+        InputStream in = cl.getResourceAsStream(resourceName);
+        if (in == null) {
+            return null;
+        }
+
+        byte[] contents = Streams.readFully(in);
+        return new String(contents, StandardCharsets.UTF_8);
+    }
+
+    private void checkResources(ClassLoader loader) throws Exception {
+        List<String> resources = readResources(loader, "resource.txt");
+
+        assertEquals(2, resources.size());
+        assertTrue(resources.contains("parent"));
+        assertTrue(resources.contains("child"));
+
+        resources = readResources(loader, "resource2.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("parent2", resources.get(0));
+    }
+
+    @Test
+    public void testGetResourceSharedLibraries1() throws Exception {
+        File parentPath = resourcesMap.get("parent.jar");
+        File childPath = resourcesMap.get("child.jar");
+        assertTrue(parentPath != null);
+        assertTrue(childPath != null);
+
+        ClassLoader parent = Object.class.getClassLoader();
+
+        ClassLoader[] sharedLibraries = {
+          new PathClassLoader(parentPath.getAbsolutePath(), null, parent),
+          new PathClassLoader(childPath.getAbsolutePath(), null, parent),
+        };
+
+        // PCL[]{PCL[parent.jar]#PCL[child.jar]}
+        ClassLoader loader = new PathClassLoader("", null, parent, sharedLibraries);
+        assertEquals("parent", readResource(loader, "resource.txt"));
+        checkResources(loader);
+
+        // DLC[]{PCL[parent.jar]#PCL[child.jar]}
+        loader = new DelegateLastClassLoader("", null, parent, sharedLibraries);
+        assertEquals("parent", readResource(loader, "resource.txt"));
+        checkResources(loader);
+    }
+
+    @Test
+    public void testGetResourceSharedLibraries2() throws Exception {
+        File parentPath = resourcesMap.get("parent.jar");
+        File childPath = resourcesMap.get("child.jar");
+        assertTrue(parentPath != null);
+        assertTrue(childPath != null);
+
+        ClassLoader parent = Object.class.getClassLoader();
+
+        ClassLoader[] sharedLibraries = {
+          new PathClassLoader(childPath.getAbsolutePath(), null, parent),
+          new PathClassLoader(parentPath.getAbsolutePath(), null, parent),
+        };
+
+        // PCL[]{PCL[child.jar]#PCL[parent.jar]}
+        ClassLoader loader = new PathClassLoader("", null, parent, sharedLibraries);
+        assertEquals("child", readResource(loader, "resource.txt"));
+        checkResources(loader);
+
+        // DLC[]{PCL[child.jar]#PCL[parent.jar]}
+        loader = new DelegateLastClassLoader("", null, parent, sharedLibraries);
+        assertEquals("child", readResource(loader, "resource.txt"));
+        checkResources(loader);
+    }
+
+    @Test
+    public void testGetResourceSharedLibraries3() throws Exception {
+        File parentPath = resourcesMap.get("parent.jar");
+        File childPath = resourcesMap.get("child.jar");
+        assertTrue(parentPath != null);
+        assertTrue(childPath != null);
+
+        ClassLoader parent = Object.class.getClassLoader();
+
+        ClassLoader[] sharedLibraryLevel2 = {
+          new PathClassLoader(parentPath.getAbsolutePath(), null, parent),
+        };
+
+        ClassLoader[] sharedLibraryLevel1 = {
+          new PathClassLoader(childPath.getAbsolutePath(), null, parent, sharedLibraryLevel2),
+        };
+
+        // PCL[]{PCL[child.jar]{PCL[parent.jar]}}
+        ClassLoader loader = new PathClassLoader("", null, parent, sharedLibraryLevel1);
+        assertEquals("parent", readResource(loader, "resource.txt"));
+        checkResources(loader);
+
+        // DLC[]{PCL[child.jar]{PCL[parent.jar]}}
+        loader = new DelegateLastClassLoader("", null, parent, sharedLibraryLevel1);
+        assertEquals("parent", readResource(loader, "resource.txt"));
+        checkResources(loader);
+    }
+
+    @Test
+    public void testGetResourceSharedLibraries4() throws Exception {
+        File parentPath = resourcesMap.get("parent.jar");
+        File childPath = resourcesMap.get("child.jar");
+        assertTrue(parentPath != null);
+        assertTrue(childPath != null);
+
+        ClassLoader parent = Object.class.getClassLoader();
+
+        ClassLoader[] sharedLibraryLevel2 = {
+          new PathClassLoader(childPath.getAbsolutePath(), null, parent),
+        };
+
+        ClassLoader[] sharedLibraryLevel1 = {
+          new PathClassLoader(parentPath.getAbsolutePath(), null, parent, sharedLibraryLevel2),
+        };
+
+        // PCL[]{PCL[parent.jar]{PCL[child.jar]}}
+        ClassLoader loader = new PathClassLoader("", null, parent, sharedLibraryLevel1);
+        assertEquals("child", readResource(loader, "resource.txt"));
+        checkResources(loader);
+
+        // DLC[]{PCL[parent.jar]{PCL[child.jar]}}
+        loader = new DelegateLastClassLoader("", null, parent, sharedLibraryLevel1);
+        assertEquals("child", readResource(loader, "resource.txt"));
+        checkResources(loader);
+    }
+
+    @Test
+    public void testGetResourceSharedLibraries5() throws Exception {
+        File parentPath = resourcesMap.get("parent.jar");
+        File childPath = resourcesMap.get("child.jar");
+        assertTrue(parentPath != null);
+        assertTrue(childPath != null);
+
+        ClassLoader parentParent = Object.class.getClassLoader();
+        ClassLoader parent = new PathClassLoader(parentPath.getAbsolutePath(), null, parentParent);
+
+        ClassLoader[] sharedLibrary = {
+          new PathClassLoader(childPath.getAbsolutePath(), null, parentParent),
+        };
+
+        // PCL[]{PCL[child.jar]};PCL[parent.jar]
+        ClassLoader pathLoader = new PathClassLoader("", null, parent, sharedLibrary);
+
+        // Check that the parent was queried first.
+        assertEquals("parent", readResource(pathLoader, "resource.txt"));
+
+        // DLC[]{PCL[child.jar]};PCL[parent.jar]
+        ClassLoader delegateLast = new DelegateLastClassLoader("", null, parent, sharedLibrary);
+
+        // Check that the shared library was queried first.
+        assertEquals("child", readResource(delegateLast, "resource.txt"));
+
     }
 }
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/DelegateLastClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/DelegateLastClassLoaderTest.java
index a1102da..4267303 100644
--- a/luni/src/test/java/libcore/dalvik/system/DelegateLastClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/DelegateLastClassLoaderTest.java
@@ -94,6 +94,11 @@
     }
 
     private ClassLoader createClassLoader(String parentName, String thisName) {
+      return createClassLoader(parentName, thisName, true);
+    }
+
+    private ClassLoader createClassLoader(String parentName, String thisName,
+            boolean delegateResourceLoading) {
         File parentPath = resourcesMap.get(parentName);
         File thisPath = resourcesMap.get(thisName);
         assertNotNull(parentPath);
@@ -102,7 +107,8 @@
         ClassLoader parent = new PathClassLoader(parentPath.getAbsolutePath(),
                 Object.class.getClassLoader());
 
-        return new DelegateLastClassLoader(thisPath.getAbsolutePath(), parent);
+        return new DelegateLastClassLoader(thisPath.getAbsolutePath(), null, parent,
+            delegateResourceLoading);
     }
 
     private static String callMethod(ClassLoader cl, String name) throws Exception {
@@ -115,28 +121,12 @@
     }
 
     private static String readResource(ClassLoader cl, String resourceName) throws Exception {
-        InputStream in = cl.getResourceAsStream(resourceName);
-        assertNotNull(in);
-
-        byte[] contents = Streams.readFully(in);
-        return new String(contents, StandardCharsets.UTF_8);
+      return BaseDexClassLoaderTest.readResource(cl, resourceName);
     }
 
     private static List<String> readResources(ClassLoader cl, String resourceName)
             throws Exception {
-        Enumeration<URL> resources = cl.getResources(resourceName);
-
-        List<String> contents = new ArrayList<>();
-        while (resources.hasMoreElements()) {
-            URL url = resources.nextElement();
-
-            try (InputStream is = url.openStream()) {
-                byte[] bytes = Streams.readFully(is);
-                contents.add(new String(bytes, StandardCharsets.UTF_8));
-            }
-        }
-
-        return contents;
+      return BaseDexClassLoaderTest.readResources(cl, resourceName);
     }
 
     public void testLookupOrder_loadClass() throws Exception {
@@ -186,9 +176,21 @@
     public void testLookupOrder_getResource() throws Exception {
         ClassLoader delegate = createClassLoader("parent.jar", "child.jar");
         assertEquals("child", readResource(delegate, "resource.txt"));
+        assertEquals("parent2", readResource(delegate, "resource2.txt"));
 
         delegate = createClassLoader("child.jar", "parent.jar");
         assertEquals("parent", readResource(delegate, "resource.txt"));
+        assertEquals("parent2", readResource(delegate, "resource2.txt"));
+    }
+
+    public void testLookupOrderNodelegate_getResource() throws Exception {
+        ClassLoader delegate = createClassLoader("parent.jar", "child.jar", false);
+        assertEquals("child", readResource(delegate, "resource.txt"));
+        assertEquals(null, readResource(delegate, "resource2.txt"));
+
+        delegate = createClassLoader("child.jar", "parent.jar", false);
+        assertEquals("parent", readResource(delegate, "resource.txt"));
+        assertEquals("parent2", readResource(delegate, "resource2.txt"));
     }
 
     public void testLookupOrder_getResources() throws Exception {
@@ -207,6 +209,43 @@
         assertEquals("child", resources.get(1));
     }
 
+    public void testLookupOrder_getResources2() throws Exception {
+        ClassLoader delegate = createClassLoader("parent.jar", "child.jar");
+        List<String> resources = readResources(delegate, "resource2.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("parent2", resources.get(0));
+
+        delegate = createClassLoader("child.jar", "parent.jar");
+        resources = readResources(delegate, "resource2.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("parent2", resources.get(0));
+    }
+
+    public void testLookupOrderNoDelegate_getResources() throws Exception {
+        ClassLoader delegate = createClassLoader("parent.jar", "child.jar", false);
+        List<String> resources = readResources(delegate, "resource.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("child", resources.get(0));
+
+        resources = readResources(delegate, "resource2.txt");
+
+        assertEquals(0, resources.size());
+
+        delegate = createClassLoader("child.jar", "parent.jar", false);
+        resources = readResources(delegate, "resource.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("parent", resources.get(0));
+
+        resources = readResources(delegate, "resource2.txt");
+
+        assertEquals(1, resources.size());
+        assertEquals("parent2", resources.get(0));
+    }
+
     public void testLookupOrder_bootOverride() throws Exception {
         // The dex file in this jar contains a single class ("java.util.HashMap") and a single
         // resource ("android/icu/ICUConfig.properties"). Both of these appear in the boot
diff --git a/luni/src/test/java/libcore/dalvik/system/InMemoryDexClassLoaderTest.java b/luni/src/test/java/libcore/dalvik/system/InMemoryDexClassLoaderTest.java
index 8cda028..1012c9f 100644
--- a/luni/src/test/java/libcore/dalvik/system/InMemoryDexClassLoaderTest.java
+++ b/luni/src/test/java/libcore/dalvik/system/InMemoryDexClassLoaderTest.java
@@ -23,10 +23,14 @@
 import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.util.ArrayList;
 import libcore.io.Streams;
 import junit.framework.TestCase;
 
+import dalvik.system.BaseDexClassLoader;
 import dalvik.system.InMemoryDexClassLoader;
+import dalvik.system.DexPathList;
 
 /**
  * Tests for the class {@link InMemoryDexClassLoader}.
@@ -87,23 +91,74 @@
         }
     }
 
-    private static ByteBuffer ReadFileToByteBufferDirect(File file) throws IOException {
+    /**
+     * Helper to construct a direct ByteBuffer with the contents of a given file.
+     *
+     * Constructs a new direct ByteBuffer and inserts {@code paddingBefore} amount of
+     * zero padding followed by the contents of {@code file}. The buffer's position is
+     * set to the beginning of the file's data.
+     *
+     * @param file The file to be read
+     * @param paddingBefore Number of zero bytes to be inserted at the beginning of the buffer.
+     */
+    private static ByteBuffer readFileToByteBufferDirect(File file, int paddingBefore)
+            throws IOException {
         try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
-            ByteBuffer buffer = ByteBuffer.allocateDirect((int)file.length());
+            ByteBuffer buffer = ByteBuffer.allocateDirect(paddingBefore + (int)file.length());
+            buffer.put(new byte[paddingBefore]);
             int done = 0;
             while (done != file.length()) {
                 done += raf.getChannel().read(buffer);
             }
             buffer.rewind();
+            buffer.position(paddingBefore);
             return buffer;
         }
     }
 
-    private static ByteBuffer ReadFileToByteBufferIndirect(File file) throws IOException {
-        ByteBuffer direct = ReadFileToByteBufferDirect(file);
+    /**
+     * Helper to construct a direct ByteBuffer with the contents of a given file.
+     *
+     * Constructs a new direct ByteBuffer and the contents of {@code file}. The buffer's
+     * position is zero.
+     *
+     * @param file The file to be read
+     */
+    private static ByteBuffer readFileToByteBufferDirect(File file) throws IOException {
+        return readFileToByteBufferDirect(file, /* paddingBefore */ 0);
+    }
+
+    /**
+     * Helper to construct an indirect ByteBuffer with the contents of a given file.
+     *
+     * Constructs a new indirect ByteBuffer and inserts {@code paddingBefore} amount of
+     * zero padding followed by the contents of {@code file}. The buffer's position is
+     * set to the beginning of the file's data.
+     *
+     * @param file The file to be read
+     * @param paddingBefore Number of zero bytes to be inserted at the beginning of the buffer.
+     */
+    private static ByteBuffer readFileToByteBufferIndirect(File file, int paddingBefore)
+            throws IOException {
+        ByteBuffer direct = readFileToByteBufferDirect(file, paddingBefore);
+        direct.rewind();
         byte[] array = new byte[direct.limit()];
         direct.get(array);
-        return ByteBuffer.wrap(array);
+        ByteBuffer buf = ByteBuffer.wrap(array);
+        buf.position(paddingBefore);
+        return buf;
+    }
+
+    /**
+     * Helper to construct an indirect ByteBuffer with the contents of a given file.
+     *
+     * Constructs a new indirect ByteBuffer and the contents of {@code file}. The buffer's
+     * position is zero.
+     *
+     * @param file The file to be read
+     */
+    private static ByteBuffer readFileToByteBufferIndirect(File file) throws IOException {
+        return readFileToByteBufferIndirect(file, /* paddingBefore */ 0);
     }
 
     /**
@@ -114,13 +169,13 @@
      *
      * @param files The .dex files to use for the class path.
      */
-    private static ClassLoader createLoaderDirect(File... files) throws IOException {
+    private ClassLoader createLoaderDirect(File... files) throws IOException {
         assertNotNull(files);
         assertTrue(files.length > 0);
         ClassLoader result = ClassLoader.getSystemClassLoader();
         for (int i = 0; i < files.length; ++i) {
-            ByteBuffer buffer = ReadFileToByteBufferDirect(files[i]);
-            result = new InMemoryDexClassLoader(buffer, result);
+            ByteBuffer buffer = readFileToByteBufferDirect(files[i]);
+            result = new InMemoryDexClassLoader(new ByteBuffer[] { buffer }, result);
         }
         return result;
     }
@@ -133,13 +188,13 @@
      *
      * @param files The .dex files to use for the class path.
      */
-    private static ClassLoader createLoaderIndirect(File... files) throws IOException {
+    private ClassLoader createLoaderIndirect(File... files) throws IOException {
         assertNotNull(files);
         assertTrue(files.length > 0);
         ClassLoader result = ClassLoader.getSystemClassLoader();
         for (int i = 0; i < files.length; ++i) {
-            ByteBuffer buffer = ReadFileToByteBufferIndirect(files[i]);
-            result = new InMemoryDexClassLoader(buffer, result);
+            ByteBuffer buffer = readFileToByteBufferIndirect(files[i]);
+            result = new InMemoryDexClassLoader(new ByteBuffer[] { buffer }, result);
         }
         return result;
     }
@@ -180,6 +235,21 @@
         return m.invoke(null, (Object[]) null);
     }
 
+    /**
+     * Creates an InMemoryDexClassLoader using the content of {@code dex} and with a
+     * library path of {@code applicationLibPath}. The parent classloader is the boot
+     * classloader.
+     *
+     * @param dex The .dex file to be loaded.
+     * @param applicationLibPath Library search path of the new class loader.
+     */
+    private static InMemoryDexClassLoader createLoaderWithLibPath(File dex, File applicationLibPath)
+            throws IOException {
+        return new InMemoryDexClassLoader(
+                new ByteBuffer[] { readFileToByteBufferIndirect(dex) },
+                applicationLibPath.toString(), null);
+    }
+
     // ONE_DEX with direct ByteBuffer.
 
     public void test_oneDexDirect_simpleUse() throws Exception {
@@ -299,4 +369,84 @@
         createLoaderDirectAndCallMethod(
             "test.TestMethods", "test_diff_getInstanceVariable", dex2, dex1);
     }
+
+    public void testLibraryPath() throws IOException {
+        File applicationLibPath = new File(srcDir, "applicationLibPath");
+        File applicationLib = makeEmptyFile(applicationLibPath, "libtestlibpath.so");
+
+        InMemoryDexClassLoader classLoader = createLoaderWithLibPath(dex1, applicationLibPath);
+
+        String path = classLoader.findLibrary("testlibpath");
+        assertEquals(applicationLib.toString(), path);
+    }
+
+    public void testLibraryPathSearchOrder() throws IOException {
+        File systemLibPath = new File(srcDir, "systemLibPath");
+        File applicationLibPath = new File(srcDir, "applicationLibPath");
+        makeEmptyFile(systemLibPath, "libduplicated.so");
+        File applicationLib = makeEmptyFile(applicationLibPath, "libduplicated.so");
+
+        System.setProperty("java.library.path", systemLibPath.toString());
+        InMemoryDexClassLoader classLoader = createLoaderWithLibPath(dex1, applicationLibPath);
+
+        String path = classLoader.findLibrary("duplicated");
+        assertEquals(applicationLib.toString(), path);
+    }
+
+    public void testNullParent() throws IOException, ClassNotFoundException {
+        // Other tests set up InMemoryDexClassLoader with the system class loader
+        // as parent. Test that passing {@code null} works too (b/120603906).
+        InMemoryDexClassLoader classLoader = new InMemoryDexClassLoader(
+                new ByteBuffer[] { readFileToByteBufferIndirect(dex1) },
+                /* parent */ null);
+
+        // Try to load a class from the boot class loader.
+        Class<?> objectClass = classLoader.loadClass("java.lang.Object");
+        assertEquals(objectClass, Object.class);
+
+        // Try to load a class from this class loader.
+        classLoader.loadClass("test.TestMethods");
+    }
+
+    public void testNonZeroBufferOffsetDirect() throws IOException, ClassNotFoundException {
+        // Arbitrary amount of padding to prove a non-zero buffer position is supported.
+        int paddingBefore = 13;
+        InMemoryDexClassLoader classLoader = new InMemoryDexClassLoader(
+                new ByteBuffer[] { readFileToByteBufferDirect(dex1, paddingBefore) },
+                /* parent */ null);
+        classLoader.loadClass("test.TestMethods");
+    }
+
+    public void testNonZeroBufferOffsetIndirect() throws IOException, ClassNotFoundException {
+        // Arbitrary amount of padding to prove a non-zero buffer position is supported.
+        int paddingBefore = 13;
+        InMemoryDexClassLoader classLoader = new InMemoryDexClassLoader(
+                new ByteBuffer[] { readFileToByteBufferIndirect(dex1, paddingBefore) },
+                /* parent */ null);
+        classLoader.loadClass("test.TestMethods");
+    }
+
+    /**
+     * DexPathList.makeInMemoryDexElements() is a legacy code path not used by
+     * InMemoryDexClassLoader anymore but heavily used by 3p apps. Test that it still works.
+     */
+    public void testMakeInMemoryDexElements() throws Exception {
+        ArrayList<IOException> exceptions = new ArrayList<>();
+        Object[] elements = DexPathList.makeInMemoryDexElements(
+                new ByteBuffer[] { readFileToByteBufferDirect(dex1),
+                                   readFileToByteBufferIndirect(dex2) },
+                exceptions);
+        assertEquals(2, elements.length);
+        assertTrue(exceptions.isEmpty());
+    }
+
+    private static File makeEmptyFile(File directory, String name) throws IOException {
+        assertTrue(directory.mkdirs());
+        File result = new File(directory, name);
+        FileOutputStream stream = new FileOutputStream(result);
+        stream.close();
+        assertTrue(result.exists());
+        return result;
+    }
+
 }
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/io/FileInputStreamTest.java b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
index d214c9e..e722b4f 100644
--- a/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
@@ -30,12 +30,13 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.StructStatVfs;
-import android.system.Int32Ref;
 
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
 import libcore.junit.junit3.TestCaseWithRules;
 import libcore.junit.util.ResourceLeakageDetector;
+import libcore.testing.io.TestIoUtils;
+
 import org.junit.Rule;
 import org.junit.rules.TestRule;
 
@@ -64,7 +65,7 @@
                     }
                     fos.write(buffer);
                 } finally {
-                    IoUtils.closeQuietly(fos);
+                    TestIoUtils.closeQuietly(fos);
                     IoUtils.close(mOutFd);
                 }
             } catch (IOException e) {
@@ -234,7 +235,7 @@
 
     // http://b/25695227
     public void testFdLeakWhenOpeningDirectory() throws Exception {
-        File phile = IoUtils.createTemporaryDirectory("test_bug_25695227");
+        File phile = TestIoUtils.createTemporaryDirectory("test_bug_25695227");
 
         try {
             new FileInputStream(phile);
diff --git a/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java b/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java
new file mode 100644
index 0000000..8bee284
--- /dev/null
+++ b/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 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.io;
+
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamClass.DefaultSUIDCompatibilityListener;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnitParamsRunner.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ObjectStreamClassTest {
+
+  @Rule
+  public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
+  /**
+   * The default SUID for this should not be affected by the b/29064453 patch.
+   */
+  private static class BaseWithStaticInitializer implements Serializable {
+    static {
+      System.out.println(
+          "Static initializer for " + BaseWithoutStaticInitializer.class.getCanonicalName());
+    }
+  }
+
+  /**
+   * The default SUID for this should not be affected by the b/29064453 patch.
+   */
+  private static class BaseWithoutStaticInitializer implements Serializable {
+  }
+
+  /**
+   * The default SUID for this should not be affected by the b/29064453 patch.
+   */
+  private static class WithStaticInitializer extends BaseWithoutStaticInitializer {
+    static {
+      System.out.println(
+          "Static initializer for " + WithStaticInitializer.class.getCanonicalName());
+    }
+  }
+
+  /**
+   * The default SUID for this should not be affected by the b/29064453 patch.
+   */
+  private static class WithoutStaticInitializer extends BaseWithoutStaticInitializer {
+  }
+
+  /**
+   * The default SUID for this should be affected by the b/29064453 patch and so should differ
+   * between version <= 23 and version > 23.
+   */
+  private static class InheritStaticInitializer extends BaseWithStaticInitializer {
+  }
+
+  public static Object[][] defaultSUIDs() {
+    return new Object[][] {
+        // The default SUID for BaseWithStaticInitializer should not be affected by the b/29064453
+        // patch.
+        { BaseWithStaticInitializer.class, -4971959491244110788L, -4971959491244110788L },
+
+        // The default SUID for BaseWithoutStaticInitializer should not be affected by the
+        // b/29064453 patch.
+        { BaseWithoutStaticInitializer.class, -245652310465925293L, -245652310465925293L },
+
+        // The default SUID for WithStaticInitializer should not be affected by the b/29064453
+        // patch.
+        { WithStaticInitializer.class, -3581047773254885060L, -3581047773254885060L },
+
+        // The default SUID for WithStaticInitializer should not be affected by the
+        // b/29064453 patch.
+        { WithoutStaticInitializer.class, -975889567651927545L, -975889567651927545L },
+
+        // The default SUID for the InheritStaticInitializer should be affected by the b/29064453
+        // patch and so should differ between version <= 23 and version > 23.
+        { InheritStaticInitializer.class, 4188245044387716731L, 992629205079295334L },
+    };
+  }
+
+  @Parameters(method = "defaultSUIDs")
+  @Test
+  public void computeDefaultSUID_current(Class<?> clazz, long suid,
+      @SuppressWarnings("unused") long suid23) {
+    checkSerialVersionUID(suid, clazz, false);
+  }
+
+  @Parameters(method = "defaultSUIDs")
+  @Test
+  @TargetSdkVersion(23)
+  public void computeDefaultSUID_targetSdkVersion_23(Class<?> clazz, long suid, long suid23) {
+    // If the suid and suid23 hashes are different then a warning is expected to be logged.
+    boolean expectedWarning = suid23 != suid;
+    checkSerialVersionUID(suid23, clazz, expectedWarning);
+  }
+
+  private static void checkSerialVersionUID(
+      long expectedSUID, Class<?> clazz, boolean expectedWarning) {
+    // Use reflection to call the private static computeDefaultSUID method directly to avoid the
+    // caching performed by ObjectStreamClass.lookup(Class).
+    long defaultSUID;
+    DefaultSUIDCompatibilityListener savedListener
+        = ObjectStreamClass.suidCompatibilityListener;
+    try {
+      ObjectStreamClass.suidCompatibilityListener = (c, hash) -> {
+        // Delegate to the existing listener so that the warning is logged.
+        savedListener.warnDefaultSUIDTargetVersionDependent(clazz, hash);
+        if (expectedWarning) {
+          assertEquals(clazz, c);
+          assertEquals(expectedSUID, hash);
+        } else {
+          fail("Unexpected warning for " + c + " with defaultSUID " + hash);
+        }
+      };
+
+      Method computeDefaultSUIDMethod =
+          ObjectStreamClass.class.getDeclaredMethod("computeDefaultSUID", Class.class);
+      computeDefaultSUIDMethod.setAccessible(true);
+
+      defaultSUID = (Long) computeDefaultSUIDMethod.invoke(null, clazz);
+    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+      throw new IllegalStateException(e);
+    } finally {
+      ObjectStreamClass.suidCompatibilityListener = savedListener;
+    }
+    assertEquals(expectedSUID, defaultSUID);
+  }
+}
diff --git a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
index 15119bf..ec6c09b 100644
--- a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
@@ -25,13 +25,19 @@
 import java.io.OutputStream;
 import java.security.Permission;
 import java.util.Arrays;
-import java.util.Vector;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 import tests.support.resource.Support_Resources;
-import dalvik.system.VMRuntime;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 
-public class OldRuntimeTest extends junit.framework.TestCase {
+public class OldRuntimeTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
     Runtime r = Runtime.getRuntime();
 
@@ -517,71 +523,66 @@
     }
 
     // b/25859957
-    public void test_loadDeprecated() throws Exception {
-        final int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+    @TargetSdkVersion(24)
+    public void test_loadDeprecated_targetSdkVersion_24() throws Exception {
         try {
-            try {
-                // Call Runtime#load(String, ClassLoader) at API level 24 (N). It will fail
-                // with a UnsatisfiedLinkError because requested library doesn't exits.
-                VMRuntime.getRuntime().setTargetSdkVersion(24);
-                Method loadMethod =
-                        Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
-                loadMethod.setAccessible(true);
-                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
-                fail();
-            } catch(InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
-            }
-
-            try {
-                // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
-                // with a IllegalStateException because it's deprecated.
-                VMRuntime.getRuntime().setTargetSdkVersion(25);
-                Method loadMethod =
-                        Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
-                loadMethod.setAccessible(true);
-                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
-                fail();
-            } catch(InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
-            }
-        } finally {
-            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
+            // Call Runtime#load(String, ClassLoader) at API level 24 (N). It will fail
+            // with an UnsatisfiedLinkError because requested library doesn't exist.
+            Method loadMethod =
+                    Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
+            loadMethod.setAccessible(true);
+            loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+            fail();
+        } catch(InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
         }
     }
 
     // b/25859957
-    public void test_loadLibraryDeprecated() throws Exception {
-        final int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+    @TargetSdkVersion(25)
+    public void test_loadDeprecated_targetSdkVersion_25() throws Exception {
         try {
-            try {
-                // Call Runtime#loadLibrary(String, ClassLoader) at API level 24 (N). It will fail
-                // with a UnsatisfiedLinkError because requested library doesn't exits.
-                VMRuntime.getRuntime().setTargetSdkVersion(24);
-                Method loadMethod =
-                        Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
-                loadMethod.setAccessible(true);
-                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
-                fail();
-            } catch(InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
-            }
+            // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
+            // with an IllegalStateException because it's deprecated.
+            Method loadMethod =
+                    Runtime.class.getDeclaredMethod("load", String.class, ClassLoader.class);
+            loadMethod.setAccessible(true);
+            loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+            fail();
+        } catch(InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsupportedOperationException);
+        }
+    }
 
-            try {
-                // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
-                // with a IllegalStateException because it's deprecated.
+    // b/25859957
+    @TargetSdkVersion(24)
+    public void test_loadLibraryDeprecated_targetSdkVersion_24() throws Exception {
+        try {
+            // Call Runtime#loadLibrary(String, ClassLoader) at API level 24 (N). It will fail
+            // with a UnsatisfiedLinkError because requested library doesn't exits.
+            Method loadMethod =
+                    Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
+            loadMethod.setAccessible(true);
+            loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+            fail();
+        } catch(InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsatisfiedLinkError);
+        }
+    }
 
-                VMRuntime.getRuntime().setTargetSdkVersion(25);
-                Method loadMethod =
-                        Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
-                loadMethod.setAccessible(true);
-                loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
-                fail();
-            } catch(InvocationTargetException expected) {
-                assertTrue(expected.getCause() instanceof UnsupportedOperationException);
-            }
-        } finally {
-            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
+    // b/25859957
+    @TargetSdkVersion(25)
+    public void test_loadLibraryDeprecated_targetSdkVersion_25() throws Exception {
+        try {
+            // Call Runtime#load(String, ClassLoader) at API level 25. It will fail
+            // with a IllegalStateException because it's deprecated.
+            Method loadMethod =
+                    Runtime.class.getDeclaredMethod("loadLibrary", String.class, ClassLoader.class);
+            loadMethod.setAccessible(true);
+            loadMethod.invoke(Runtime.getRuntime(), "nonExistentLibrary", null);
+            fail();
+        } catch(InvocationTargetException expected) {
+            assertTrue(expected.getCause() instanceof UnsupportedOperationException);
         }
     }
 }
diff --git a/luni/src/test/java/libcore/java/lang/PackageTest.java b/luni/src/test/java/libcore/java/lang/PackageTest.java
index 176d0de..672af5d 100644
--- a/luni/src/test/java/libcore/java/lang/PackageTest.java
+++ b/luni/src/test/java/libcore/java/lang/PackageTest.java
@@ -19,9 +19,17 @@
 import dalvik.system.VMRuntime;
 import java.util.Arrays;
 import java.util.List;
-import junit.framework.TestCase;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
-public final class PackageTest extends TestCase {
+public final class PackageTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
     /** assign packages immediately so that Class.getPackage() calls cannot side-effect it */
     private static final List<Package> packages = Arrays.asList(Package.getPackages());
 
@@ -39,21 +47,17 @@
     }
 
     // http://b/28057303
-    public void test_toString() throws Exception {
-        int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
-        try {
-            VMRuntime.getRuntime().setTargetSdkVersion(24);
-            Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
-            assertEquals("package libcore.java.lang",
-                         libcoreJavaLang.toString());
+    @TargetSdkVersion(24)
+    public void test_toString_targetSdkVersion_24() throws Exception {
+        Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+        assertEquals("package libcore.java.lang", libcoreJavaLang.toString());
+    }
 
-            VMRuntime.getRuntime().setTargetSdkVersion(25);
-            libcoreJavaLang = Package.getPackage("libcore.java.lang");
-            assertEquals("package libcore.java.lang, Unknown, version 0.0",
-                         libcoreJavaLang.toString());
-        } finally {
-            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
-        }
+    // http://b/28057303
+    @TargetSdkVersion(25)
+    public void test_toString_targetSdkVersion_25() throws Exception {
+        Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+        assertEquals("package libcore.java.lang, Unknown, version 0.0", libcoreJavaLang.toString());
     }
 
     // http://b/5171136
diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java
index 7320d9a..c440ebe 100644
--- a/luni/src/test/java/libcore/java/lang/StringTest.java
+++ b/luni/src/test/java/libcore/java/lang/StringTest.java
@@ -781,4 +781,18 @@
             fail();
         } catch (NullPointerException expected) {}
     }
+
+    /**
+     * Check that String.format() does not throw when the default locale is invalid.
+     * http://b/129070579
+     */
+    public void testFormat_invalidLocale() {
+        Locale defaultLocale = Locale.getDefault();
+        try {
+            Locale.setDefault(new Locale("invalidLocale"));
+            String.format("%s", "");
+        } finally {
+            Locale.setDefault(defaultLocale);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index 48f4591..56b6558 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -27,8 +27,17 @@
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import android.system.Os;
+
 public class SystemTest extends TestCase {
 
+    public void testOsName() throws Exception {
+        // Ensure os.name always matches the underlying OS.
+        String sysname = Os.uname().sysname;
+        String property = System.getProperty("os.name");
+        assertEquals(sysname, property);
+    }
+
     public void testLineSeparator() throws Exception {
         try {
             // Before Java 7, the small number of classes that wanted the line separator would
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 6f62dd1..f1d0db6 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -19,6 +19,7 @@
 import java.lang.Thread.UncaughtExceptionHandler;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
 import java.util.concurrent.locks.ReentrantLock;
 
 import junit.framework.Assert;
@@ -241,7 +242,7 @@
 
                 if (!afterPark.get()) {
                     wasParkedForLongTime.set(true);
-                    current.unpark$();
+                    LockSupport.unpark(current);
                 }
             }
         };
@@ -250,7 +251,7 @@
         // b/29746125 is caused by underflow: parkUntilArg - System.currentTimeMillis() > 0.
         // parkUntil$ should return immediately for everyargument that's <=
         // System.currentTimeMillis().
-        current.parkUntil$(Long.MIN_VALUE);
+        LockSupport.parkUntil(Long.MIN_VALUE);
         if (wasParkedForLongTime.get()) {
             fail("Current thread was parked, but was expected to return immediately");
         }
diff --git a/luni/src/test/java/libcore/java/lang/ThrowableTest.java b/luni/src/test/java/libcore/java/lang/ThrowableTest.java
index 3479a22..74b1956 100644
--- a/luni/src/test/java/libcore/java/lang/ThrowableTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThrowableTest.java
@@ -16,13 +16,22 @@
 
 package libcore.java.lang;
 
+import java.io.ObjectStreamClass;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Arrays;
-import junit.framework.TestCase;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
 import libcore.libcore.util.SerializationTester;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
-public class ThrowableTest extends TestCase {
+public class ThrowableTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
     private static class NoStackTraceException extends Exception {
         @Override
         public synchronized Throwable fillInStackTrace() {
@@ -315,6 +324,32 @@
         }.test();
     }
 
+    /**
+     * Detect issue that caused b/109930347
+     *
+     * <p>Due to a bug in the default serialVersionUID calculation that is used for apps with
+     * targetSdkVersion <= 23 changes in {@link Throwable} can affect the default SUID for
+     * subclasses of {@link Throwable}.
+     *
+     * <p>This test protects against changes in Throwable (e.g. removing Android specific patches)
+     * that would cause a change in the default SUID of Throwable subclasses in apps with
+     * targetSdkVersion <= 23. It does so by checking the default SUID for a Throwable subclass,
+     * computed as by an app with targetSdkVersion <= 23, against a known good value.
+     */
+    @TargetSdkVersion(23)
+    public void testThrowableSubclassSerialVersionUIDComputation_target23() {
+        ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(ThrowableSubclass.class);
+        assertEquals(
+            "SerialVersionUID computation for Throwable subclass is broken for targetSdkVersion 23",
+            -1036450421582688704L, objectStreamClass.getSerialVersionUID());
+    }
+
+    public static class ThrowableSubclass extends Throwable {
+        public ThrowableSubclass(String message) {
+            super(message);
+        }
+    }
+
     private void assertSerialized(final Throwable throwable, String golden) {
         new SerializationTester<Throwable>(throwable, golden) {
             @Override protected boolean equals(Throwable a, Throwable b) {
diff --git a/luni/src/test/java/libcore/java/lang/reflect/annotations/AnnotationsTest.java b/luni/src/test/java/libcore/java/lang/reflect/annotations/AnnotationsTest.java
index a694981..0e40644 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/annotations/AnnotationsTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/annotations/AnnotationsTest.java
@@ -15,8 +15,6 @@
  */
 package libcore.java.lang.reflect.annotations;
 
-import junit.framework.TestCase;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -24,12 +22,19 @@
 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationA;
 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationB;
 
-import dalvik.system.VMRuntime;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
 /**
  * Tests for the behavior of Annotation instances at runtime.
  */
-public class AnnotationsTest extends TestCase {
+public class AnnotationsTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
     enum Breakfast { WAFFLES, PANCAKES }
 
@@ -88,24 +93,25 @@
     @ClassRetentionAnnotation @RuntimeRetentionAnnotation @SourceRetentionAnnotation
     public static class RetentionAnnotations {}
 
-    public void testRetentionPolicy() {
-        // b/29500035
-        int savedTargetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
-        try {
-            // Test N and later behavior
-            VMRuntime.getRuntime().setTargetSdkVersion(24);
-            Annotation classRetentionAnnotation =
+    // b/29500035
+    @TargetSdkVersion(23)
+    public void testRetentionPolicy_targetSdkVersion_23() {
+        // Test pre-N behavior
+        Annotation classRetentionAnnotation =
                 RetentionAnnotations.class.getAnnotation(ClassRetentionAnnotation.class);
-            assertNull(classRetentionAnnotation);
+        assertNotNull(classRetentionAnnotation);
+    }
 
-            // Test pre-N behavior
-            VMRuntime.getRuntime().setTargetSdkVersion(23);
-            classRetentionAnnotation =
-                RetentionAnnotations.class.getAnnotation(ClassRetentionAnnotation.class);
-            assertNotNull(classRetentionAnnotation);
-        } finally {
-            VMRuntime.getRuntime().setTargetSdkVersion(savedTargetSdkVersion);
-        }
+    // b/29500035
+    @TargetSdkVersion(24)
+    public void testRetentionPolicy_targetSdkVersion_24() {
+        // Test N and later behavior
+        Annotation classRetentionAnnotation =
+            RetentionAnnotations.class.getAnnotation(ClassRetentionAnnotation.class);
+        assertNull(classRetentionAnnotation);
+    }
+
+    public void testRetentionPolicy() {
         assertNotNull(RetentionAnnotations.class.getAnnotation(RuntimeRetentionAnnotation.class));
         assertNull(RetentionAnnotations.class.getAnnotation(SourceRetentionAnnotation.class));
     }
diff --git a/luni/src/test/java/libcore/java/net/DelegatingSocketFactory.java b/luni/src/test/java/libcore/java/net/DelegatingSocketFactory.java
new file mode 100644
index 0000000..20f2bb7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/net/DelegatingSocketFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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.java.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import javax.net.SocketFactory;
+
+/**
+ * {@link SocketFactory} which delegates all invocations to the provided delegate
+ * {@code SocketFactory}.
+ */
+public class DelegatingSocketFactory extends SocketFactory {
+
+  private final SocketFactory mDelegate;
+
+  protected DelegatingSocketFactory(SocketFactory delegate) {
+    this.mDelegate = delegate;
+  }
+
+  /**
+   * Invoked after obtaining a socket from the delegate and before returning it to the caller.
+   *
+   * <p>The default implementation does nothing.
+   */
+  protected Socket configureSocket(Socket socket) throws IOException {
+    return socket;
+  }
+
+  @Override
+  public Socket createSocket() throws IOException {
+    Socket socket = mDelegate.createSocket();
+    return configureSocket(socket);
+  }
+
+  @Override
+  public Socket createSocket(String host, int port) throws IOException {
+    Socket socket = mDelegate.createSocket(host, port);
+    return configureSocket(socket);
+  }
+
+  @Override
+  public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+      throws IOException {
+    Socket socket = mDelegate.createSocket(host, port, localHost, localPort);
+    return configureSocket(socket);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress host, int port) throws IOException {
+    Socket socket = mDelegate.createSocket(host, port);
+    return configureSocket(socket);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+      int localPort) throws IOException {
+    Socket socket = mDelegate.createSocket(address, port, localAddress, localPort);
+    return configureSocket(socket);
+  }
+}
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index e55d38f..307cd1d 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -192,6 +192,20 @@
     }
 
     @Test
+    public void test_isNumeric_notNumeric_null() throws Exception {
+        try {
+            boolean result = InetAddress.isNumeric(null);
+            fail("Expected isNumeric(null) to throw a NPE but instead returned " + result);
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void test_isNumeric_notNumeric_empty() throws Exception {
+        assertFalse(InetAddress.isNumeric(""));
+    }
+
+    @Test
     public void test_isNumeric_notNumeric() throws Exception {
         // Negative test
         assertFalse(InetAddress.isNumeric("example.com"));
diff --git a/luni/src/test/java/libcore/java/net/OldSocketTest.java b/luni/src/test/java/libcore/java/net/OldSocketTest.java
index 8a577fb..644fe52 100644
--- a/luni/src/test/java/libcore/java/net/OldSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/OldSocketTest.java
@@ -20,6 +20,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.net.BindException;
 import java.net.ConnectException;
 import java.net.Inet4Address;
@@ -37,6 +39,7 @@
 import java.nio.channels.IllegalBlockingModeException;
 import java.nio.channels.SocketChannel;
 import java.security.Permission;
+import java.util.concurrent.atomic.AtomicReference;
 import libcore.junit.util.ResourceLeakageDetector.DisableResourceLeakageDetection;
 import tests.support.Support_Configuration;
 
@@ -1266,39 +1269,37 @@
         }
     }
 
-    @DisableResourceLeakageDetection(
-            why = "Strange threading behavior causes resource leak",
-            bug = "31820278")
     public void test_connectLjava_net_SocketAddressI_setSOTimeout() throws Exception {
+        final AtomicReference<Exception> exceptionRef = new AtomicReference<>();
+
         class SocketConnector extends Thread {
+            private final int timeout;
+            private final Socket theSocket;
+            private final SocketAddress address;
 
-            int timeout = 0;
-
-            Socket theSocket = null;
-
-            SocketAddress address = null;
-
+            @Override
             public void run() {
                 try {
                     theSocket.connect(address, timeout);
                 } catch (Exception e) {
+                    exceptionRef.set(e);
                 }
-
-                return;
             }
 
-            public SocketConnector(int timeout, Socket theSocket,
-                    SocketAddress address) {
+            private SocketConnector(int timeout, Socket theSocket, SocketAddress address) {
                 this.timeout = timeout;
                 this.theSocket = theSocket;
                 this.address = address;
             }
         }
 
-        // now try to set options while we are connecting
-        SocketAddress nonReachableAddress = UNREACHABLE_ADDRESS;
-        try (Socket theSocket = new Socket()) {
-            SocketConnector connector = new SocketConnector(5000, theSocket, nonReachableAddress);
+        // Now try to set options while we are connecting
+        try (final Socket theSocket = new Socket()) {
+            // Force SocketImpl creation to prevent race between connect() and setSoTimeout()
+            // creating it. b/144258500
+            theSocket.getSoTimeout();
+            final SocketConnector connector
+                = new SocketConnector(5000, theSocket, UNREACHABLE_ADDRESS);
             connector.start();
             theSocket.setSoTimeout(1000);
             Thread.sleep(10);
@@ -1308,10 +1309,21 @@
             theSocket.setSoTimeout(2000);
             assertTrue("Socket option not set during connect: 50 ",
                     Math.abs(2000 - theSocket.getSoTimeout()) <= 10);
-            Thread.sleep(5000);
+            connector.join();
+            Exception e = exceptionRef.get();
+            if (!(e instanceof SocketTimeoutException)) {
+                fail(printStackTraceToString(e));
+            }
         }
     }
 
+    private String printStackTraceToString(Throwable throwable) {
+        StringWriter writer = new StringWriter();
+        throwable.printStackTrace(new PrintWriter(writer));
+        return writer.toString();
+    }
+
+
     public void test_isInputShutdown() throws IOException {
         Socket theSocket = new Socket();
         ServerSocket serverSocket = new ServerSocket(0, 5);
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 0bfd241..3e1c1a6 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -39,7 +39,6 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -387,44 +386,58 @@
     }
 
     public void testCloseDuringConnect() throws Exception {
-        final CountDownLatch signal = new CountDownLatch(1);
+        // This address is reserved for documentation: should never be reachable and therefore
+        // is expected to produce block behavior when attempting to connect().
+        final InetSocketAddress unreachableIp = new InetSocketAddress("192.0.2.0", 80);
+
         final Socket s = new Socket();
 
-        // Executes a connect() that should block.
-        Callable<String> connectWorker = () -> {
+        // A Callable that executes a connect() that should block and ultimately throw an exception.
+        // Inverts usual behavior for code: expected to *return* a throwable for analysis if one is
+        // thrown, but throws an Error if no exception is thrown.
+        Callable<Throwable> connectWorker = () -> {
             try {
-                // This address is reserved for documentation: should never be reachable.
-                InetSocketAddress unreachableIp = new InetSocketAddress("192.0.2.0", 80);
-                // This should never return.
+                // This method should not return naturally.
                 s.connect(unreachableIp, 0 /* infinite */);
-                return "Connect returned unexpectedly for: " + unreachableIp;
-            } catch (SocketException expected) {
-                signal.countDown();
-                return expected.getMessage().contains("Socket closed")
-                        ? null
-                        : "Unexpected SocketException message: " + expected.getMessage();
-            } catch (IOException e) {
-                return "Unexpected exception: " + e;
+                throw new AssertionError(
+                        "connect() to address(" + unreachableIp + ") did not block as required");
+            } catch (Exception exception) {
+                // Return the exception so that it can be inspected.
+                return exception;
             }
         };
-        Future<String> connectResult =
+        Future<Throwable> connectResult =
                 Executors.newSingleThreadScheduledExecutor().submit(connectWorker);
 
         // Wait sufficient time for the connectWorker thread to run and start connect().
         Thread.sleep(2000);
 
+        // Check for unexpected early termination. We require an environment where connect() will
+        // block forever with the specified IP and we can fail early if we detect the block hasn't
+        // happened.
+        if (connectResult.isDone()) {
+            // We expect an ExecutionError here. If not something has gone wrong with the test
+            // logic.
+            Throwable error = connectResult.get();
+            throw new AssertionError("Unexpected result from connectWorker", error);
+        }
+
         // Close the socket that connectWorker should currently be blocked in connect().
         s.close();
 
-        // connectWorker should have been unblocked so await() should return true.
-        boolean connectUnblocked = signal.await(2000, TimeUnit.MILLISECONDS);
-
-        // connectWorker should have returned null if everything went as expected.
-        String workerFailure = connectResult.get(2000, TimeUnit.MILLISECONDS);
-
-        assertTrue("connectUnblocked=[" + connectUnblocked
-                + "], workerFailure=[" + workerFailure + "]",
-                connectUnblocked && workerFailure == null);
+        // connectWorker should unblock so get() should obtain the exception that we expect to be
+        // thrown.
+        Throwable result = connectResult.get(2000, TimeUnit.MILLISECONDS);
+        if (result instanceof SocketException) {
+            if (result.getMessage().contains("Socket closed")) {
+                // This is the only case we accept.
+                return;
+            }
+            throw new AssertionError(
+                    "Unexpected SocketException message: " + result.getMessage(), result);
+        } else {
+            throw new AssertionError("Unexpected exception encountered", result);
+        }
     }
 
     // http://b/29092095
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 3619497..1574caf 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -89,8 +89,6 @@
 import libcore.java.security.TestKeyStore;
 import libcore.javax.net.ssl.TestSSLContext;
 
-import tests.net.DelegatingSocketFactory;
-
 import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
 import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
 import static com.google.mockwebserver.SocketPolicy.FAIL_HANDSHAKE;
@@ -857,6 +855,55 @@
     }
 
     /**
+     * Checks that paths ending in '/' (directory listings) are identified as HTML.
+     */
+    public void testGetFileNameMap_directory() {
+        checkFileNameMap("text/html", "/directory/path/");
+        checkFileNameMap("text/html", "http://example.com/path/");
+    }
+
+    public void testGetFileNameMap_simple() {
+        checkFileNameMap("text/plain", "example.txt");
+        checkFileNameMap("text/plain", "example.com/file.txt");
+    }
+
+    /**
+     * Checks that the *last* dot is considered for determining a file extension.
+     */
+    public void testGetFileNameMap_multipleDots() {
+        checkFileNameMap("text/html", "example.com/foo.txt/bar.html");
+        checkFileNameMap("text/plain", "example.com/foo.html/bar.txt");
+        checkFileNameMap("text/plain", "example.html.txt");
+    }
+
+    /**
+     * Checks that fragments are stripped when determining file extension.
+     */
+    public void testGetFileNameMap_fragment() {
+        checkFileNameMap("text/plain", "example.txt#fragment");
+        checkFileNameMap("text/plain", "example.com/path/example.txt#fragment");
+    }
+
+    /**
+     * Checks that fragments are NOT stripped and therefore break recognition
+     * of file type.
+     * This matches RI behavior, but it'd be reasonable to change behavior here.
+     */
+    public void testGetFileNameMap_queryParameter() {
+        checkFileNameMap(null, "example.txt?key=value");
+        checkFileNameMap(null, "example.txt?key=value#fragment");
+    }
+
+    private static void checkFileNameMap(String expected, String fileName) {
+        String actual = URLConnection.getFileNameMap().getContentTypeFor(fileName);
+        assertEquals(fileName, expected, actual);
+
+        // The documentation doesn't guarantee that these two do exactly the same thing,
+        // but it is one reasonable way to implement it.
+        assertEquals(fileName, expected, URLConnection.guessContentTypeFromName(fileName));
+    }
+
+    /**
      * Test Etag headers are returned correctly when a client-side cache is installed and the server
      * data is unchanged.
      * https://code.google.com/p/android/issues/detail?id=108949
@@ -2069,6 +2116,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 066442e..2daa09d 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -933,6 +933,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..f808092 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -40,7 +40,6 @@
 import java.nio.channels.FileChannel;
 import java.util.Arrays;
 import libcore.io.Memory;
-import libcore.io.SizeOf;
 import libcore.java.lang.ref.FinalizationTester;
 
 public class BufferTest extends TestCase {
@@ -60,62 +59,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));
     }
@@ -943,14 +886,14 @@
         // of this buffer.
         assertEquals(1, 1 << ByteBuffer.allocate(0).getElementSizeShift());
 
-        assertEquals(SizeOf.CHAR, 1 << CharBuffer.allocate(0).getElementSizeShift());
-        assertEquals(SizeOf.SHORT, 1 << ShortBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Character.BYTES, 1 << CharBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Short.BYTES, 1 << ShortBuffer.allocate(0).getElementSizeShift());
 
-        assertEquals(SizeOf.INT, 1 << IntBuffer.allocate(0).getElementSizeShift());
-        assertEquals(SizeOf.FLOAT, 1 << FloatBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Integer.BYTES, 1 << IntBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Float.BYTES, 1 << FloatBuffer.allocate(0).getElementSizeShift());
 
-        assertEquals(SizeOf.LONG, 1 << LongBuffer.allocate(0).getElementSizeShift());
-        assertEquals(SizeOf.DOUBLE, 1 << DoubleBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Long.BYTES, 1 << LongBuffer.allocate(0).getElementSizeShift());
+        assertEquals(Double.BYTES, 1 << DoubleBuffer.allocate(0).getElementSizeShift());
     }
 
     public void testFreed() {
diff --git a/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java b/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
index 9377d4e..2ea10a0 100644
--- a/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
+++ b/luni/src/test/java/libcore/java/nio/file/FileSystemsTest.java
@@ -35,9 +35,10 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import libcore.io.Streams;
+
 import dalvik.system.PathClassLoader;
 import junitparams.JUnitParamsRunner;
-import sun.misc.IOUtils;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -178,11 +179,13 @@
      * MockFileSystemProvider and MockFileSystem classes.
      * @throws Exception
      */
-    ClassLoader createClassLoaderForTestFileSystems() throws Exception {
-        File jarFile = new File(filesSetup.getTestDir().toString(), "filesystemstset.jar");
-        InputStream jis = getClass().getResource("/filesystemstest.jar").openStream();
-        OutputStream jos = new FileOutputStream(jarFile);
-        jos.write(IOUtils.readFully(jis, -1, true));
+    ClassLoader createClassLoaderForTestFileSystems() throws IOException {
+        File jarFile = new File(filesSetup.getTestDir(), "filesystemstest.jar");
+        try (InputStream in = getClass().getResource("/filesystemstest.jar").openStream();
+             OutputStream out = new FileOutputStream(jarFile))
+        {
+            Streams.copy(in, out);
+        }
 
         return new PathClassLoader(jarFile.getAbsolutePath(), getClass().getClassLoader());
     }
diff --git a/luni/src/test/java/libcore/java/security/KeyAgreementHelper.java b/luni/src/test/java/libcore/java/security/KeyAgreementHelper.java
new file mode 100644
index 0000000..bb624d7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/KeyAgreementHelper.java
@@ -0,0 +1,43 @@
+/*
+ * 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.java.security;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import javax.crypto.KeyAgreement;
+import junit.framework.Assert;
+
+class KeyAgreementHelper {
+
+    private final String algorithmName;
+
+    KeyAgreementHelper(String algorithmName) {
+        this.algorithmName = algorithmName;
+    }
+
+    public void test(KeyPair keyPair) throws Exception {
+        test(keyPair.getPrivate(), keyPair.getPublic());
+    }
+
+    private void test(PrivateKey encryptKey, PublicKey decryptKey) throws Exception {
+        KeyAgreement keyAgreement = KeyAgreement.getInstance(algorithmName);
+        keyAgreement.init(encryptKey);
+        keyAgreement.doPhase(decryptKey, true);
+        Assert.assertNotNull("generated secret is null", keyAgreement.generateSecret());
+    }
+}
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/OldKeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
index 5c0fc2f..00e76d8 100644
--- a/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/java/security/OldKeyPairGeneratorTestDH.java
@@ -17,9 +17,7 @@
 
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
 import junit.framework.TestCase;
-import tests.security.KeyAgreementHelper;
 
 public class OldKeyPairGeneratorTestDH extends TestCase {
 
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index 64ea0e6..a9a5318 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -213,6 +213,32 @@
         assertEquals("Missing classes", Collections.EMPTY_LIST, missing);
     }
 
+    // This tests the CDD requirement that specifies the first seven security providers
+    // (section 3.5, [C-0-9] as of P).
+    public void testProviderList() {
+        Provider[] providers = Security.getProviders();
+        assertTrue(providers.length >= 7);
+        assertProviderProperties(providers[0], "AndroidNSSP",
+            "android.security.net.config.NetworkSecurityConfigProvider");
+        assertProviderProperties(providers[1], "AndroidOpenSSL",
+            "com.android.org.conscrypt.OpenSSLProvider");
+        assertProviderProperties(providers[2], "CertPathProvider",
+            "sun.security.provider.CertPathProvider");
+        assertProviderProperties(providers[3], "AndroidKeyStoreBCWorkaround",
+            "android.security.keystore.AndroidKeyStoreBCWorkaroundProvider");
+        assertProviderProperties(providers[4], "BC",
+            "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");
+        assertProviderProperties(providers[5], "HarmonyJSSE",
+            "com.android.org.conscrypt.JSSEProvider");
+        assertProviderProperties(providers[6], "AndroidKeyStore",
+            "android.security.keystore.AndroidKeyStoreProvider");
+    }
+
+    private void assertProviderProperties(Provider p, String name, String className) {
+        assertEquals(name, p.getName());
+        assertEquals(className, p.getClass().getName());
+    }
+
     private static final Pattern alias = Pattern.compile("Alg\\.Alias\\.([^.]*)\\.(.*)");
 
     /**
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/CertPathValidatorTest.java b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
index e621b5c..0f84e91 100644
--- a/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
@@ -32,22 +32,22 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
-import com.android.org.bouncycastle.asn1.x509.CRLReason;
-import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.cert.X509CertificateHolder;
-import com.android.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import com.android.org.bouncycastle.cert.ocsp.BasicOCSPResp;
-import com.android.org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
-import com.android.org.bouncycastle.cert.ocsp.CertificateID;
-import com.android.org.bouncycastle.cert.ocsp.CertificateStatus;
-import com.android.org.bouncycastle.cert.ocsp.OCSPResp;
-import com.android.org.bouncycastle.cert.ocsp.OCSPRespBuilder;
-import com.android.org.bouncycastle.cert.ocsp.RevokedStatus;
-import com.android.org.bouncycastle.operator.DigestCalculatorProvider;
-import com.android.org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
-import com.android.org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import junit.framework.TestCase;
 import libcore.java.security.TestKeyStore;
+import org.bouncycastle.asn1.x509.CRLReason;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.operator.DigestCalculatorProvider;
+import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 
 import dalvik.system.VMRuntime;
 import sun.security.jca.Providers;
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/text/NumberFormatTest.java b/luni/src/test/java/libcore/java/text/NumberFormatTest.java
index 63892df..547653f 100644
--- a/luni/src/test/java/libcore/java/text/NumberFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/NumberFormatTest.java
@@ -210,19 +210,18 @@
     public void test_setCurrency() throws Exception {
         NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
 
-        // The Armenian Dram is a special case where the fractional digits are 0.
-        Currency amd = Currency.getInstance("AMD");
-        assertEquals(0, amd.getDefaultFractionDigits());
+        // The Japanese Yen is a special case where the fractional digits are 0.
+        Currency jpy = Currency.getInstance("JPY");
+        assertEquals(0, jpy.getDefaultFractionDigits());
 
-        // Armenian Dram ISO 4217 code.
-        nf.setCurrency(amd);
+        nf.setCurrency(jpy);
         assertEquals(2, nf.getMinimumFractionDigits());  // Check DecimalFormat has not taken the
         assertEquals(2, nf.getMaximumFractionDigits());  // currency specific fractional digits.
-        assertEquals("AMD50.00", nf.format(50.00));
+        assertEquals("¥50.00", nf.format(50.00));
 
         // Try and explicitly request fractional digits for the specified currency.
-        nf.setMaximumFractionDigits(amd.getDefaultFractionDigits());
-        assertEquals("AMD50", nf.format(50.00));
+        nf.setMaximumFractionDigits(jpy.getDefaultFractionDigits());
+        assertEquals("¥50", nf.format(50.00));
 
         nf = NumberFormat.getCurrencyInstance(Locale.US);
 
@@ -230,9 +229,9 @@
         nf.setCurrency(Currency.getInstance("EUR"));
         assertEquals("€50.00", nf.format(50.00));
 
-        // Japanese Yen symbol.
-        nf.setCurrency(Currency.getInstance("JPY"));
-        assertEquals("¥50.00", nf.format(50.00));
+        // Armenian Dram symbol.
+        nf.setCurrency(Currency.getInstance("AMD"));
+        assertEquals("AMD50.00", nf.format(50.00));
 
         // Swiss Franc ISO 4217 code.
         nf.setCurrency(Currency.getInstance("CHF"));
@@ -245,9 +244,9 @@
         NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.JAPAN);
         assertEquals("¥50", nf.format(50.00));
 
-        // Armenian Dram 0 fractional digits.
+        // Armenian Dram 2 fractional digits.
         nf = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("hy-AM"));
-        assertEquals("50\u00a0֏", nf.format(50.00));
+        assertEquals("50,00\u00a0֏", nf.format(50.00));
 
         // Swiss Francs 2 fractional digits.
         nf = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("de-CH"));
diff --git a/luni/src/test/java/libcore/java/text/OldAttributedStringTest.java b/luni/src/test/java/libcore/java/text/OldAttributedStringTest.java
index 26bd21d..e8a1d9f 100644
--- a/luni/src/test/java/libcore/java/text/OldAttributedStringTest.java
+++ b/luni/src/test/java/libcore/java/text/OldAttributedStringTest.java
@@ -19,11 +19,11 @@
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedString;
 import java.text.CharacterIterator;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.WeakHashMap;
 
 public class OldAttributedStringTest extends junit.framework.TestCase {
 
@@ -165,9 +165,7 @@
 
         // case 1: Try to construct AttributedString
         try {
-            AttributedString attrString = new AttributedString(
-                    test,
-                    new WeakHashMap<AttributedCharacterIterator.Attribute, String>());
+            AttributedString attrString = new AttributedString(test, Collections.emptyMap());
             AttributedCharacterIterator it = attrString.getIterator();
             StringBuffer buf = new StringBuffer();
             buf.append(it.first());
@@ -182,10 +180,9 @@
         // case 2: Try to construct AttributedString using 0-length text and
         // not an empty Map attributes.
         try {
-            Map<AttributedCharacterIterator.Attribute, String> whm = new WeakHashMap<AttributedCharacterIterator.Attribute, String>();
-            whm.put(new TestAttributedCharacterIteratorAttribute("test"),
-                    "value");
-            new AttributedString("", whm);
+            Map<AttributedCharacterIterator.Attribute, String> map = Collections.singletonMap(
+                    new TestAttributedCharacterIteratorAttribute("test"), "value");
+            new AttributedString("", map);
             fail("Expected IllegalArgumentException was not thrown");
         } catch (Exception e) {
             // expected
@@ -304,7 +301,7 @@
         }
 
         // regression for Harmony-1244
-        as = new AttributedString("123", new WeakHashMap());
+        as = new AttributedString("123", Collections.emptyMap());
         try {
             as.addAttribute(null, new TreeSet(), 0, 1);
             fail("should throw NullPointerException");
@@ -326,7 +323,7 @@
      */
     public void test_addAttributeLjava_text_AttributedCharacterIterator$AttributeLjava_lang_Object() {
         // regression for Harmony-1244
-        AttributedString as = new AttributedString("123", new WeakHashMap());
+        AttributedString as = new AttributedString("123", Collections.emptyMap());
 
         as.addAttribute(AttributedCharacterIterator.Attribute.LANGUAGE, "english");
         as.addAttribute(AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT,
diff --git a/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
index fa98bf9..444d91e 100644
--- a/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
+++ b/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
@@ -33,7 +33,6 @@
     public void test_RIHarmony_compatible() throws Exception {
         ObjectInputStream i = null;
         try {
-            DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRANCE);
             i = new ObjectInputStream(
                     getClass()
                             .getClassLoader()
@@ -43,7 +42,17 @@
             // RI's default NaN is U+FFFD, Harmony's is based on ICU
             // This suggests an RI bug, assuming that non-UTF8 bytes are UTF8 and
             // getting a conversion failure.
+            assertEquals("\ufffd", riSymbols.getNaN());
+            // Since CLDR 34, Android's group separator in French is changed from \u00a0 to \u202f.
+            // Both are no-break whitespace in Unicode.
+            assertEquals('\u00a0', riSymbols.getGroupingSeparator());
+
+            // Override the riSymbols fields known to differ on Android values so that we can check
+            // equality on all other fields with equals().
             riSymbols.setNaN("NaN");
+            riSymbols.setGroupingSeparator('\u202f');
+            // Compare the Android defaults with the RI snapshot.
+            DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRANCE);
             assertEquals(symbols, riSymbols);
         } catch(NullPointerException e) {
             assertNotNull("Failed to load /serialization/java/text/" +
@@ -144,7 +153,7 @@
         assertEquals("\u20AC", dfs.getCurrencySymbol());
         assertEquals(',', dfs.getDecimalSeparator());
         assertEquals('#', dfs.getDigit());
-        assertEquals('\u00a0', dfs.getGroupingSeparator());
+        assertEquals('\u202f', dfs.getGroupingSeparator());
         assertEquals("\u221e", dfs.getInfinity());
         assertEquals("EUR", dfs.getInternationalCurrencySymbol());
         assertEquals('-', dfs.getMinusSign());
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index dc1412f..2d85c1b 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -733,6 +733,44 @@
         assertDayPeriodParseFailure("HH B", "08 in the morning");
     }
 
+    public void testContextSensitiveMonth() {
+        Locale ru = new Locale("ru");
+        assertEquals("1", formatDateUtc(ru, "M"));
+        assertEquals("01", formatDateUtc(ru, "MM"));
+        assertEquals("янв.", formatDateUtc(ru, "MMM"));
+        assertEquals("января", formatDateUtc(ru, "MMMM"));
+        assertEquals("Я", formatDateUtc(ru, "MMMMM"));
+    }
+
+    /*
+     * Tests that forced standalone form is not used on Android. In some languages, e.g. Russian,
+     * Polish or Czech, in some cases the month name form depends on the usage context. For example,
+     * January in Russian is "Январь" (nominative case), but if you say 11th of January
+     * (genitive case), it will look like "11 Января" (notice the difference in the last letter).
+     * Five Ms format makes month name independent on the context (in this case "11 Январь").
+     */
+    public void testContextSensitiveMonth_nonGregorianCalendar() {
+        final Locale ru = new Locale("ru");
+        final Locale cs = new Locale("cs");
+
+        // The RI forces standalone form here, which would be "январь".
+        // Android does not force standalone form. http://b/66411240#comment7
+        assertEquals("янв.", formatDateNonGregorianCalendar("MMM", ru));
+        assertEquals("января", formatDateNonGregorianCalendar("MMMM", ru));
+        assertEquals("января", formatDateNonGregorianCalendar("MMMMM", ru));
+        assertEquals("led", formatDateNonGregorianCalendar("MMM", cs));
+        assertEquals("ledna", formatDateNonGregorianCalendar("MMMM", cs));
+        assertEquals("ledna", formatDateNonGregorianCalendar("MMMMM", cs));
+
+        // Ensure that Android standalone form is used for Ls format strings
+        assertEquals("янв.", formatDateNonGregorianCalendar("LLL", ru));
+        assertEquals("январь", formatDateNonGregorianCalendar("LLLL", ru));
+        assertEquals("январь", formatDateNonGregorianCalendar("LLLLL", ru));
+        assertEquals("led", formatDateNonGregorianCalendar("LLL", cs));
+        assertEquals("leden", formatDateNonGregorianCalendar("LLLL", cs));
+        assertEquals("leden", formatDateNonGregorianCalendar("LLLLL", cs));
+    }
+
     private void assertDayPeriodParseFailure(String pattern, String source) {
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, Locale.US);
         ParsePosition parsePosition = new ParsePosition(0);
@@ -757,19 +795,56 @@
 
     // http://b/38396219
     public void testDisplayNamesOnNonGregorianCalendar() {
-        assertEquals("Jan", formatDateNonGregorianCalendar("MMM")); // MONTH
-        assertEquals("Jan", formatDateNonGregorianCalendar("LLL")); // MONTH_STANDALONE
-        assertEquals("Thu", formatDateNonGregorianCalendar("EEE")); // DAY_OF_WEEK
-        assertEquals("Thu", formatDateNonGregorianCalendar("ccc")); // STANDALONE_DAY_OF_WEEK
+        assertEquals("Jan", formatDateNonGregorianCalendar("MMM", Locale.US)); // MONTH
+        assertEquals("Jan", formatDateNonGregorianCalendar("LLL", Locale.US)); // MONTH_STANDALONE
+        assertEquals("Thu", formatDateNonGregorianCalendar("EEE", Locale.US)); // DAY_OF_WEEK
+        assertEquals("Thu", formatDateNonGregorianCalendar("ccc", Locale.US)); // STANDALONE_DAY_OF_WEEK
+    }
+
+    /*
+     * This is a regression test to ensure that month name can't be parsed using narrow format.
+     * There are still some cases when parsing can succeed, because on some locales
+     * (e.g. "ko", "th" and others) long, short and narrow forms of month are equal.
+     * There are two locales tested: AK and UK. AK locale has all months names unique
+     * (i.e. 01, 02, 03, ...), so there is no ambiguity and theoretically it is possible to parse
+     * them, however SimpleDateFormat doesn't allow it. UK locale is ambiguous
+     * (i.e. J, F, M, A, M, J, J, ...) so it is impossible to distinguish January, June or July in
+     * narrow form.
+     */
+    public void testParseNarrowFormat_throws() {
+        // narrow format for months is not ambiguous (01, 02, 03, ...)
+        checkParseNarrowFormat_throws(Locale.forLanguageTag("ak"));
+        // narrow format for months is ambiguous (J, F, M, A, M, J, J, ...).
+        checkParseNarrowFormat_throws(Locale.UK);
+    }
+
+    private static void checkParseNarrowFormat_throws(Locale locale) {
+        final Date date = new Date(0);
+        final TimeZone tz = TimeZone.getTimeZone("UTC");
+
+        // Format the date with DateFormatSymbol data and parsing it with Calendar data
+        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM", locale);
+        sdf.setTimeZone(tz);
+        String formattedDate = sdf.format(date);
+
+        // non-gregorian calendar to trigger getDisplayNamesMap() call while
+        // parsing narrow format date
+        sdf.setCalendar(new NonGregorianCalendar(tz, locale));
+
+        try {
+            sdf.parse(formattedDate);
+            fail(String.format("Parsed unparseable date on %s locale", locale.toLanguageTag()));
+        } catch (ParseException expected) {
+        }
     }
 
     /**
      * Format a date using a "non-gregorian" calendar. This means that we use a calendar that is not
      * exactly {@code java.util.GregorianCalendar} as checked by
-     * {@link SimpleDateFormat#isGregorianCalendar()}.
+     * {@link SimpleDateFormat#useDateFormatSymbols()}.
      */
-    private static String formatDateNonGregorianCalendar(String fmt) {
-        DateFormat dateFormat = new SimpleDateFormat(fmt, Locale.US);
+    private static String formatDateNonGregorianCalendar(String fmt, Locale locale) {
+        DateFormat dateFormat = new SimpleDateFormat(fmt, locale);
         NonGregorianCalendar cal = new NonGregorianCalendar();
         cal.clear();
         cal.setTimeZone(UTC);
@@ -782,5 +857,13 @@
      * #testDisplayNamesOnNonGregorianCalendar()}.
      */
     private static class NonGregorianCalendar extends GregorianCalendar {
+        NonGregorianCalendar() {
+            super();
+        }
+
+        NonGregorianCalendar(TimeZone timeZone, Locale locale) {
+            super(timeZone, locale);
+        }
     }
+
 }
diff --git a/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java b/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java
index 1f36b2c..3c1f0cf 100644
--- a/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java
+++ b/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java
@@ -16,8 +16,6 @@
 package libcore.java.time.chrono;
 
 import org.junit.Test;
-import android.icu.util.JapaneseCalendar;
-import java.util.List;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalTime;
@@ -25,7 +23,6 @@
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.chrono.ChronoZonedDateTime;
-import java.time.chrono.Era;
 import java.time.chrono.JapaneseChronology;
 import java.time.chrono.JapaneseDate;
 import java.time.chrono.JapaneseEra;
@@ -113,14 +110,4 @@
         assertEquals(true, date.isSupported(ChronoField.YEAR));
         assertEquals(true, date.isSupported(ChronoField.YEAR_OF_ERA));
     }
-
-    @Test
-    public void test_eras_isLatestEraConsistency() {
-        List<Era> japaneseEras = JapaneseChronology.INSTANCE.eras();
-        boolean isHeiseiLatestInJavaTime =
-            japaneseEras.get(japaneseEras.size()-1).getValue() <= JapaneseEra.HEISEI.getValue();
-        boolean isHeiseiLatestInIcu = JapaneseCalendar.CURRENT_ERA == JapaneseCalendar.HEISEI;
-        assertEquals("java.time and ICU4J are not consistent in the latest japanese era",
-            isHeiseiLatestInJavaTime, isHeiseiLatestInIcu);
-    }
 }
diff --git a/luni/src/test/java/libcore/java/util/ArrayListTest.java b/luni/src/test/java/libcore/java/util/ArrayListTest.java
index 95dd3f3..a90fb68 100644
--- a/luni/src/test/java/libcore/java/util/ArrayListTest.java
+++ b/luni/src/test/java/libcore/java/util/ArrayListTest.java
@@ -17,6 +17,8 @@
 package libcore.java.util;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 public class ArrayListTest extends junit.framework.TestCase {
     public void test_replaceAll() {
@@ -26,4 +28,53 @@
     public void test_sort() {
         ListDefaultMethodTester.test_sort(new ArrayList<>());
     }
+
+    public void test_sublist_throws() {
+        ArrayList<String> list = new ArrayList<>(Arrays.asList("zero", "one", "two"));
+
+        // For comparison, a few cases that should not throw
+        list.subList(1, 2);
+        list.subList(0, 3);
+        list.subList(1, 1);
+
+        // Cases that should throw
+        try {
+            list.subList(-1, 1); // fromIndex out of bounds
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            list.subList(0, 4); // toIndex out of bounds
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            list.subList(-1, 4); // both fromIndex and toIndex out of bounds
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            list.subList(1, 0); // fromIndex > toIndex
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void test_sublist_set() {
+        List<String> list = new ArrayList<>(Arrays.asList("zero", "one", "two"));
+        list.subList(1, 2).set(0, "ONE");
+        assertEquals(Arrays.asList("zero", "ONE", "two"), list);
+
+        list.subList(1, 2).subList(0, 1).set(0, "1");
+        assertEquals(Arrays.asList("zero", "1", "two"), list);
+
+        try {
+            list.subList(1, 2).set(2, "out of bounds");
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
 }
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/CollectionsTest.java b/luni/src/test/java/libcore/java/util/CollectionsTest.java
index 8ca3122..c92bcd4 100644
--- a/luni/src/test/java/libcore/java/util/CollectionsTest.java
+++ b/luni/src/test/java/libcore/java/util/CollectionsTest.java
@@ -47,9 +47,12 @@
 import java.util.concurrent.LinkedBlockingDeque;
 
 import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
 
-import dalvik.system.VMRuntime;
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
 
 import static java.util.Collections.checkedNavigableMap;
 import static java.util.Collections.checkedQueue;
@@ -61,7 +64,10 @@
 import static java.util.Spliterator.SUBSIZED;
 import static libcore.java.util.SpliteratorTester.assertHasCharacteristics;
 
-public final class CollectionsTest extends TestCase {
+public final class CollectionsTest extends TestCaseWithRules {
+
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
     private static final Object NOT_A_STRING = new Object();
     private static final Object A_STRING = "string";
@@ -156,86 +162,55 @@
      * Tests that when targetSdk {@code <= 25}, Collections.sort() does not delegate
      * to List.sort().
      */
+    @TargetSdkVersion(25)
     public void testSort_nougatOrEarlier_doesNotDelegateToListSort() {
-        runOnTargetSdk(25, () -> { // Nougat MR1 / MR2
-            ArrayListInheritor<String> list = new ArrayListInheritor<>(
-                    Arrays.asList("a", "c", "b"));
-            assertEquals(0, list.numSortCalls());
-            Collections.sort(list);
-            assertEquals(0, list.numSortCalls());
-        });
+        // Nougat MR1 / MR2
+        ArrayListInheritor<String> list = new ArrayListInheritor<>(Arrays.asList("a", "c", "b"));
+        assertEquals(0, list.numSortCalls());
+        Collections.sort(list);
+        assertEquals(0, list.numSortCalls());
     }
 
+    @TargetSdkVersion(26)
     public void testSort_postNougat_delegatesToListSort() {
-        runOnTargetSdkAtLeast(26, () -> {
-            ArrayListInheritor<String> list = new ArrayListInheritor<>(
-                    Arrays.asList("a", "c", "b"));
-            assertEquals(0, list.numSortCalls());
-            Collections.sort(list);
-            assertEquals(1, list.numSortCalls());
-        });
+        ArrayListInheritor<String> list = new ArrayListInheritor<>(Arrays.asList("a", "c", "b"));
+        assertEquals(0, list.numSortCalls());
+        Collections.sort(list);
+        assertEquals(1, list.numSortCalls());
     }
 
+    @TargetSdkVersion(26)
     public void testSort_modcountUnmodifiedForLinkedList() {
-        runOnTargetSdkAtLeast(26, () -> {
-            LinkedList<String> list = new LinkedList<>(Arrays.asList(
-                    "red", "green", "blue", "violet"));
-            Iterator<String> it = list.iterator();
-            it.next();
-            Collections.sort(list);
-            it.next(); // does not throw ConcurrentModificationException
-        });
+        // does not throw ConcurrentModificationException
+        LinkedList<String> list = new LinkedList<>(Arrays.asList("red", "green", "blue", "violet"));
+        Iterator<String> it = list.iterator();
+        it.next();
+        Collections.sort(list);
+        it.next(); // does not throw ConcurrentModificationException
     }
 
+    @TargetSdkVersion(26)
     public void testSort_modcountModifiedForArrayListAndSubclasses() {
-        runOnTargetSdkAtLeast(26, () -> {
-            List<String> testData = Arrays.asList("red", "green", "blue", "violet");
+        List<String> testData = Arrays.asList("red", "green", "blue", "violet");
 
-            ArrayList<String> list = new ArrayList<>(testData);
-            Iterator<String> it = list.iterator();
-            it.next();
-            Collections.sort(list);
-            try {
-                it.next();
-                fail();
-            } catch (ConcurrentModificationException expected) {
-            }
-
-            list = new ArrayListInheritor<>(testData);
-            it = list.iterator();
-            it.next();
-            Collections.sort(list);
-            try {
-                it.next();
-                fail();
-            } catch (ConcurrentModificationException expected) {
-            }
-        });
-    }
-
-    /**
-     * Runs the given runnable on this thread with the targetSdkVersion temporarily set
-     * to the specified value, unless the current value is already higher.
-     */
-    private static void runOnTargetSdkAtLeast(int minimumTargetSdkForTest, Runnable runnable) {
-        int targetSdkForTest = Math.max(minimumTargetSdkForTest,
-                VMRuntime.getRuntime().getTargetSdkVersion());
-        runOnTargetSdk(targetSdkForTest, runnable);
-    }
-
-    /**
-     * Runs the given runnable on this thread with the targetSdkVersion temporarily set
-     * to the specified value. This helps test behavior that depends on an API level
-     * other than the current one (e.g. between releases).
-     */
-    private static void runOnTargetSdk(int targetSdkForTest, Runnable runnable) {
-        VMRuntime runtime = VMRuntime.getRuntime();
-        int targetSdk = runtime.getTargetSdkVersion();
+        ArrayList<String> list = new ArrayList<>(testData);
+        Iterator<String> it = list.iterator();
+        it.next();
+        Collections.sort(list);
         try {
-            runtime.setTargetSdkVersion(targetSdkForTest);
-            runnable.run();
-        } finally {
-            runtime.setTargetSdkVersion(targetSdk);
+            it.next();
+            fail();
+        } catch (ConcurrentModificationException expected) {
+        }
+
+        list = new ArrayListInheritor<>(testData);
+        it = list.iterator();
+        it.next();
+        Collections.sort(list);
+        try {
+            it.next();
+            fail();
+        } catch (ConcurrentModificationException expected) {
         }
     }
 
diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java
index df86a38..1fd8193 100644
--- a/luni/src/test/java/libcore/java/util/DateTest.java
+++ b/luni/src/test/java/libcore/java/util/DateTest.java
@@ -50,10 +50,19 @@
         c.clear();
         c.set(Calendar.YEAR, 21);
         assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
-        assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString());
+        String actual21GmtString = c.getTime().toGMTString();
+        // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
+        assertTrue("Actual: " + actual21GmtString,
+                "1 Jan 21 07:52:58 GMT".equals(actual21GmtString)
+                        || "1 Jan 21 08:00:00 GMT".equals(actual21GmtString));
+
         c.set(Calendar.YEAR, 321);
         assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
-        assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
+        String actual321GmtString = c.getTime().toGMTString();
+        // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
+        assertTrue("Actual: " + actual321GmtString,
+                "1 Jan 321 07:52:58 GMT".equals(actual321GmtString)
+                        || "1 Jan 321 08:00:00 GMT".equals(actual321GmtString));
     }
 
     public void test_toGMTString_nonUs() throws Exception {
@@ -64,10 +73,19 @@
         c.clear();
         c.set(Calendar.YEAR, 21);
         assertEquals("Wed Jan 01 00:00:00 PST 21", c.getTime().toString());
-        assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString());
+        String actual21GmtString = c.getTime().toGMTString();
+        // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
+        assertTrue("Actual: " + actual21GmtString,
+                "1 Jan 21 07:52:58 GMT".equals(actual21GmtString)
+                        || "1 Jan 21 08:00:00 GMT".equals(actual21GmtString));
+
         c.set(Calendar.YEAR, 321);
         assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString());
-        assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString());
+        String actual321GmtString = c.getTime().toGMTString();
+        // zic <= 2014b data gives -08:00:00, later ones gives -07:52:58 instead. http://b/73719425
+        assertTrue("Actual: " + actual321GmtString,
+                "1 Jan 321 07:52:58 GMT".equals(actual321GmtString)
+                        || "1 Jan 321 08:00:00 GMT".equals(actual321GmtString));
     }
 
     public void test_parse_timezones() {
diff --git a/luni/src/test/java/libcore/java/util/ForEachRemainingTester.java b/luni/src/test/java/libcore/java/util/ForEachRemainingTester.java
index 9387e96..3bd5b88 100644
--- a/luni/src/test/java/libcore/java/util/ForEachRemainingTester.java
+++ b/luni/src/test/java/libcore/java/util/ForEachRemainingTester.java
@@ -23,6 +23,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.function.Supplier;
 
 import static junit.framework.Assert.*;
 
@@ -32,15 +33,15 @@
  */
 public class ForEachRemainingTester {
 
-    @SuppressWarnings("unchecked")
-    public static <T> void runTests(Class<?> collectionClazz, T[] initialData)
-            throws Exception {
-        test_forEachRemaining((Collection<T>) collectionClazz.newInstance(), initialData);
-        test_forEachRemaining_NPE((Collection<T>) collectionClazz.newInstance(), initialData);
-        test_forEachRemaining_CME((Collection<T>) collectionClazz.newInstance(), initialData);
+    public static <T> void runTests(Supplier<? extends Collection<T>> collectionSupplier,
+            T[] initialData) throws Exception {
+        test_forEachRemaining(collectionSupplier.get(), initialData);
+        test_forEachRemaining_NPE(collectionSupplier.get(), initialData);
+        test_forEachRemaining_CME(collectionSupplier.get(), initialData);
 
-        if (List.class.isAssignableFrom(collectionClazz)) {
-            List<T> asList = (List<T>) collectionClazz.newInstance();
+        Collection<T> collection = collectionSupplier.get();
+        if (collection instanceof List) {
+            List<T> asList = (List<T>) collection;
             test_forEachRemaining_list(asList, initialData);
             test_forEachRemaining_NPE_list(asList, initialData);
             test_forEachRemaining_CME_list(asList, initialData);
diff --git a/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java b/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
index 65a42ab..801271b 100644
--- a/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
+++ b/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
@@ -254,6 +254,76 @@
         assertFalse(m.containsKey("foo"));
     }
 
+    // This tests the behavior of removeEldestEntry when it modifies underlying map on its own,
+    // removing the eldest entry by key if necessary.
+    public void test_removeEldestEntry_removeKey() {
+        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>() {
+            @Override
+            protected boolean removeEldestEntry(Entry<String, String> eldest) {
+                int size = size();
+                if (size > 2) {
+                    remove(eldest.getKey());
+                }
+                return false;
+            }
+        };
+        m.putAll(createMap("K1", "V1", "K2", "V2", "K3", "V3", "K4", "V4"));
+        assertEquals(createMap("K3", "V3", "K4", "V4"), m);
+    }
+
+    // This tests the behavior of removeEldestEntry when it modifies underlying map on its own,
+    // removing the eldest entry by both key and value if necessary.
+    public void test_removeEldestEntry_removeEntry() {
+        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>() {
+            @Override
+            protected boolean removeEldestEntry(Entry<String, String> eldest) {
+                int size = size();
+                if (size > 2) {
+                    remove(eldest.getKey(), eldest.getValue());
+                }
+                return false;
+            }
+        };
+        m.putAll(createMap("K1", "V1", "K2", "V2", "K3", "V3", "K4", "V4"));
+        assertEquals(createMap("K3", "V3", "K4", "V4"), m);
+    }
+
+    // This tests the behavior of removeEldestEntry when it modifies underlying map with order
+    // access on its own, removing the eldest entry by key if necessary.
+    public void test_removeEldestEntry_orderedAccess() {
+        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>(4, 0.75f, true) {
+            @Override
+            protected boolean removeEldestEntry(Entry<String, String> eldest) {
+                int size = size();
+                if (size > 2) {
+                    remove(eldest.getKey(), eldest.getValue());
+                }
+                return false;
+            }
+        };
+        m.putAll(createMap("K1", "V1", "K2", "V2", "K3", "V3"));
+        m.get("K2");
+        m.putAll(createMap("K4", "V4"));
+        assertEquals(createMap("K2", "V2", "K4", "V4"), m);
+    }
+
+    // This tests the behavior of removeEldestEntry when it modifies underlying map on its own,
+    // removing other than passed entry by key if necessary.
+    public void test_removeEldestEntry_removeOtherThanPassedEldest() {
+        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>() {
+            @Override
+            protected boolean removeEldestEntry(Entry<String, String> eldest) {
+                int size = size();
+                if (size > 2) {
+                    remove("K2");
+                }
+                return false;
+            }
+        };
+        m.putAll(createMap("K1", "V1", "K2", "V2", "K3", "V3"));
+        assertEquals(createMap("K1", "V1", "K3", "V3"), m);
+    }
+
     private static<E> int iterableSize(Iterable<E> iterable) {
         int result = 0;
         for (E element : iterable) {
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..6297080 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
@@ -64,7 +58,30 @@
     }
 
     // http://code.google.com/p/android/issues/detail?id=14395
-    public void testPreHistoricInDaylightTime() throws Exception {
+    public void testPreHistoricInDaylightTime() {
+        // A replacement for testPreHistoricInDaylightTime_old() using a zone that still lacks an
+        // explicit transition at Integer.MIN_VALUE with zic 2019a and 2019a data.
+        TimeZone tz = TimeZone.getTimeZone("CET");
+
+        long firstTransitionTimeMillis = -1693706400000L; // Apr 30, 1916 22:00:00 GMT
+        assertEquals(7200000L, tz.getOffset(firstTransitionTimeMillis));
+        assertTrue(tz.inDaylightTime(new Date(firstTransitionTimeMillis)));
+
+        long beforeFirstTransitionTimeMillis = firstTransitionTimeMillis - 1;
+        assertEquals(3600000L, tz.getOffset(beforeFirstTransitionTimeMillis));
+        assertFalse(tz.inDaylightTime(new Date(beforeFirstTransitionTimeMillis)));
+    }
+
+    // http://code.google.com/p/android/issues/detail?id=14395
+    public void testPreHistoricInDaylightTime_old() 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 some zones have an
+        // explicit non-DST transition at time -2^31 seconds so it is no longer possible to test
+        // this with America/Los_Angeles.
+        // This regression test has been kept in case that changes again in future and to prove the
+        // behavior has remained consistent.
+
         Locale.setDefault(Locale.US);
         TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
         TimeZone.setDefault(tz);
@@ -75,7 +92,7 @@
         assertFalse(tz.inDaylightTime(date));
         assertEquals("Fri Oct 31 08:00:00 PST 1902", date.toString());
         assertEquals("31 Oct 1902 16:00:00 GMT", date.toGMTString());
-        // Any time before we have transition data is considered non-daylight, even in summer.
+        // For zic versions <= 2014b, this would be before the first transition.
         date = sdf.parse("1902-06-01T00:00:00.000+0800");
         assertEquals(-28800000, tz.getOffset(date.getTime()));
         assertFalse(tz.inDaylightTime(date));
@@ -88,33 +105,47 @@
     }
 
     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
+        // Note: This test changed after P to account for previously incorrect handling of
+        // prehistoric offsets. http://b/118835133
+        // "Africa/Bissau" has just a few known transitions:
+        // Transition time             : Offset    : DST / non-DST
+        // <Integer.MIN_VALUE secs>[1] : -01:02:20 : non-DST
+        // 1912-01-01 01:00:00 GMT     : -01:00:00 : non-DST
+        // 1975-01-01 01:00:00 GMT     :  00:00:00 : non-DST
+        //
+        // [1] This transition can be implicit or explicit depending on the version of zic used to
+        // generate the data. When implicit, the first non-DST type defn should be used.
         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);
+        // Times before Integer.MIN_VALUE should assume we're using the first non-DST type.
+        assertNonDaylightOffset(-3740, parseIsoTime("1900-01-01T00:00:00.0+0000"), tz);
 
+        // Time before 1912-01-01 01:00:00 but after Integer.MIN_VALUE.
+        assertNonDaylightOffset(-3740, parseIsoTime("1911-01-01T00:00:00.0+0000"), tz);
+
+        // Times after 1912-01-01 01:00:00 should use that transition.
         assertNonDaylightOffset(-3600, parseIsoTime("1912-01-01T12:00:00.0-0100"), tz);
 
-        // Times after our last transition should assume we're still following that transition.
+        // Times after 1975-01-01 01:00:00 should use 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)));
     }
 
+    /** Returns the millis elapsed since the beginning of the Unix epoch. */
     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 +319,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");
@@ -340,18 +346,42 @@
         return String.format("GMT%c%02d:%02d", sign, offset / 60, offset % 60);
     }
 
-    // http://b/18839557
+    /**
+     * This test is to check for 32-bit integer overflow / underflow in TimeZone offset
+     * calculations. A bug (http://b/18839557) was reported when someone noticed that Android's
+     * TimeZone didn't produce the same answers as other libraries at times just outside the range
+     * of Integer seconds. The reason was because of int overflow / underflow which has been fixed.
+     * At the time of writing, Android's java.util.TimeZone implementation only supports reading
+     * TZif version 1 data (32-bit times) and provides one additional "before first transition"
+     * type. This makes Android's time zone information outside of the Integer range unreliable and
+     * unlikely to match libraries that use 64-bit times for transitions and/or calculate times
+     * outside of the range using rules (e.g. like ICU4J does).
+     */
     public void testOverflowing32BitUnixDates() {
         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));
+        // These times are significant because they are outside the 32-bit range for seconds.
+        final long beforeInt32Seconds = -2206292400L; // Thu, 01 Feb 1900 05:00:00 GMT
+        final long afterInt32Seconds = 2206292400L; // Wed, 30 Nov 2039 19:00:00 GMT
+
+        final long lowerTimeMillis = beforeInt32Seconds * 1000L;
+        final long upperTimeMillis = afterInt32Seconds * 1000L;
+
+        // This timezone didn't have any daylight savings prior to 1917 and this date is in 1900.
+        assertFalse(tz.inDaylightTime(new Date(lowerTimeMillis)));
+
+        // http://b/118835133:
+        // zic <= 2014b produces data that suggests before -1633280400 seconds (Sun, 31 Mar 1918
+        // 07:00:00 GMT) the offset was -18000000.
+        // zic > 2014b produces data that suggests before Integer.MIN_VALUE seconds the offset was
+        // -17762000 and between Integer.MIN_VALUE and -1633280400 it was -18000000. Once Android
+        // moves to zic > 2014b the -18000000 can be removed. http://b/73719425
+        int actualOffset = tz.getOffset(lowerTimeMillis);
+        assertTrue(-18000000 == actualOffset || -17762000 == actualOffset);
 
         // 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(upperTimeMillis)));
+        assertEquals(-18000000, tz.getOffset(upperTimeMillis));
     }
 
     public void testTimeZoneIDLocalization() {
@@ -368,22 +398,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 +409,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/prefs/OldAbstractPreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
index 0f8ed99..b5fa493 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldAbstractPreferencesTest.java
@@ -31,7 +31,8 @@
 import java.util.prefs.PreferencesFactory;
 
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+
+import libcore.testing.io.TestIoUtils;
 
 public final class OldAbstractPreferencesTest extends TestCase {
 
@@ -52,7 +53,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        File tmpDir = IoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("OldAbstractPreferencesTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
 
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java b/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
index ea8cb39..5189ab2 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldFilePreferencesImplTest.java
@@ -22,7 +22,7 @@
 
 import junit.framework.TestCase;
 
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 
 public final class OldFilePreferencesImplTest extends TestCase {
 
@@ -31,7 +31,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        File tmpDir = IoUtils.createTemporaryDirectory("OldFilePreferencesImplTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("OldFilePreferencesImplTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
     }
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java b/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
index 7ba1dfe..e87246b 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldNodeChangeEventTest.java
@@ -26,7 +26,7 @@
 
 import junit.framework.TestCase;
 
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 
 public final class OldNodeChangeEventTest extends TestCase {
 
@@ -35,7 +35,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        File tmpDir = IoUtils.createTemporaryDirectory("OldNodeChangeEventTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("OldNodeChangeEventTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
     }
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java b/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
index 2f07129..cb19371 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldPreferenceChangeEventTest.java
@@ -25,7 +25,7 @@
 
 import junit.framework.TestCase;
 
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 
 public final class OldPreferenceChangeEventTest extends TestCase {
 
@@ -34,7 +34,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        File tmpDir = IoUtils.createTemporaryDirectory("OldPreferenceChangeEventTest");
+        File tmpDir = TestIoUtils.createTemporaryDirectory("OldPreferenceChangeEventTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
     }
diff --git a/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
index 7245af7..6c5d323 100644
--- a/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/OldPreferencesTest.java
@@ -28,7 +28,8 @@
 import java.util.prefs.Preferences;
 import java.util.prefs.PreferencesFactory;
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+
+import libcore.testing.io.TestIoUtils;
 
 public final class OldPreferencesTest extends TestCase {
 
@@ -56,7 +57,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        final File tmpDir = IoUtils.createTemporaryDirectory("OldPreferenceTest");
+        final File tmpDir = TestIoUtils.createTemporaryDirectory("OldPreferenceTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new PreferencesTest.TestPreferencesFactory(tmpDir.getAbsolutePath()));
 
diff --git a/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java b/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
index e60b4c6..6857f4e 100644
--- a/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
+++ b/luni/src/test/java/libcore/java/util/prefs/PreferencesTest.java
@@ -24,7 +24,8 @@
 import java.util.prefs.Preferences;
 import java.util.prefs.PreferencesFactory;
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
+
+import libcore.testing.io.TestIoUtils;
 
 public final class PreferencesTest extends TestCase {
 
@@ -60,7 +61,7 @@
 
     @Override
     public void setUp() throws Exception {
-        temporaryDirectory = IoUtils.createTemporaryDirectory("PreferencesTest");
+        temporaryDirectory = TestIoUtils.createTemporaryDirectory("PreferencesTest");
         defaultFactory = Preferences.setPreferencesFactory(
                 new TestPreferencesFactory(temporaryDirectory.getAbsolutePath()));
     }
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..99c7116 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))";
@@ -632,6 +659,29 @@
             m.group("third");
             fail();
         } catch (IllegalArgumentException expected) {}
+        try {
+            m.start("third");
+            fail();
+        } catch (IllegalArgumentException expected) {}
+        try {
+            m.end("third");
+            fail();
+        } catch (IllegalArgumentException expected) {}
+        // Calling group(null) et al should definitely fail, since there is no named-capturing group
+        // of that name. The contract doesn't specifically require either IllegalArgumentException
+        // or NullPointerException and both seem reasonable, so this test accepts either.
+        try {
+            m.group(null);
+            fail();
+        } catch (IllegalArgumentException | NullPointerException expected) {}
+        try {
+            m.start(null);
+            fail();
+        } catch (IllegalArgumentException | NullPointerException expected) {}
+        try {
+            m.end(null);
+            fail();
+        } catch (IllegalArgumentException | NullPointerException expected) {}
 
         try {
             Pattern.compile("(?<>[a-f]*)");
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..19ee2b9 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/HardwareAesTest.java b/luni/src/test/java/libcore/javax/crypto/HardwareAesTest.java
deleted file mode 100644
index f79bb81..0000000
--- a/luni/src/test/java/libcore/javax/crypto/HardwareAesTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-
-import libcore.java.security.CpuFeatures;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class HardwareAesTest {
-
-    @Test
-    public void hardwareAesAvailability() {
-        // Test is only applicable if we know for sure that the device should support
-        // hardware AES.  That covers the important cases (non-emulated ARM and x86_64),
-        // For everything else we assume BoringSSL does the right thing.
-        assumeTrue(CpuFeatures.isKnownToSupportHardwareAes());
-        assertTrue(CpuFeatures.isAesHardwareAccelerated());
-    }
-}
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/javax/net/ssl/FakeSSLContextSpi.java b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLContextSpi.java
new file mode 100644
index 0000000..7151df4
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLContextSpi.java
@@ -0,0 +1,66 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.security.SecureRandom;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ */
+public final class FakeSSLContextSpi extends SSLContextSpi {
+
+    @Override
+    protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
+            SecureRandom secureRandom) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected SSLSocketFactory engineGetSocketFactory() {
+        return new FakeSSLSocketFactory();
+    }
+
+    @Override
+    protected SSLServerSocketFactory engineGetServerSocketFactory() {
+        return new FakeSSLServerSocketFactory();
+    }
+
+    @Override
+    protected SSLEngine engineCreateSSLEngine(String s, int i) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected SSLEngine engineCreateSSLEngine() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected SSLSessionContext engineGetServerSessionContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected SSLSessionContext engineGetClientSessionContext() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/FakeSSLServerSocketFactory.java b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLServerSocketFactory.java
new file mode 100644
index 0000000..2db97ff
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLServerSocketFactory.java
@@ -0,0 +1,57 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ */
+public class FakeSSLServerSocketFactory extends SSLServerSocketFactory {
+
+    public FakeSSLServerSocketFactory() {
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress)
+            throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketFactory.java b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketFactory.java
new file mode 100644
index 0000000..82f7280
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketFactory.java
@@ -0,0 +1,64 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ */
+public class FakeSSLSocketFactory extends SSLSocketFactory {
+
+    public FakeSSLSocketFactory() {
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+            int localPort) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Socket createSocket(InetAddress host, int port) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Socket createSocket(String host, int port) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketProvider.java b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketProvider.java
new file mode 100644
index 0000000..78783f6
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/FakeSSLSocketProvider.java
@@ -0,0 +1,28 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.security.Provider;
+
+/**
+ */
+public class FakeSSLSocketProvider extends Provider {
+
+    public FakeSSLSocketProvider() {
+        super("FakeSSLSocketProvider", 1.0, "Testing provider");
+        put("SSLContext.Default", FakeSSLContextSpi.class.getName());
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
new file mode 100644
index 0000000..9f32ea5
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -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.
+ */
+
+package libcore.javax.net.ssl;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.function.BiFunction;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import junit.framework.TestCase;
+
+public class SSLEngineTest extends TestCase {
+  /**
+   * A basic SSLEngine that has no behavior beyond that of the base class.
+   */
+  private static class PlainSSLEngine extends SSLEngine {
+    @Override public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i1,
+        ByteBuffer byteBuffer) throws SSLException { return null; }
+    @Override public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers,
+        int i, int i1) throws SSLException { return null; }
+    @Override public Runnable getDelegatedTask() { return null; }
+    @Override public void closeInbound() throws SSLException {}
+    @Override public boolean isInboundDone() {  return false; }
+    @Override public void closeOutbound() {}
+    @Override public boolean isOutboundDone() { return false; }
+    @Override public String[] getSupportedCipherSuites() { return new String[0]; }
+    @Override public String[] getEnabledCipherSuites() { return new String[0]; }
+    @Override public void setEnabledCipherSuites(String[] strings) {}
+    @Override public String[] getSupportedProtocols() { return new String[0]; }
+    @Override public String[] getEnabledProtocols() { return new String[0]; }
+    @Override public void setEnabledProtocols(String[] strings) {}
+    @Override public SSLSession getSession() { return null; }
+    @Override public void beginHandshake() throws SSLException {}
+    @Override public HandshakeStatus getHandshakeStatus() { return null; }
+    @Override public void setUseClientMode(boolean b) {}
+    @Override public boolean getUseClientMode() { return false; }
+    @Override public void setNeedClientAuth(boolean b) {}
+    @Override public boolean getNeedClientAuth() { return false; }
+    @Override public void setWantClientAuth(boolean b) {}
+    @Override public boolean getWantClientAuth() { return false; }
+    @Override public void setEnableSessionCreation(boolean b) {}
+    @Override public boolean getEnableSessionCreation() { return false; }
+  }
+
+  public void test_Alpn() throws Exception {
+    SSLEngine engine = new PlainSSLEngine();
+    try {
+      engine.getApplicationProtocol();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.getHandshakeApplicationProtocol();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.setHandshakeApplicationProtocolSelector(
+          new BiFunction<SSLEngine, List<String>, String>() {
+            @Override
+            public String apply(SSLEngine sslEngine, List<String> strings) {
+              return "";
+            }
+          });
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.getHandshakeApplicationProtocolSelector();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
new file mode 100644
index 0000000..620c022
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.util.Arrays;
+import javax.net.ssl.SSLParameters;
+import junit.framework.TestCase;
+
+public class SSLParametersTest extends TestCase {
+
+  public void test_applicationProtocols() {
+    SSLParameters params = new SSLParameters();
+    try {
+      params.setApplicationProtocols(null);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {""});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {null});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {"h2", ""});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {"h2", null});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+
+    // Test that both setApplicationProtocols and getApplicationProtocols clone arrays properly
+    String[] protocols = new String[] {"h2"};
+    params.setApplicationProtocols(protocols);
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+    protocols[0] = "bad";
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+    protocols = params.getApplicationProtocols();
+    protocols[0] = "bad";
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+  }
+
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
new file mode 100644
index 0000000..a0fa449
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.javax.net.ssl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Properties;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
+
+import static org.junit.Assert.assertNotEquals;
+
+public class SSLServerSocketFactoryTest extends TestCase {
+    private static final String SSL_PROPERTY = "ssl.ServerSocketFactory.provider";
+    
+    public void test_SSLServerSocketFactory_getDefault_cacheInvalidate() throws Exception {
+        String origProvider = resetSslProvider();
+        try {
+            ServerSocketFactory sf1 = SSLServerSocketFactory.getDefault();
+            assertNotNull(sf1);
+            assertTrue(SSLServerSocketFactory.class.isAssignableFrom(sf1.getClass()));
+
+            Provider fakeProvider = new FakeSSLSocketProvider();
+            ServerSocketFactory sf4;
+            SSLContext origContext = null;
+            try {
+                origContext = SSLContext.getDefault();
+                Security.insertProviderAt(fakeProvider, 1);
+                SSLContext.setDefault(SSLContext.getInstance("Default", fakeProvider));
+
+                sf4 = SSLServerSocketFactory.getDefault();
+                assertNotNull(sf4);
+                assertTrue(SSLServerSocketFactory.class.isAssignableFrom(sf4.getClass()));
+
+                assertNotEquals(sf1.getClass(), sf4.getClass());
+            } finally {
+                SSLContext.setDefault(origContext);
+                Security.removeProvider(fakeProvider.getName());
+            }
+
+            ServerSocketFactory sf3 = SSLServerSocketFactory.getDefault();
+            assertNotNull(sf3);
+            assertTrue(SSLServerSocketFactory.class.isAssignableFrom(sf3.getClass()));
+
+            assertEquals(sf1.getClass() + " should be " + sf3.getClass(), sf1.getClass(),
+                    sf3.getClass());
+
+            if (!StandardNames.IS_RI) {
+                Security.setProperty(SSL_PROPERTY, FakeSSLServerSocketFactory.class.getName());
+                ServerSocketFactory sf2 = SSLServerSocketFactory.getDefault();
+                assertNotNull(sf2);
+                assertTrue(SSLServerSocketFactory.class.isAssignableFrom(sf2.getClass()));
+
+                assertNotEquals(sf1.getClass(), sf2.getClass());
+                assertEquals(sf2.getClass(), sf4.getClass());
+
+                resetSslProvider();
+            }
+        } finally {
+            Security.setProperty(SSL_PROPERTY, origProvider);
+        }
+    }
+
+    /**
+     * Should only run on Android.
+     */
+    private String resetSslProvider() {
+        String origProvider = Security.getProperty(SSL_PROPERTY);
+
+        try {
+            Field field_secprops = Security.class.getDeclaredField("props");
+            field_secprops.setAccessible(true);
+            Properties secprops = (Properties) field_secprops.get(null);
+            secprops.remove(SSL_PROPERTY);
+            Method m_increaseVersion = Security.class.getDeclaredMethod("increaseVersion");
+            m_increaseVersion.invoke(null);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Could not clear security provider", e);
+        }
+
+        assertNull(Security.getProperty(SSL_PROPERTY));
+        return origProvider;
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
index 8fe329c..ec46f4b 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
@@ -18,120 +18,22 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
 import java.io.InputStream;
-import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketException;
-import java.security.KeyManagementException;
 import java.security.Provider;
-import java.security.SecureRandom;
 import java.security.Security;
 import java.util.Properties;
-import javax.net.ServerSocketFactory;
 import javax.net.SocketFactory;
-import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLContextSpi;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
 import junit.framework.TestCase;
 import libcore.java.security.StandardNames;
 
+import static org.junit.Assert.assertNotEquals;
+
 public class SSLSocketFactoryTest extends TestCase {
     private static final String SSL_PROPERTY = "ssl.SocketFactory.provider";
 
-    public static class FakeSSLSocketProvider extends Provider {
-        public FakeSSLSocketProvider() {
-            super("FakeSSLSocketProvider", 1.0, "Testing provider");
-            put("SSLContext.Default", FakeSSLContextSpi.class.getName());
-        }
-    }
-
-    public static final class FakeSSLContextSpi extends SSLContextSpi {
-        @Override
-        protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
-                SecureRandom secureRandom) throws KeyManagementException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected SSLSocketFactory engineGetSocketFactory() {
-            return new FakeSSLSocketFactory();
-        }
-
-        @Override
-        protected SSLServerSocketFactory engineGetServerSocketFactory() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected SSLEngine engineCreateSSLEngine(String s, int i) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected SSLEngine engineCreateSSLEngine() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected SSLSessionContext engineGetServerSessionContext() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected SSLSessionContext engineGetClientSessionContext() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public static class FakeSSLSocketFactory extends SSLSocketFactory {
-        public FakeSSLSocketFactory() {
-        }
-
-        @Override
-        public String[] getDefaultCipherSuites() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public String[] getSupportedCipherSuites() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
-                int localPort) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Socket createSocket(InetAddress host, int port) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Socket createSocket(String host, int port) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
     public void test_SSLSocketFactory_getDefault_cacheInvalidate() throws Exception {
         String origProvider = resetSslProvider();
         try {
@@ -140,7 +42,7 @@
             assertTrue(SSLSocketFactory.class.isAssignableFrom(sf1.getClass()));
 
             Provider fakeProvider = new FakeSSLSocketProvider();
-            SocketFactory sf4 = null;
+            SocketFactory sf4;
             SSLContext origContext = null;
             try {
                 origContext = SSLContext.getDefault();
@@ -151,8 +53,7 @@
                 assertNotNull(sf4);
                 assertTrue(SSLSocketFactory.class.isAssignableFrom(sf4.getClass()));
 
-                assertFalse(sf1.getClass() + " should not be " + sf4.getClass(),
-                        sf1.getClass().equals(sf4.getClass()));
+                assertNotEquals(sf1.getClass(), sf4.getClass());
             } finally {
                 SSLContext.setDefault(origContext);
                 Security.removeProvider(fakeProvider.getName());
@@ -162,8 +63,7 @@
             assertNotNull(sf3);
             assertTrue(SSLSocketFactory.class.isAssignableFrom(sf3.getClass()));
 
-            assertTrue(sf1.getClass() + " should be " + sf3.getClass(),
-                    sf1.getClass().equals(sf3.getClass()));
+            assertEquals(sf1.getClass(), sf3.getClass());
 
             if (!StandardNames.IS_RI) {
                 Security.setProperty(SSL_PROPERTY, FakeSSLSocketFactory.class.getName());
@@ -171,9 +71,8 @@
                 assertNotNull(sf2);
                 assertTrue(SSLSocketFactory.class.isAssignableFrom(sf2.getClass()));
 
-                assertFalse(sf2.getClass().getName() + " should not be " + Security.getProperty(SSL_PROPERTY),
-                        sf1.getClass().equals(sf2.getClass()));
-                assertTrue(sf2.getClass().equals(sf4.getClass()));
+                assertNotEquals(sf1.getClass(), sf2.getClass());
+                assertEquals(sf2.getClass(), sf4.getClass());
 
                 resetSslProvider();
             }
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index fe5e1ae..0f87d14 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -17,6 +17,8 @@
 package libcore.javax.net.ssl;
 
 import java.io.IOException;
+import java.util.List;
+import java.util.function.BiFunction;
 import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
@@ -24,34 +26,39 @@
 
 public class SSLSocketTest extends TestCase {
 
+    /**
+     * A basic SSLSocket that has no behavior beyond that of the base class.
+     */
+    private static class PlainSSLSocket extends SSLSocket {
+        @Override public String[] getSupportedCipherSuites() { return new String[0]; }
+        @Override public String[] getEnabledCipherSuites() { return new String[0]; }
+        @Override public void setEnabledCipherSuites(String[] strings) { }
+        @Override public String[] getSupportedProtocols() { return new String[0]; }
+        @Override public String[] getEnabledProtocols() { return new String[0]; }
+        @Override public void setEnabledProtocols(String[] strings) { }
+        @Override public SSLSession getSession() { return null; }
+        @Override public void addHandshakeCompletedListener(
+            HandshakeCompletedListener handshakeCompletedListener) { }
+        @Override public void removeHandshakeCompletedListener(
+            HandshakeCompletedListener handshakeCompletedListener) { }
+        @Override public void startHandshake() throws IOException { }
+        @Override public void setUseClientMode(boolean b) { }
+        @Override public boolean getUseClientMode() { return false; }
+        @Override public void setNeedClientAuth(boolean b) { }
+        @Override public boolean getNeedClientAuth() { return false; }
+        @Override public void setWantClientAuth(boolean b) { }
+        @Override public boolean getWantClientAuth() { return false; }
+        @Override public void setEnableSessionCreation(boolean b) { }
+        @Override public boolean getEnableSessionCreation() { return false; }
+    }
+
     // We modified the toString() of SSLSocket, and it's based on the output
     // of Socket.toString(), so we want to make sure that a change in
     // Socket.toString() doesn't cause us to output nonsense.
     public void test_SSLSocket_toString() throws Exception {
         // The actual implementation from a security provider might do something
         // special for its toString(), so we create our own implementation
-        SSLSocket socket = new SSLSocket() {
-            @Override public String[] getSupportedCipherSuites() { return new String[0]; }
-            @Override public String[] getEnabledCipherSuites() { return new String[0]; }
-            @Override public void setEnabledCipherSuites(String[] strings) { }
-            @Override public String[] getSupportedProtocols() { return new String[0]; }
-            @Override public String[] getEnabledProtocols() { return new String[0]; }
-            @Override public void setEnabledProtocols(String[] strings) { }
-            @Override public SSLSession getSession() { return null; }
-            @Override public void addHandshakeCompletedListener(
-                    HandshakeCompletedListener handshakeCompletedListener) { }
-            @Override public void removeHandshakeCompletedListener(
-                    HandshakeCompletedListener handshakeCompletedListener) { }
-            @Override public void startHandshake() throws IOException { }
-            @Override public void setUseClientMode(boolean b) { }
-            @Override public boolean getUseClientMode() { return false; }
-            @Override public void setNeedClientAuth(boolean b) { }
-            @Override public boolean getNeedClientAuth() { return false; }
-            @Override public void setWantClientAuth(boolean b) { }
-            @Override public boolean getWantClientAuth() { return false; }
-            @Override public void setEnableSessionCreation(boolean b) { }
-            @Override public boolean getEnableSessionCreation() { return false; }
-        };
+        SSLSocket socket = new PlainSSLSocket();
         assertTrue(socket.toString().startsWith("SSLSocket["));
     }
 
@@ -80,6 +87,36 @@
         }
     }
 
+    public void test_Alpn() throws Exception {
+        SSLSocket socket = new PlainSSLSocket();
+        try {
+            socket.getApplicationProtocol();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.getHandshakeApplicationProtocol();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.setHandshakeApplicationProtocolSelector(
+                new BiFunction<SSLSocket, List<String>, String>() {
+                    @Override
+                    public String apply(SSLSocket sslSocket, List<String> strings) {
+                        return "";
+                    }
+                });
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.getHandshakeApplicationProtocolSelector();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
     public static void main (String[] args) {
         new SSLSocketTest().stress_test_TestSSLSocketPair_create();
     }
diff --git a/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java b/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java
index 24c7b33..c659f9d 100644
--- a/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java
@@ -23,6 +23,7 @@
 import java.util.Locale;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Test for {@link android.icu.text.AlphabeticIndex}
@@ -36,16 +37,28 @@
 
     // http://b/64953401
     @Test
-    public void test_amharic() {
-        Locale amharic = Locale.forLanguageTag("am");
-        UnicodeSet exemplarSet = LocaleData
-                .getExemplarSet(ULocale.forLocale(amharic), 0, LocaleData.ES_INDEX);
-        // If this assert fails it means that the am locale has gained an exemplar characters set
-        // for index (see key ExemplarCharactersIndex in locale/am.txt). If that's the case, please
-        // find another locale that's missing that key where the logic in
-        // AlphabeticIndex.addIndexExemplars will generate buckets from alternate data.
-        assertTrue(exemplarSet == null || exemplarSet.isEmpty());
-        verifyIndex(amharic);
+    public void testBucketCount_withNoIndexCharacters() {
+        Locale localeWithNoIndexCharacters = null;
+        // Search in the available languages only instead of all possible locales
+        // in order to speed-up the test.
+        for (String language : Locale.getISOLanguages()) {
+            Locale locale = Locale.forLanguageTag(language);
+            UnicodeSet exemplarSet = LocaleData.getExemplarSet(
+                ULocale.forLocale(locale), 0, LocaleData.ES_INDEX);
+            if (exemplarSet == null || exemplarSet.isEmpty()) {
+                localeWithNoIndexCharacters = locale;
+                break;
+            }
+        }
+
+        assertNotNull("Can't find any language with no index characters",
+            localeWithNoIndexCharacters);
+
+        // If this assert fails it means that it can't find any language with no index character.
+        // If that's the case, please find expand the search space to find a locale that's missing
+        // that key where the logic in AlphabeticIndex.addIndexExemplars will generate buckets from
+        // alternate data.
+        verifyIndex(localeWithNoIndexCharacters);
     }
 
     private void verifyIndex(Locale locale) {
@@ -58,6 +71,7 @@
         for (String s : exemplarSet) {
             index.addRecord(s, s);
         }
-        assertTrue("Not enough buckets: " + index.getBucketLabels(), index.getBucketCount() > 1);
+        assertTrue("Locale(" + locale + ") does not have enough buckets: " + index.getBucketLabels(),
+            index.getBucketCount() > 1);
     }
 }
diff --git a/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
index 7d2cb93..55af0e2 100644
--- a/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
@@ -20,6 +20,10 @@
 import android.icu.util.TimeZone;
 import android.icu.util.ULocale;
 
+import java.util.function.BiFunction;
+
+import static android.icu.util.TimeZone.GMT_ZONE;
+import static android.icu.util.ULocale.ENGLISH;
 import static libcore.icu.DateIntervalFormat.formatDateRange;
 import static libcore.icu.DateUtilsBridge.*;
 
@@ -83,8 +87,8 @@
     assertEquals("1/19/2009 – 2/9/2012", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
 
     assertEquals("19.1.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
-    assertEquals("19.01.2009 – 22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
-    assertEquals("19.01.2009 – 22.04.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+    assertEquals("19.–22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
+    assertEquals("19.01. – 22.04.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
     assertEquals("19.01.2009 – 09.02.2012", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
 
     assertEquals("19/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
@@ -433,44 +437,45 @@
   }
 
   // http://b/68847519
-  public void testEndAtMidnight() {
-    ULocale locale = new ULocale("en");
-    TimeZone timeZone = TimeZone.getTimeZone("UTC");
-    int dateTimeFlags = FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR;
+  public void testEndAtMidnight_dateAndTime() {
+    BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange(
+            ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR);
     // If we're showing times and the end-point is midnight the following day, we want the
     // behaviour of suppressing the date for the end...
-    assertEquals("February 27, 2018, 04:00 – 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 04:00 – 00:00", fmt.apply(1172548800000L, 1172620800000L));
     // ...unless the start-point is also midnight, in which case we need dates to disambiguate.
-    assertEquals("February 27, 2018, 00:00 – February 28, 2018, 00:00",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00",
+            fmt.apply(1172534400000L, 1172620800000L));
     // We want to show the date if the end-point is a millisecond after midnight the following
     // day, or if it is exactly midnight the day after that.
-    assertEquals("February 27, 2018, 04:00 – February 28, 2018, 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519776000001L, dateTimeFlags));
-    assertEquals("February 27, 2018, 04:00 – March 1, 2018, 00:00",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519862400000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 04:00 – February 28, 2007, 00:00",
+            fmt.apply(1172548800000L, 1172620800001L));
+    assertEquals("February 27, 2007, 04:00 – March 1, 2007, 00:00",
+            fmt.apply(1172548800000L, 1172707200000L));
     // We want to show the date if the start-point is anything less than a minute after midnight,
     // since that gets displayed as midnight...
-    assertEquals("February 27, 2018, 00:00 – February 28, 2018, 00:00",
-        formatDateRange(locale, timeZone, 1519689659999L, 1519776000000L, dateTimeFlags));
+    assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00",
+            fmt.apply(1172534459999L, 1172620800000L));
     // ...but not if it is exactly one minute after midnight.
-    assertEquals("February 27, 2018, 00:01 – 00:00",
-        formatDateRange(locale, timeZone, 1519689660000L, 1519776000000L, dateTimeFlags));
-    int dateOnlyFlags = FORMAT_SHOW_DATE;
-    // If we're only showing dates and the end-point is midnight of any day, we want the
-    // behaviour of showing an end date one earlier. So if the end-point is March 2, 00:00, show
-    // March 1 instead (whether the start-point is midnight or not).
-    assertEquals("February 27 – March 1, 2018",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519948800000L, dateOnlyFlags));
-    assertEquals("February 27 – March 1, 2018",
-        formatDateRange(locale, timeZone, 1519704000000L, 1519948800000L, dateOnlyFlags));
-    // We want to show the true date if the end-point is a millisecond after midnight.
-    assertEquals("February 27 – March 2, 2018",
-        formatDateRange(locale, timeZone, 1519689600000L, 1519948800001L, dateOnlyFlags));
+    assertEquals("February 27, 2007, 00:01 – 00:00", fmt.apply(1172534460000L, 1172620800000L));
+  }
 
-    // 2017-02-27 00:00:00.000 GMT - 2018-03-02 00:00:00.000 GMT
-    assertEquals("February 27, 2017 – March 1, 2018",
-            formatDateRange(locale, timeZone, 1488153600000L, 1519948800000L, dateOnlyFlags));
+  // http://b/68847519
+  public void testEndAtMidnight_dateOnly() {
+    BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange(
+            ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE);
+    // If we're only showing dates and the end-point is midnight of any day, we want the
+    // behaviour of showing an end date one earlier. So if the end-point is March 2, 2007 00:00,
+    // show March 1, 2007 instead (whether the start-point is midnight or not).
+    assertEquals("February 27 – March 1, 2007", fmt.apply(1172534400000L, 1172793600000L));
+    assertEquals("February 27 – March 1, 2007", fmt.apply(1172548800000L, 1172793600000L));
+    // We want to show the true date if the end-point is a millisecond after midnight.
+    assertEquals("February 27 – March 2, 2007", fmt.apply(1172534400000L, 1172793600001L));
+
+    // 2006-02-27 00:00:00.000 GMT - 2007-03-02 00:00:00.000 GMT
+    assertEquals("February 27, 2006 – March 1, 2007", fmt.apply(1140998400000L, 1172793600000L));
+
+    // Spans a leap year's Feb 29th.
+    assertEquals("February 27 – March 1, 2004", fmt.apply(1077840000000L, 1078185600000L));
   }
 }
diff --git a/luni/src/test/java/libcore/libcore/icu/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/ICUCurrencyTest.java b/luni/src/test/java/libcore/libcore/icu/ICUCurrencyTest.java
new file mode 100644
index 0000000..48c8655
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/ICUCurrencyTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.assertNotNull;
+
+import java.util.Currency;
+import java.util.Locale;
+import org.junit.Test;
+
+public class ICUCurrencyTest {
+
+  /**
+   * Regression test that ensures CLDR root data has U+00A4 ¤ as the
+   * symbol for unknown currency XXX.
+   * http://b/113149899
+   */
+  @Test
+  public void test_fallbackCurrencySymbolForUnknownLocale() {
+    final String unknownCurrencySymbol = "\u00a4"; // "¤"
+
+    Currency c = Currency.getInstance("XXX");
+    assertNotNull(c);
+    assertEquals(unknownCurrencySymbol, c.getSymbol(Locale.ROOT));
+
+    android.icu.util.Currency ac = android.icu.util.Currency.getInstance("XXX");
+    assertNotNull(ac);
+    assertEquals(unknownCurrencySymbol, ac.getSymbol(android.icu.util.ULocale.ROOT));
+  }
+
+}
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/LocaleDataTest.java b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
index f5be28b..607397d 100644
--- a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
@@ -138,4 +138,12 @@
     LocaleData haw = LocaleData.get(new Locale("haw"));
     assertFalse(haw.shortDateFormat.isEmpty());
   }
+
+  /**
+   * Check that LocaleData.get() does not throw when the input locale is invalid.
+   * http://b/129070579
+   */
+  public void testInvalidLocale() {
+    LocaleData.get(new Locale("invalidLocale"));
+  }
 }
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..32dbb1c
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
@@ -0,0 +1,537 @@
+/*
+ * 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 android.icu.util.VersionInfo;
+import android.system.Os;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+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 java.util.function.Function;
+import java.util.stream.Collectors;
+
+import libcore.icu.ICU;
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.timezone.TimeZoneFinder;
+import libcore.timezone.TzDataSetVersion;
+import libcore.timezone.ZoneInfoDB;
+import libcore.util.CoreLibraryDebug;
+import libcore.util.DebugInfo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+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);
+    }
+
+    /**
+     * Asserts that the time zone format major / minor versions meets expectations.
+     *
+     * <p>If a set of time zone files is to be compatible with a device then the format of the files
+     * must meet the Android team's expectations. This is a sanity check to ensure that devices
+     * running the test (e.g. under CTS) have not modified the TzDataSetVersion major / minor
+     * versions for some reason: if they have it would render updated time zone files sent to the
+     * device incompatible.
+     */
+    @Test
+    public void testTimeZoneFormatVersion() {
+        // The code below compares the final static int constant values (inlined at test compile
+        // time) with the version reported at runtime. This saves us hardcoding the numbers in two
+        // places.
+        assertEquals(TzDataSetVersion.CURRENT_FORMAT_MAJOR_VERSION,
+                TzDataSetVersion.currentFormatMajorVersion());
+        assertEquals(TzDataSetVersion.CURRENT_FORMAT_MINOR_VERSION,
+                TzDataSetVersion.currentFormatMinorVersion());
+    }
+
+    /**
+     * Asserts that all expected sets of time zone files meet format expectations.
+     *
+     * <p>This uses the device's knowledge of the format version it expects and the
+     * {@link TzDataSetVersion} files that accompany the known time zone data files.
+     *
+     * <p>This is a sanity check to ensure that there's no way of installing incompatible data
+     * on a device. It assumes that {@link TzDataSetVersion} is updated as it should be when changes
+     * are made that might affect time zone code / time zone data compatibility.
+     */
+    @Test
+    public void testTzDataSetVersions() throws Exception {
+        String moduleTzVersionFile = "tz/" + TzDataSetVersion.DEFAULT_FILE_NAME;
+
+        String timeZoneModuleVersionFile =
+                TimeZoneDataFiles.getTimeZoneModuleFile(moduleTzVersionFile);
+        // We currently treat the time zone APEX as optional in code. Its is also not present on ART
+        // host environments.
+        if (fileExists(timeZoneModuleVersionFile)) {
+            assertTzDataSetVersionIsCompatible(timeZoneModuleVersionFile);
+        }
+
+        String runtimeModuleVersionFile =
+                TimeZoneDataFiles.getRuntimeModuleFile(moduleTzVersionFile);
+        assertTzDataSetVersionIsCompatible(runtimeModuleVersionFile);
+
+        // Check getRuntimeModuleTzVersionFile() is doing the right thing.
+        // getRuntimeModuleTzVersionFile() should go away when its one user, RulesManagerService,
+        // is removed from the platform code. http://b/123398797
+        assertEquals(TimeZoneDataFiles.getRuntimeModuleTzVersionFile(), runtimeModuleVersionFile);
+
+        // TODO: Remove this once the /system copy of time zone files have gone away. See also
+        // testTimeZoneDebugInfo().
+        assertTzDataSetVersionIsCompatible(
+                TimeZoneDataFiles.getSystemTimeZoneFile(TzDataSetVersion.DEFAULT_FILE_NAME));
+    }
+
+    private static void assertTzDataSetVersionIsCompatible(String versionFile) throws Exception {
+        TzDataSetVersion actualVersion =
+                TzDataSetVersion.readFromFile(new File(versionFile));
+        assertEquals(
+                TzDataSetVersion.currentFormatMajorVersion(),
+                actualVersion.formatMajorVersion);
+        int minDeviceMinorVersion = TzDataSetVersion.currentFormatMinorVersion();
+        assertTrue(actualVersion.formatMinorVersion >= minDeviceMinorVersion);
+    }
+
+    /**
+     * A test for confirming debug information matches file system state on device.
+     * It can also be used to confirm that device and host environments satisfy file system
+     * expectations.
+     */
+    @Test
+    public void testTimeZoneDebugInfo() throws Exception {
+        DebugInfo debugInfo = CoreLibraryDebug.getDebugInfo();
+
+        // Devices are expected to have a time zone module which overrides or extends the data in
+        // the runtime module depending on the file. It's not actually mandatory for all Android
+        // devices right now although it may be required for some subset of Android devices. It
+        // isn't present on host ART.
+        String tzModuleStatus = getDebugStringValue(debugInfo,
+                "core_library.timezone.source.tzdata_module_status");
+        String apexRootDir = TimeZoneDataFiles.getTimeZoneModuleFile("");
+        List<String> dataModuleFiles =
+                createModuleTzFileNames(TimeZoneDataFiles::getTimeZoneModuleFile);
+        String icuOverlayFile = TimeZoneDataFiles.getTimeZoneModuleFile("icu/icu_tzdata.dat");
+        if (fileExists(apexRootDir)) {
+            assertEquals("OK", tzModuleStatus);
+            dataModuleFiles.forEach(TimeZoneIntegrationTest::assertFileExists);
+            assertFileExists(icuOverlayFile);
+        } else {
+            assertEquals("NOT_FOUND", tzModuleStatus);
+            dataModuleFiles.forEach(TimeZoneIntegrationTest::assertFileDoesNotExist);
+            assertFileDoesNotExist(icuOverlayFile);
+        }
+
+        // Every device should have a runtime module copy of time zone data since we expect every
+        // device to have a runtime module. This is the base copy of time zone data that can be
+        // updated when we update the runtime module. Host ART should match device.
+        assertEquals("OK", getDebugStringValue(debugInfo,
+                "core_library.timezone.source.runtime_module_status"));
+        assertFileExists(TimeZoneDataFiles.getRuntimeModuleFile(""));
+        List<String> runtimeModuleFiles =
+                createModuleTzFileNames(TimeZoneDataFiles::getRuntimeModuleFile);
+        runtimeModuleFiles.forEach(TimeZoneIntegrationTest::assertFileExists);
+
+        String icuDatFileName = "icudt" + VersionInfo.ICU_VERSION.getMajor() + "l.dat";
+        String runtimeModuleIcuData =
+                TimeZoneDataFiles.getRuntimeModuleFile("icu/" + icuDatFileName);
+        assertFileExists(runtimeModuleIcuData);
+
+        // Devices currently have a subset of the time zone files in /system. These are going away
+        // but we test them while they exist. Host ART should match device.
+        assertEquals("OK", getDebugStringValue(debugInfo,
+                "core_library.timezone.source.system_status"));
+        assertFileExists(
+                TimeZoneDataFiles.getSystemTimeZoneFile(TzDataSetVersion.DEFAULT_FILE_NAME));
+        assertFileExists(TimeZoneDataFiles.getSystemTimeZoneFile("tzdata"));
+        // The following files once existed in /system but have been removed as part of APEX work.
+        assertFileDoesNotExist(TimeZoneDataFiles.getSystemTimeZoneFile("tzlookup.xml"));
+
+        // It's hard to assert much about this file as there is a symlink in /system on device for
+        // app compatibility (b/122985829) but it doesn't exist in host environments. If the file
+        // exists we can say it should resolve (realpath) to the same file as the runtime module.
+        String systemIcuData = TimeZoneDataFiles.getSystemIcuFile(icuDatFileName);
+        if (new File(systemIcuData).exists()) {
+            assertEquals(Os.realpath(runtimeModuleIcuData), Os.realpath(systemIcuData));
+        }
+    }
+
+    private static List<String> createModuleTzFileNames(
+            Function<String, String> pathCreationFunction) {
+        List<String> relativePaths = Arrays.asList(
+                "tz/" + TzDataSetVersion.DEFAULT_FILE_NAME,
+                "tz/tzdata",
+                "tz/tzlookup.xml");
+        return relativePaths.stream().map(pathCreationFunction).collect(Collectors.toList());
+    }
+
+    private static boolean fileExists(String fileName) {
+        return new File(fileName).exists();
+    }
+
+    private static void assertFileDoesNotExist(String fileName) {
+        assertFalse(fileName + " must not exist", fileExists(fileName));
+    }
+
+    private static void assertFileExists(String fileName) {
+        assertTrue(fileName + " must exist", fileExists(fileName));
+    }
+
+    private String getDebugStringValue(DebugInfo debugInfo, String key) {
+        return debugInfo.getDebugEntry(key).getStringValue();
+    }
+
+    /**
+     * Confirms that ICU can recognize all the time zone IDs used by the ZoneInfoDB data.
+     * ICU's IDs may be a superset.
+     */
+    @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/icu/TimeZoneNamesTest.java b/luni/src/test/java/libcore/libcore/icu/TimeZoneNamesTest.java
deleted file mode 100644
index f16e3bc..0000000
--- a/luni/src/test/java/libcore/libcore/icu/TimeZoneNamesTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 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 java.util.Arrays;
-import java.util.Locale;
-import java.util.HashSet;
-import java.util.TimeZone;
-import libcore.icu.TimeZoneNames;
-
-public class TimeZoneNamesTest extends junit.framework.TestCase {
-  public void test_forLocale() throws Exception {
-    String[] ids = TimeZoneNames.forLocale(Locale.CANADA);
-    // Check that we got some ids.
-    assertTrue(ids.length > 0);
-    HashSet<String> allIds = new HashSet<String>(Arrays.asList(TimeZone.getAvailableIDs()));
-    // Check that they're all real.
-    for (String id : ids) {
-      assertTrue(allIds.contains(id));
-    }
-    // Check that Toronto comes before Atikokan. http://b/8391426.
-    int toronto = linearSearch(ids, "America/Toronto");
-    assertTrue(toronto >= 0);
-    int atikokan = linearSearch(ids, "America/Atikokan");
-    assertTrue(atikokan >= 0);
-    assertTrue(toronto < atikokan);
-  }
-
-  private int linearSearch(String[] xs, String x) {
-    for (int i = 0; i < xs.length; ++i) {
-      if (xs[i].equals(x)) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  public void testBug9327819() throws Exception {
-    // Check one specific example of a zone.tab line without a comment thoroughly.
-    String[] ids = TimeZoneNames.forLocale(Locale.KOREA);
-    assertEquals("Asia/Seoul", ids[0]);
-    assertEquals(1, ids.length);
-
-    // Now check we can parse all countries' lines.
-    for (Locale l : Locale.getAvailableLocales()) {
-      assertTrue(TimeZoneNames.forLocale(l) != null);
-    }
-  }
-}
diff --git a/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java
new file mode 100644
index 0000000..cc48ec0
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.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 libcore.libcore.internal;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+import libcore.internal.Java9LanguageFeatures;
+
+public class Java9LanguageFeaturesTest extends TestCase {
+
+    public static class SimplePerson implements Java9LanguageFeatures.Person {
+        private final String name;
+        public SimplePerson(String name) { this.name = Objects.requireNonNull(name); }
+        @Override public String toString() { return "Person: " + name; }
+        @Override public String name() { return name; }
+    }
+
+    public void testPrivateInterfaceMethods() {
+        assertFalse(new SimplePerson("Anna").isPalindrome());
+        assertTrue(new SimplePerson("Anna").isPalindromeIgnoreCase());
+        assertTrue(new SimplePerson("anna").isPalindrome());
+        assertTrue(new SimplePerson("bob").isPalindrome());
+        assertFalse(new SimplePerson("larry").isPalindrome());
+        assertFalse(new SimplePerson("larry").isPalindromeIgnoreCase());
+    }
+
+    public void testTryOnEffectivelyFinalVariables() throws IOException {
+        byte[] data = "Hello, world!".getBytes();
+        byte[] dataCopy = Java9LanguageFeatures.copy(data);
+        assertTrue(Arrays.equals(data, dataCopy));
+        assertTrue(data != dataCopy);
+    }
+
+    public void testDiamondOnAnonymousClasses() {
+        AtomicReference<String> ref = new Java9LanguageFeatures().createReference("Hello, world");
+        assertSame("Hello, world", ref.get());
+    }
+
+    public void testSafeVarargsOnPrivateMethod() {
+        assertEquals("[23, and, 42]", Java9LanguageFeatures.toListString(23, "and", 42L));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 7015521..0e2c6b5 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -16,6 +16,12 @@
 
 package libcore.libcore.io;
 
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -24,10 +30,14 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import android.system.ErrnoException;
 import android.system.OsConstants;
 import android.system.StructAddrinfo;
 
+import java.io.FileDescriptor;
+import java.io.IOException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.net.InetAddress;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -37,6 +47,8 @@
 import java.util.regex.Pattern;
 
 import libcore.io.BlockGuardOs;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
 import libcore.io.Os;
 
 import dalvik.system.BlockGuard;
@@ -46,6 +58,8 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -57,22 +71,42 @@
 
     @Mock private Os mockOsDelegate;
     @Mock private BlockGuard.Policy mockThreadPolicy;
+    @Mock private BlockGuard.VmPolicy mockVmPolicy;
 
     private BlockGuard.Policy savedThreadPolicy;
+    private BlockGuard.VmPolicy savedVmPolicy;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         savedThreadPolicy = BlockGuard.getThreadPolicy();
+        savedVmPolicy = BlockGuard.getVmPolicy();
         BlockGuard.setThreadPolicy(mockThreadPolicy);
+        BlockGuard.setVmPolicy(mockVmPolicy);
     }
 
     @After
     public void tearDown() {
+        BlockGuard.setVmPolicy(savedVmPolicy);
         BlockGuard.setThreadPolicy(savedThreadPolicy);
     }
 
     @Test
+    public void test_blockguardOsIsNotifiedByDefault_rename() {
+        String oldPath = "BlockGuardOsTest/missing/old/path";
+        String newPath = "BlockGuardOsTest/missing/new/path";
+        try {
+            // We try not to be prescriptive about the exact default Os implementation.
+            // Whatever default Os is installed, we do expect BlockGuard to be called.
+            Os.getDefault().rename(oldPath, newPath);
+        } catch (ErrnoException ignored) {
+        }
+        verify(mockThreadPolicy).onWriteToDisk();
+        verify(mockVmPolicy).onPathAccess(oldPath);
+        verify(mockVmPolicy).onPathAccess(newPath);
+    }
+
+    @Test
     public void test_android_getaddrinfo_networkPolicy() {
         InetAddress[] addresses = new InetAddress[] { InetAddress.getLoopbackAddress() };
         when(mockOsDelegate.android_getaddrinfo(anyString(), any(), anyInt()))
@@ -108,6 +142,31 @@
         }
     }
 
+    @Test
+    public void test_connect_networkPolicy() throws ErrnoException, IOException {
+        BlockGuardOs blockGuardOs = new BlockGuardOs(mockOsDelegate);
+
+        // Test connect with a UDP socket that will not trigger a network policy check.
+        FileDescriptor udpSocket = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+        try {
+            blockGuardOs.connect(udpSocket, InetAddress.getLoopbackAddress(), 0);
+            verify(mockThreadPolicy, never()).onNetwork();
+            verify(mockOsDelegate, times(1)).connect(eq(udpSocket), any(), anyInt());
+        } finally {
+            IoUtils.closeQuietly(udpSocket);
+        }
+
+        // Test connect with a TCP socket that will trigger a network policy check.
+        FileDescriptor tcpSocket = Libcore.os.socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+        try {
+            blockGuardOs.connect(tcpSocket, InetAddress.getLoopbackAddress(), 0);
+            verify(mockThreadPolicy, times(1)).onNetwork();
+            verify(mockOsDelegate, times(1)).connect(eq(tcpSocket), any(), anyInt());
+        } finally {
+            IoUtils.closeQuietly(tcpSocket);
+        }
+    }
+
     /**
      * Checks that BlockGuardOs is updated when the Os interface changes. BlockGuardOs extends
      * ForwardingOs so doing so isn't an obvious step and it can be missed. When adding methods to
@@ -119,6 +178,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)",
@@ -211,7 +274,11 @@
 
         // Verify that all the methods in libcore.io.Os should either be overridden in BlockGuardOs
         // or else they should be in the "methodsNotRequiredBlockGuardCheckSet".
+        // We don't care about static methods because they can't be overridden.
         for (Method method : Os.class.getDeclaredMethods()) {
+            if (Modifier.isStatic(method.getModifiers())) {
+                continue;
+            }
             String methodSignature = method.toString();
             String methodNameAndParameters = getMethodNameAndParameters(methodSignature);
             if (!methodsNotRequiredBlockGuardCheckSet.contains(methodNameAndParameters) &&
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/ForwardingOsTest.java b/luni/src/test/java/libcore/libcore/io/ForwardingOsTest.java
new file mode 100644
index 0000000..47ec910
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/io/ForwardingOsTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertTrue;
+
+import libcore.io.ForwardingOs;
+import libcore.io.Os;
+
+@RunWith(JUnit4.class)
+public class ForwardingOsTest {
+    @Test
+    public void constructor_nullDelegate() {
+        try {
+            new ForwardingOs(null) {};
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void toStringContainsDelegate() {
+        String msg = "toString() for testing";
+        Os mockOs = Mockito.mock(Os.class);
+        Mockito.when(mockOs.toString()).thenReturn(msg);
+        ForwardingOs os = new ForwardingOs(mockOs) {};
+        // Wrapping may either keep the wrapped toString(), or expand on it; either is
+        // fine, as the wrapped toString() is still contained.
+        assertTrue(os.toString(), os.toString().contains(msg));
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/io/MemoryMappedFileTest.java b/luni/src/test/java/libcore/libcore/io/MemoryMappedFileTest.java
index 356acf0..1936ea7 100644
--- a/luni/src/test/java/libcore/libcore/io/MemoryMappedFileTest.java
+++ b/luni/src/test/java/libcore/libcore/io/MemoryMappedFileTest.java
@@ -29,9 +29,8 @@
 import java.util.Arrays;
 import java.util.function.Function;
 import libcore.io.BufferIterator;
-import libcore.io.IoUtils;
 import libcore.io.MemoryMappedFile;
-import libcore.io.SizeOf;
+import libcore.testing.io.TestIoUtils;
 
 public class MemoryMappedFileTest extends TestCase {
 
@@ -40,7 +39,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        tempDir = IoUtils.createTemporaryDirectory("MemoryMappedFileTest");
+        tempDir = TestIoUtils.createTemporaryDirectory("MemoryMappedFileTest");
     }
 
     public void testMmapRo_missingFile() throws Exception {
@@ -594,7 +593,7 @@
         iterator.readIntArray(dst, 1, intCount);
 
         assertArrayEquals(expectedInts, dst);
-        assertEquals(posBefore + (intCount * SizeOf.INT), iterator.pos());
+        assertEquals(posBefore + (intCount * Integer.BYTES), iterator.pos());
     }
 
     private static void assertReadIntFails(BufferIterator iterator) {
@@ -610,7 +609,7 @@
     private static void assertReadIntSucceeds(BufferIterator iterator, int expectedValue) {
         int posBefore = iterator.pos();
         assertEquals(expectedValue, iterator.readInt());
-        assertEquals(posBefore + SizeOf.INT, iterator.pos());
+        assertEquals(posBefore + Integer.BYTES, iterator.pos());
     }
 
     private static void assertReadShortFails(BufferIterator iterator) {
@@ -626,7 +625,7 @@
     private static void assertReadShortSucceeds(BufferIterator iterator, short expectedValue) {
         int posBefore = iterator.pos();
         assertEquals(expectedValue, iterator.readShort());
-        assertEquals(posBefore + SizeOf.SHORT, iterator.pos());
+        assertEquals(posBefore + Short.BYTES, iterator.pos());
     }
 
     private static void assertReadByteFails(BufferIterator iterator) {
diff --git a/luni/src/test/java/libcore/libcore/io/MemoryTest.java b/luni/src/test/java/libcore/libcore/io/MemoryTest.java
index c2603b2..80ff4ea 100644
--- a/luni/src/test/java/libcore/libcore/io/MemoryTest.java
+++ b/luni/src/test/java/libcore/libcore/io/MemoryTest.java
@@ -22,7 +22,6 @@
 import junit.framework.TestCase;
 
 import libcore.io.Memory;
-import libcore.io.SizeOf;
 
 public class MemoryTest extends TestCase {
     public void testSetIntArray() {
@@ -32,7 +31,7 @@
             swappedValues[i] = Integer.reverseBytes(values[i]);
         }
 
-        int scale = SizeOf.INT;
+        int scale = Integer.BYTES;
         VMRuntime runtime = VMRuntime.getRuntime();
         byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
         long base_ptr = runtime.addressOf(array);
@@ -62,7 +61,7 @@
 
     private void assertIntsEqual(int[] expectedValues, long ptr, boolean swap) {
         for (int i = 0; i < expectedValues.length; ++i) {
-            assertEquals(expectedValues[i], Memory.peekInt(ptr + SizeOf.INT * i, swap));
+            assertEquals(expectedValues[i], Memory.peekInt(ptr + Integer.BYTES * i, swap));
         }
     }
 
@@ -73,7 +72,7 @@
             swappedValues[i] = Long.reverseBytes(values[i]);
         }
 
-        int scale = SizeOf.LONG;
+        int scale = Long.BYTES;
         VMRuntime runtime = VMRuntime.getRuntime();
         byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
         long base_ptr = runtime.addressOf(array);
@@ -103,7 +102,7 @@
 
     private void assertLongsEqual(long[] expectedValues, long ptr, boolean swap) {
       for (int i = 0; i < expectedValues.length; ++i) {
-        assertEquals(expectedValues[i], Memory.peekLong(ptr + SizeOf.LONG * i, swap));
+        assertEquals(expectedValues[i], Memory.peekLong(ptr + Long.BYTES * i, swap));
       }
     }
 
@@ -111,7 +110,7 @@
         short[] values = { 0x0001, 0x0020, 0x0300, 0x4000 };
         short[] swappedValues = { 0x0100, 0x2000, 0x0003, 0x0040 };
 
-        int scale = SizeOf.SHORT;
+        int scale = Short.BYTES;
         VMRuntime runtime = VMRuntime.getRuntime();
         byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1);
         long base_ptr = runtime.addressOf(array);
@@ -141,7 +140,7 @@
 
     private void assertShortsEqual(short[] expectedValues, long ptr, boolean swap) {
         for (int i = 0; i < expectedValues.length; ++i) {
-            assertEquals(expectedValues[i], Memory.peekShort(ptr + SizeOf.SHORT * i, swap));
+            assertEquals(expectedValues[i], Memory.peekShort(ptr + Short.BYTES * i, swap));
         }
     }
 }
diff --git a/luni/src/test/java/libcore/libcore/io/OsTest.java b/luni/src/test/java/libcore/libcore/io/OsTest.java
index 5e8a691..6359f87 100644
--- a/luni/src/test/java/libcore/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/OsTest.java
@@ -16,1002 +16,54 @@
 
 package libcore.libcore.io;
 
-import android.system.ErrnoException;
-import android.system.Int64Ref;
-import android.system.NetlinkSocketAddress;
-import android.system.OsConstants;
-import android.system.PacketSocketAddress;
-import android.system.StructRlimit;
-import android.system.StructStat;
-import android.system.StructTimeval;
-import android.system.StructUcred;
-import android.system.UnixSocketAddress;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.DatagramPacket;
-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.ServerSocket;
-import java.net.SocketOptions;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicReference;
 import junit.framework.TestCase;
 
-import libcore.io.IoBridge;
-import libcore.io.IoUtils;
-import libcore.io.Libcore;
+import libcore.io.ForwardingOs;
+import libcore.io.Os;
 
-import static android.system.OsConstants.*;
-import static libcore.libcore.io.OsTest.SendFileImpl.ANDROID_SYSTEM_OS_INT64_REF;
-import static libcore.libcore.io.OsTest.SendFileImpl.LIBCORE_OS;
+import org.mockito.Mockito;
 
 public class OsTest extends TestCase {
-  public void testIsSocket() throws Exception {
-    File f = new File("/dev/null");
-    FileInputStream fis = new FileInputStream(f);
-    assertFalse(S_ISSOCK(Libcore.os.fstat(fis.getFD()).st_mode));
-    fis.close();
 
-    ServerSocket s = new ServerSocket();
-    assertTrue(S_ISSOCK(Libcore.os.fstat(s.getImpl().getFD$()).st_mode));
-    s.close();
-  }
-
-  public void testFcntlInt() throws Exception {
-    File f = File.createTempFile("OsTest", "tst");
-    FileInputStream fis = null;
-    try {
-      fis = new FileInputStream(f);
-      Libcore.os.fcntlInt(fis.getFD(), F_SETFD, FD_CLOEXEC);
-      int flags = Libcore.os.fcntlVoid(fis.getFD(), F_GETFD);
-      assertTrue((flags & FD_CLOEXEC) != 0);
-    } finally {
-      IoUtils.closeQuietly(fis);
-      f.delete();
-    }
-  }
-
-  public void testUnixDomainSockets_in_file_system() throws Exception {
-    String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket";
-    new File(path).delete();
-    checkUnixDomainSocket(UnixSocketAddress.createFileSystem(path), false);
-  }
-
-  public void testUnixDomainSocket_abstract_name() throws Exception {
-    // Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7).
-    checkUnixDomainSocket(UnixSocketAddress.createAbstract("/abstract_name_unix_socket"), true);
-  }
-
-  public void testUnixDomainSocket_unnamed() throws Exception {
-    final FileDescriptor fd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
-    // unix(7) says an unbound socket is unnamed.
-    checkNoSockName(fd);
-    Libcore.os.close(fd);
-  }
-
-  private void checkUnixDomainSocket(final UnixSocketAddress address, final boolean isAbstract)
-      throws Exception {
-    final FileDescriptor serverFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
-    Libcore.os.bind(serverFd, address);
-    Libcore.os.listen(serverFd, 5);
-
-    checkSockName(serverFd, isAbstract, address);
-
-    Thread server = new Thread(new Runnable() {
-      public void run() {
+    public void testCompareAndSetDefault_success() throws Exception {
+        Os defaultOs = Os.getDefault();
+        Os mockOs = Mockito.mock(Os.class);
         try {
-          UnixSocketAddress peerAddress = UnixSocketAddress.createUnnamed();
-          FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress);
-          checkSockName(clientFd, isAbstract, address);
-          checkNoName(peerAddress);
+            // There shouldn't be any concurrent threads replacing the default Os.
+            assertTrue(Os.compareAndSetDefault(defaultOs, mockOs));
+            assertSame(mockOs, Os.getDefault());
 
-          checkNoPeerName(clientFd);
-
-          StructUcred credentials = Libcore.os.getsockoptUcred(clientFd, SOL_SOCKET, SO_PEERCRED);
-          assertEquals(Libcore.os.getpid(), credentials.pid);
-          assertEquals(Libcore.os.getuid(), credentials.uid);
-          assertEquals(Libcore.os.getgid(), credentials.gid);
-
-          byte[] request = new byte[256];
-          Libcore.os.read(clientFd, request, 0, request.length);
-
-          String s = new String(request, "UTF-8");
-          byte[] response = s.toUpperCase(Locale.ROOT).getBytes("UTF-8");
-          Libcore.os.write(clientFd, response, 0, response.length);
-
-          Libcore.os.close(clientFd);
-        } catch (Exception ex) {
-          throw new RuntimeException(ex);
+            // Calls to android.system.Os should now reach our custom Os instance.
+            android.system.Os.rename("/old/path", "/new/path");
+            Mockito.verify(mockOs).rename("/old/path", "/new/path");
+        } finally {
+            assertTrue(Os.compareAndSetDefault(mockOs, defaultOs));
+            assertSame(defaultOs, Os.getDefault());
         }
-      }
-    });
-    server.start();
-
-    FileDescriptor clientFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
-
-    Libcore.os.connect(clientFd, address);
-    checkNoSockName(clientFd);
-
-    String string = "hello, world!";
-
-    byte[] request = string.getBytes("UTF-8");
-    assertEquals(request.length, Libcore.os.write(clientFd, request, 0, request.length));
-
-    byte[] response = new byte[request.length];
-    assertEquals(response.length, Libcore.os.read(clientFd, response, 0, response.length));
-
-    assertEquals(string.toUpperCase(Locale.ROOT), new String(response, "UTF-8"));
-
-    Libcore.os.close(clientFd);
-  }
-
-  private static void checkSockName(FileDescriptor fd, boolean isAbstract,
-      UnixSocketAddress address) throws Exception {
-    UnixSocketAddress isa = (UnixSocketAddress) Libcore.os.getsockname(fd);
-    assertEquals(address, isa);
-    if (isAbstract) {
-      assertEquals(0, isa.getSunPath()[0]);
     }
-  }
 
-  private void checkNoName(UnixSocketAddress usa) {
-    assertEquals(0, usa.getSunPath().length);
-  }
-
-  private void checkNoPeerName(FileDescriptor fd) throws Exception {
-    checkNoName((UnixSocketAddress) Libcore.os.getpeername(fd));
-  }
-
-  private void checkNoSockName(FileDescriptor fd) throws Exception {
-    checkNoName((UnixSocketAddress) Libcore.os.getsockname(fd));
-  }
-
-  public void test_strsignal() throws Exception {
-    assertEquals("Killed", Libcore.os.strsignal(9));
-    assertEquals("Unknown signal -1", Libcore.os.strsignal(-1));
-  }
-
-  public void test_byteBufferPositions_write_pwrite() throws Exception {
-    FileOutputStream fos = new FileOutputStream(new File("/dev/null"));
-    FileDescriptor fd = fos.getFD();
-    final byte[] contents = new String("goodbye, cruel world").getBytes(StandardCharsets.US_ASCII);
-    ByteBuffer byteBuffer = ByteBuffer.wrap(contents);
-
-    byteBuffer.position(0);
-    int written = Libcore.os.write(fd, byteBuffer);
-    assertTrue(written > 0);
-    assertEquals(written, byteBuffer.position());
-
-    byteBuffer.position(4);
-    written = Libcore.os.write(fd, byteBuffer);
-    assertTrue(written > 0);
-    assertEquals(written + 4, byteBuffer.position());
-
-    byteBuffer.position(0);
-    written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */);
-    assertTrue(written > 0);
-    assertEquals(written, byteBuffer.position());
-
-    byteBuffer.position(4);
-    written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */);
-    assertTrue(written > 0);
-    assertEquals(written + 4, byteBuffer.position());
-
-    fos.close();
-  }
-
-  public void test_byteBufferPositions_read_pread() throws Exception {
-    FileInputStream fis = new FileInputStream(new File("/dev/zero"));
-    FileDescriptor fd = fis.getFD();
-    ByteBuffer byteBuffer = ByteBuffer.allocate(64);
-
-    byteBuffer.position(0);
-    int read = Libcore.os.read(fd, byteBuffer);
-    assertTrue(read > 0);
-    assertEquals(read, byteBuffer.position());
-
-    byteBuffer.position(4);
-    read = Libcore.os.read(fd, byteBuffer);
-    assertTrue(read > 0);
-    assertEquals(read + 4, byteBuffer.position());
-
-    byteBuffer.position(0);
-    read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */);
-    assertTrue(read > 0);
-    assertEquals(read, byteBuffer.position());
-
-    byteBuffer.position(4);
-    read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */);
-    assertTrue(read > 0);
-    assertEquals(read + 4, byteBuffer.position());
-
-    fis.close();
-  }
-
-  static void checkByteBufferPositions_sendto_recvfrom(
-      int family, InetAddress loopback) throws Exception {
-    final FileDescriptor serverFd = Libcore.os.socket(family, SOCK_STREAM, 0);
-    Libcore.os.bind(serverFd, loopback, 0);
-    Libcore.os.listen(serverFd, 5);
-
-    InetSocketAddress address = (InetSocketAddress) Libcore.os.getsockname(serverFd);
-
-    final Thread server = new Thread(new Runnable() {
-      public void run() {
+    public void testCompareandSetDefault_null() {
+        Os defaultOs = Os.getDefault();
+        // update == null is not allowed
         try {
-          InetSocketAddress peerAddress = new InetSocketAddress();
-          FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress);
-
-          // Attempt to receive a maximum of 24 bytes from the client, and then
-          // close the connection.
-          ByteBuffer buffer = ByteBuffer.allocate(16);
-          int received = Libcore.os.recvfrom(clientFd, buffer, 0, null);
-          assertTrue(received > 0);
-          assertEquals(received, buffer.position());
-
-          ByteBuffer buffer2 = ByteBuffer.allocate(16);
-          buffer2.position(8);
-          received = Libcore.os.recvfrom(clientFd, buffer2, 0, null);
-          assertTrue(received > 0);
-          assertEquals(received + 8, buffer.position());
-
-          Libcore.os.close(clientFd);
-        } catch (Exception ex) {
-          throw new RuntimeException(ex);
-        }
-      }
-    });
-
-    server.start();
-
-    FileDescriptor clientFd = Libcore.os.socket(family, SOCK_STREAM, 0);
-    Libcore.os.connect(clientFd, address.getAddress(), address.getPort());
-
-    final byte[] bytes = "good bye, cruel black hole with fancy distortion"
-        .getBytes(StandardCharsets.US_ASCII);
-    assertTrue(bytes.length > 24);
-
-    ByteBuffer input = ByteBuffer.wrap(bytes);
-    input.position(0);
-    input.limit(16);
-
-    int sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
-    assertTrue(sent > 0);
-    assertEquals(sent, input.position());
-
-    input.position(16);
-    input.limit(24);
-    sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
-    assertTrue(sent > 0);
-    assertEquals(sent + 16, input.position());
-
-    Libcore.os.close(clientFd);
-  }
-
-  public void test_NetlinkSocket() throws Exception {
-    FileDescriptor nlSocket = Libcore.os.socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
-    Libcore.os.bind(nlSocket, new NetlinkSocketAddress());
-    NetlinkSocketAddress address = (NetlinkSocketAddress) Libcore.os.getsockname(nlSocket);
-    assertTrue(address.getPortId() > 0);
-    assertEquals(0, address.getGroupsMask());
-
-    NetlinkSocketAddress nlKernel = new NetlinkSocketAddress();
-    Libcore.os.connect(nlSocket, nlKernel);
-    NetlinkSocketAddress nlPeer = (NetlinkSocketAddress) Libcore.os.getpeername(nlSocket);
-    assertEquals(0, nlPeer.getPortId());
-    assertEquals(0, nlPeer.getGroupsMask());
-    Libcore.os.close(nlSocket);
-  }
-
-  public void test_PacketSocketAddress() throws Exception {
-    NetworkInterface lo = NetworkInterface.getByName("lo");
-    FileDescriptor fd = Libcore.os.socket(AF_PACKET, SOCK_DGRAM, ETH_P_IPV6);
-    PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6, lo.getIndex());
-    Libcore.os.bind(fd, addr);
-
-    PacketSocketAddress bound = (PacketSocketAddress) Libcore.os.getsockname(fd);
-    assertEquals((short) ETH_P_IPV6, bound.sll_protocol);  // ETH_P_IPV6 is an int.
-    assertEquals(lo.getIndex(), bound.sll_ifindex);
-    assertEquals(ARPHRD_LOOPBACK, bound.sll_hatype);
-    assertEquals(0, bound.sll_pkttype);
-
-    // The loopback address is ETH_ALEN bytes long and is all zeros.
-    // http://lxr.free-electrons.com/source/drivers/net/loopback.c?v=3.10#L167
-    assertEquals(6, bound.sll_addr.length);
-    for (int i = 0; i < 6; i++) {
-      assertEquals(0, bound.sll_addr[i]);
-    }
-  }
-
-  public void test_byteBufferPositions_sendto_recvfrom_af_inet() throws Exception {
-    checkByteBufferPositions_sendto_recvfrom(AF_INET, InetAddress.getByName("127.0.0.1"));
-  }
-
-  public void test_byteBufferPositions_sendto_recvfrom_af_inet6() throws Exception {
-    checkByteBufferPositions_sendto_recvfrom(AF_INET6, InetAddress.getByName("::1"));
-  }
-
-  private void checkSendToSocketAddress(int family, InetAddress loopback) throws Exception {
-    FileDescriptor recvFd = Libcore.os.socket(family, SOCK_DGRAM, 0);
-    Libcore.os.bind(recvFd, loopback, 0);
-    StructTimeval tv = StructTimeval.fromMillis(20);
-    Libcore.os.setsockoptTimeval(recvFd, SOL_SOCKET, SO_RCVTIMEO, tv);
-
-    InetSocketAddress to = ((InetSocketAddress) Libcore.os.getsockname(recvFd));
-    FileDescriptor sendFd = Libcore.os.socket(family, SOCK_DGRAM, 0);
-    byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes("UTF-8");
-    int len = msg.length;
-
-    assertEquals(len, Libcore.os.sendto(sendFd, msg, 0, len, 0, to));
-    byte[] received = new byte[msg.length + 42];
-    InetSocketAddress from = new InetSocketAddress();
-    assertEquals(len, Libcore.os.recvfrom(recvFd, received, 0, received.length, 0, from));
-    assertEquals(loopback, from.getAddress());
-  }
-
-  public void test_sendtoSocketAddress_af_inet() throws Exception {
-    checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
-  }
-
-  public void test_sendtoSocketAddress_af_inet6() throws Exception {
-    checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
-  }
-
-  public void test_socketFamilies() throws Exception {
-    FileDescriptor fd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0);
-    Libcore.os.bind(fd, InetAddress.getByName("::"), 0);
-    InetSocketAddress localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
-    assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
-
-    fd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0);
-    Libcore.os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
-    localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
-    assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
-
-    fd = Libcore.os.socket(AF_INET, SOCK_STREAM, 0);
-    Libcore.os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
-    localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
-    assertEquals(Inet4Address.ANY, localSocketAddress.getAddress());
-    try {
-      Libcore.os.bind(fd, InetAddress.getByName("::"), 0);
-      fail("Expected ErrnoException binding IPv4 socket to ::");
-    } catch (ErrnoException expected) {
-      assertEquals("Expected EAFNOSUPPORT binding IPv4 socket to ::", EAFNOSUPPORT, expected.errno);
-    }
-  }
-
-  private static void assertArrayEquals(byte[] expected, byte[] actual) {
-    assertTrue("Expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual),
-        Arrays.equals(expected, actual));
-  }
-
-  private static void checkSocketPing(FileDescriptor fd, InetAddress to, byte[] packet,
-      byte type, byte responseType, boolean useSendto) throws Exception {
-    int len = packet.length;
-    packet[0] = type;
-    if (useSendto) {
-      assertEquals(len, Libcore.os.sendto(fd, packet, 0, len, 0, to, 0));
-    } else {
-      Libcore.os.connect(fd, to, 0);
-      assertEquals(len, Libcore.os.sendto(fd, packet, 0, len, 0, null, 0));
-    }
-
-    int icmpId = ((InetSocketAddress) Libcore.os.getsockname(fd)).getPort();
-    byte[] received = new byte[4096];
-    InetSocketAddress srcAddress = new InetSocketAddress();
-    assertEquals(len, Libcore.os.recvfrom(fd, received, 0, received.length, 0, srcAddress));
-    assertEquals(to, srcAddress.getAddress());
-    assertEquals(responseType, received[0]);
-    assertEquals(received[4], (byte) (icmpId >> 8));
-    assertEquals(received[5], (byte) (icmpId & 0xff));
-
-    received = Arrays.copyOf(received, len);
-    received[0] = (byte) type;
-    received[2] = received[3] = 0;  // Checksum.
-    received[4] = received[5] = 0;  // ICMP ID.
-    assertArrayEquals(packet, received);
-  }
-
-  public void test_socketPing() throws Exception {
-    final byte ICMP_ECHO = 8, ICMP_ECHOREPLY = 0;
-    final byte ICMPV6_ECHO_REQUEST = (byte) 128, ICMPV6_ECHO_REPLY = (byte) 129;
-    final byte[] packet = ("\000\000\000\000" +  // ICMP type, code.
-        "\000\000\000\003" +  // ICMP ID (== port), sequence number.
-        "Hello myself").getBytes(StandardCharsets.US_ASCII);
-
-    FileDescriptor fd = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
-    InetAddress ipv6Loopback = InetAddress.getByName("::1");
-    checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, true);
-    checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, false);
-
-    fd = Libcore.os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
-    InetAddress ipv4Loopback = InetAddress.getByName("127.0.0.1");
-    checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, true);
-    checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
-  }
-
-  public void test_Ipv4Fallback() throws Exception {
-    // This number of iterations gives a ~60% chance of creating the conditions that caused
-    // http://b/23088314 without making test times too long. On a hammerhead running MRZ37C using
-    // vogar, this test takes about 4s.
-    final int ITERATIONS = 10000;
-    for (int i = 0; i < ITERATIONS; i++) {
-      FileDescriptor mUdpSock = Libcore.os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-      try {
-          Libcore.os.bind(mUdpSock, Inet4Address.ANY, 0);
-      } catch(ErrnoException e) {
-          fail("ErrnoException after " + i + " iterations: " + e);
-      } finally {
-          Libcore.os.close(mUdpSock);
-      }
-    }
-  }
-
-  public void test_unlink() throws Exception {
-    File f = File.createTempFile("OsTest", "tst");
-    assertTrue(f.exists());
-    Libcore.os.unlink(f.getAbsolutePath());
-    assertFalse(f.exists());
-
-    try {
-      Libcore.os.unlink(f.getAbsolutePath());
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(OsConstants.ENOENT, e.errno);
-    }
-  }
-
-  // b/27294715
-  public void test_recvfrom_concurrentShutdown() throws Exception {
-      final FileDescriptor serverFd = Libcore.os.socket(AF_INET, SOCK_DGRAM, 0);
-      Libcore.os.bind(serverFd, InetAddress.getByName("127.0.0.1"), 0);
-      // Set 4s timeout
-      IoBridge.setSocketOption(serverFd, SocketOptions.SO_TIMEOUT, new Integer(4000));
-
-      final AtomicReference<Exception> killerThreadException = new AtomicReference<Exception>(null);
-      final Thread killer = new Thread(new Runnable() {
-          public void run() {
-              try {
-                  Thread.sleep(2000);
-                  try {
-                      Libcore.os.shutdown(serverFd, SHUT_RDWR);
-                  } catch (ErrnoException expected) {
-                      if (OsConstants.ENOTCONN != expected.errno) {
-                          killerThreadException.set(expected);
-                      }
-                  }
-              } catch (Exception ex) {
-                  killerThreadException.set(ex);
-              }
-          }
-      });
-      killer.start();
-
-      ByteBuffer buffer = ByteBuffer.allocate(16);
-      InetSocketAddress srcAddress = new InetSocketAddress();
-      int received = Libcore.os.recvfrom(serverFd, buffer, 0, srcAddress);
-      assertTrue(received == 0);
-      Libcore.os.close(serverFd);
-
-      killer.join();
-      assertNull(killerThreadException.get());
-  }
-
-  public void test_xattr() throws Exception {
-    final String NAME_TEST = "user.meow";
-
-    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
-    final byte[] VALUE_PIE = "pie".getBytes(StandardCharsets.UTF_8);
-
-    File file = File.createTempFile("xattr", "test");
-    String path = file.getAbsolutePath();
-
-    try {
-      try {
-        Libcore.os.getxattr(path, NAME_TEST);
-        fail("Expected ENODATA");
-      } catch (ErrnoException e) {
-        assertEquals(OsConstants.ENODATA, e.errno);
-      }
-      assertFalse(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
-
-      Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
-      byte[] xattr_create = Libcore.os.getxattr(path, NAME_TEST);
-      assertTrue(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
-      assertEquals(VALUE_CAKE.length, xattr_create.length);
-      assertStartsWith(VALUE_CAKE, xattr_create);
-
-      try {
-        Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_CREATE);
-        fail("Expected EEXIST");
-      } catch (ErrnoException e) {
-        assertEquals(OsConstants.EEXIST, e.errno);
-      }
-
-      Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_REPLACE);
-      byte[] xattr_replace = Libcore.os.getxattr(path, NAME_TEST);
-      assertTrue(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
-      assertEquals(VALUE_PIE.length, xattr_replace.length);
-      assertStartsWith(VALUE_PIE, xattr_replace);
-
-      Libcore.os.removexattr(path, NAME_TEST);
-      try {
-        Libcore.os.getxattr(path, NAME_TEST);
-        fail("Expected ENODATA");
-      } catch (ErrnoException e) {
-        assertEquals(OsConstants.ENODATA, e.errno);
-      }
-      assertFalse(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
-
-    } finally {
-      file.delete();
-    }
-  }
-
-  public void test_xattr_NPE() throws Exception {
-    File file = File.createTempFile("xattr", "test");
-    final String path = file.getAbsolutePath();
-    final String NAME_TEST = "user.meow";
-    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
-
-    // getxattr
-    try {
-      Libcore.os.getxattr(null, NAME_TEST);
-      fail();
-    } catch (NullPointerException expected) { }
-    try {
-      Libcore.os.getxattr(path, null);
-      fail();
-    } catch (NullPointerException expected) { }
-
-    // listxattr
-    try {
-      Libcore.os.listxattr(null);
-      fail();
-    } catch (NullPointerException expected) { }
-
-    // removexattr
-    try {
-      Libcore.os.removexattr(null, NAME_TEST);
-      fail();
-    } catch (NullPointerException expected) { }
-    try {
-      Libcore.os.removexattr(path, null);
-      fail();
-    } catch (NullPointerException expected) { }
-
-    // setxattr
-    try {
-      Libcore.os.setxattr(null, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
-      fail();
-    } catch (NullPointerException expected) { }
-    try {
-      Libcore.os.setxattr(path, null, VALUE_CAKE, OsConstants.XATTR_CREATE);
-      fail();
-    } catch (NullPointerException expected) { }
-    try {
-      Libcore.os.setxattr(path, NAME_TEST, null, OsConstants.XATTR_CREATE);
-      fail();
-    } catch (NullPointerException expected) { }
-  }
-
-  public void test_xattr_Errno() throws Exception {
-    final String NAME_TEST = "user.meow";
-    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
-
-    // ENOENT, No such file or directory.
-    try {
-      Libcore.os.getxattr("", NAME_TEST);
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(ENOENT, e.errno);
-    }
-    try {
-      Libcore.os.listxattr("");
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(ENOENT, e.errno);
-    }
-    try {
-      Libcore.os.removexattr("", NAME_TEST);
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(ENOENT, e.errno);
-    }
-    try {
-      Libcore.os.setxattr("", NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(ENOENT, e.errno);
-    }
-
-    // ENOTSUP, Extended attributes are not supported by the filesystem, or are disabled.
-    // Since kernel version 4.9 (or some other version after 4.4), *xattr() methods
-    // may set errno to EACCESS instead. This behavior change is likely related to
-    // https://patchwork.kernel.org/patch/9294421/ which reimplemented getxattr, setxattr,
-    // and removexattr on top of generic handlers.
-    final String path = "/proc/self/stat";
-    try {
-      Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
-      fail();
-    } catch (ErrnoException e) {
-      assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
-    }
-    try {
-      Libcore.os.getxattr(path, NAME_TEST);
-      fail();
-    } catch (ErrnoException e) {
-      assertEquals(ENOTSUP, e.errno);
-    }
-    try {
-      // Linux listxattr does not set errno.
-      Libcore.os.listxattr(path);
-    } catch (ErrnoException e) {
-      fail();
-    }
-    try {
-      Libcore.os.removexattr(path, NAME_TEST);
-      fail();
-    } catch (ErrnoException e) {
-      assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
-    }
-  }
-
-  public void test_realpath() throws Exception {
-      File tmpDir = new File(System.getProperty("java.io.tmpdir"));
-      // This is a chicken and egg problem. We have no way of knowing whether
-      // the temporary directory or one of its path elements were symlinked, so
-      // we'll need this call to realpath.
-      String canonicalTmpDir = Libcore.os.realpath(tmpDir.getAbsolutePath());
-
-      // Test that "." and ".." are resolved correctly.
-      assertEquals(canonicalTmpDir,
-          Libcore.os.realpath(canonicalTmpDir + "/./../" + tmpDir.getName()));
-
-      // Test that symlinks are resolved correctly.
-      File target = new File(tmpDir, "target");
-      File link = new File(tmpDir, "link");
-      try {
-          assertTrue(target.createNewFile());
-          Libcore.os.symlink(target.getAbsolutePath(), link.getAbsolutePath());
-
-          assertEquals(canonicalTmpDir + "/target",
-              Libcore.os.realpath(canonicalTmpDir + "/link"));
-      } finally {
-          boolean deletedTarget = target.delete();
-          boolean deletedLink = link.delete();
-          // Asserting this here to provide a definitive reason for
-          // a subsequent failure on the same run.
-          assertTrue("deletedTarget = " + deletedTarget + ", deletedLink =" + deletedLink,
-              deletedTarget && deletedLink);
-      }
-  }
-
-  /**
-   * Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
-   * that it behaves as expected.
-   */
-  public void test_socket_tcpUserTimeout_setAndGet() throws Exception {
-    final FileDescriptor fd = Libcore.os.socket(AF_INET, SOCK_STREAM, 0);
-    try {
-      int v = Libcore.os.getsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT);
-      assertEquals(0, v); // system default value
-      int newValue = 3000;
-      Libcore.os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
-              newValue);
-      int actualValue = Libcore.os.getsockoptInt(fd, OsConstants.IPPROTO_TCP,
-              OsConstants.TCP_USER_TIMEOUT);
-      // The kernel can round the requested value based on the HZ setting. We allow up to 10ms
-      // difference.
-      assertTrue("Returned incorrect timeout:" + actualValue,
-              Math.abs(newValue - actualValue) <= 10);
-      // No need to reset the value to 0, since we're throwing the socket away
-    } finally {
-      Libcore.os.close(fd);
-    }
-  }
-
-  public void test_socket_tcpUserTimeout_doesNotWorkOnDatagramSocket() throws Exception {
-    final FileDescriptor fd = Libcore.os.socket(AF_INET, SOCK_DGRAM, 0);
-    try {
-      Libcore.os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
-              3000);
-      fail("datagram (connectionless) sockets shouldn't support TCP_USER_TIMEOUT");
-    } catch (ErrnoException expected) {
-      // expected
-    } finally {
-      Libcore.os.close(fd);
-    }
-  }
-
-  public void test_if_nametoindex_if_indextoname() throws Exception {
-    List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
-
-    assertTrue(nis.size() > 0);
-    for (NetworkInterface ni : nis) {
-      int index = ni.getIndex();
-      String name = ni.getName();
-      assertEquals(index, Libcore.os.if_nametoindex(name));
-      assertTrue(Libcore.os.if_indextoname(index).equals(name));
-    }
-
-    assertEquals(0, Libcore.os.if_nametoindex("this-interface-does-not-exist"));
-    assertEquals(null, Libcore.os.if_indextoname(-1000));
-
-    try {
-      Libcore.os.if_nametoindex(null);
-      fail();
-    } catch (NullPointerException expected) { }
-  }
-
-  private static void assertStartsWith(byte[] expectedContents, byte[] container) {
-    for (int i = 0; i < expectedContents.length; i++) {
-      if (expectedContents[i] != container[i]) {
-        fail("Expected " + Arrays.toString(expectedContents) + " but found "
-            + Arrays.toString(expectedContents));
-      }
-    }
-  }
-
-  public void test_readlink() throws Exception {
-    File path = new File(IoUtils.createTemporaryDirectory("test_readlink"), "symlink");
-
-    // ext2 and ext4 have PAGE_SIZE limits on symlink targets.
-    // If file encryption is enabled, there's extra overhead to store the
-    // size of the encrypted symlink target. There's also an off-by-one
-    // in current kernels (and marlin/sailfish where we're seeing this
-    // failure are still on 3.18, far from current). Given that we don't
-    // really care here, just use 2048 instead. http://b/33306057.
-    int size = 2048;
-    String xs = "";
-    for (int i = 0; i < size - 1; ++i) xs += "x";
-
-    Libcore.os.symlink(xs, path.getPath());
-
-    assertEquals(xs, Libcore.os.readlink(path.getPath()));
-  }
-
-  // Address should be correctly set for empty packets. http://b/33481605
-  public void test_recvfrom_EmptyPacket() throws Exception {
-    try (DatagramSocket ds = new DatagramSocket();
-         DatagramSocket srcSock = new DatagramSocket()) {
-      srcSock.send(new DatagramPacket(new byte[0], 0, ds.getLocalSocketAddress()));
-
-      byte[] recvBuf = new byte[16];
-      InetSocketAddress address = new InetSocketAddress();
-      int recvCount =
-          android.system.Os.recvfrom(ds.getFileDescriptor$(), recvBuf, 0, 16, 0, address);
-      assertEquals(0, recvCount);
-      assertTrue(address.getAddress().isLoopbackAddress());
-      assertEquals(srcSock.getLocalPort(), address.getPort());
-    }
-  }
-
-  public void test_fstat_times() throws Exception {
-    File file = File.createTempFile("OsTest", "fstattest");
-    FileOutputStream fos = new FileOutputStream(file);
-    StructStat structStat1 = Libcore.os.fstat(fos.getFD());
-    assertEquals(structStat1.st_mtim.tv_sec, structStat1.st_mtime);
-    assertEquals(structStat1.st_ctim.tv_sec, structStat1.st_ctime);
-    assertEquals(structStat1.st_atim.tv_sec, structStat1.st_atime);
-    Thread.sleep(100);
-    fos.write(new byte[]{1,2,3});
-    fos.flush();
-    StructStat structStat2 = Libcore.os.fstat(fos.getFD());
-    fos.close();
-
-    assertEquals(-1, structStat1.st_mtim.compareTo(structStat2.st_mtim));
-    assertEquals(-1, structStat1.st_ctim.compareTo(structStat2.st_ctim));
-    assertEquals(0, structStat1.st_atim.compareTo(structStat2.st_atim));
-  }
-
-  public void test_getrlimit() throws Exception {
-    StructRlimit rlimit = Libcore.os.getrlimit(OsConstants.RLIMIT_NOFILE);
-    // We can't really make any assertions about these values since they might vary from
-    // device to device and even process to process. We do know that they will be greater
-    // than zero, though.
-    assertTrue(rlimit.rlim_cur > 0);
-    assertTrue(rlimit.rlim_max > 0);
-  }
-
-  // http://b/65051835
-  public void test_pipe2_errno() throws Exception {
-    try {
-        // flag=-1 is not a valid value for pip2, will EINVAL
-        Libcore.os.pipe2(-1);
-        fail();
-    } catch(ErrnoException expected) {
-    }
-  }
-
-  // http://b/65051835
-  public void test_sendfile_errno() throws Exception {
-    try {
-        // FileDescriptor.out is not open for input, will cause EBADF
-        Int64Ref offset = new Int64Ref(10);
-        Libcore.os.sendfile(FileDescriptor.out, FileDescriptor.out, offset, 10);
-        fail();
-    } catch(ErrnoException expected) {
-    }
-  }
-
-  public void test_sendfile_null() throws Exception {
-    File in = createTempFile("test_sendfile_null", "Hello, world!");
-    try {
-      int len = "Hello".length();
-      assertEquals("Hello", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, null, len, null));
-      assertEquals("Hello", checkSendfile(LIBCORE_OS, in, null, len, null));
-    } finally {
-      in.delete();
-    }
-  }
-
-  public void test_sendfile_offset() throws Exception {
-    File in = createTempFile("test_sendfile_offset", "Hello, world!");
-    try {
-      // checkSendfile(sendFileImplToUse, in, startOffset, maxBytes, expectedEndOffset)
-
-      assertEquals("Hello", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 0L, 5, 5L));
-      assertEquals("Hello", checkSendfile(LIBCORE_OS, in, 0L, 5, 5L));
-
-      assertEquals("ello,", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 1L, 5, 6L));
-      assertEquals("ello,", checkSendfile(LIBCORE_OS, in, 1L, 5, 6L));
-
-      // At offset 9, only 4 bytes/chars available, even though we're asking for 5.
-      assertEquals("rld!", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 9L, 5, 13L));
-      assertEquals("rld!", checkSendfile(LIBCORE_OS, in, 9L, 5, 13L));
-
-      assertEquals("", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 1L, 0, 1L));
-      assertEquals("", checkSendfile(LIBCORE_OS, in, 1L, 0, 1L));
-    } finally {
-      in.delete();
-    }
-  }
-
-  /** Which of the {@code sendfile()} implementations to use. */
-  enum SendFileImpl {
-    ANDROID_SYSTEM_OS_INT64_REF,
-    LIBCORE_OS
-  }
-
-  private static String checkSendfile(SendFileImpl sendFileImplToUse, File in, Long startOffset,
-          int maxBytes, Long expectedEndOffset) throws IOException, ErrnoException {
-    File out = File.createTempFile(OsTest.class.getSimpleName() + "_checkSendFile_" +
-            sendFileImplToUse, ".out");
-    try (FileInputStream inStream = new FileInputStream(in)) {
-      FileDescriptor inFd = inStream.getFD();
-      try (FileOutputStream outStream = new FileOutputStream(out)) {
-        FileDescriptor outFd = outStream.getFD();
-        switch (sendFileImplToUse) {
-          case ANDROID_SYSTEM_OS_INT64_REF: {
-            Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
-            android.system.Os.sendfile(outFd, inFd, offset, maxBytes);
-            assertEquals(expectedEndOffset, offset == null ? null : offset.value);
-            break;
-          }
-          case LIBCORE_OS: {
-            Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
-            libcore.io.Libcore.os.sendfile(outFd, inFd, offset, maxBytes);
-            assertEquals(expectedEndOffset, offset == null ? null : offset.value);
-            break;
-          }
-          default: {
+            Os.compareAndSetDefault(defaultOs, null);
             fail();
-            break;
-          }
+        } catch (NullPointerException expected) {
         }
-      }
-      return IoUtils.readFileAsString(out.getPath());
-    } finally {
-      out.delete();
-    }
-  }
-
-  private static File createTempFile(String namePart, String contents) throws IOException {
-    File f = File.createTempFile(OsTest.class.getSimpleName() + namePart, ".in");
-    try (FileWriter writer = new FileWriter(f)) {
-      writer.write(contents);
-    }
-    return f;
-  }
-
-  public void test_odirect() throws Exception {
-    File testFile = createTempFile("test_odirect", "");
-    try {
-      FileDescriptor fd =
-            Libcore.os.open(testFile.toString(), O_WRONLY | O_DIRECT, S_IRUSR | S_IWUSR);
-      assertNotNull(fd);
-      assertTrue(fd.valid());
-      int flags = Libcore.os.fcntlVoid(fd, F_GETFL);
-      assertTrue("Expected file flags to include " + O_DIRECT + ", actual value: " + flags,
-            0 != (flags & O_DIRECT));
-      Libcore.os.close(fd);
-    } finally {
-      testFile.delete();
-    }
-  }
-
-  public void test_splice() throws Exception {
-    FileDescriptor[] pipe = Libcore.os.pipe2(0);
-    File in = createTempFile("splice1", "foobar");
-    File out = createTempFile("splice2", "");
-
-    Int64Ref offIn = new Int64Ref(1);
-    Int64Ref offOut = new Int64Ref(0);
-
-    // Splice into pipe
-    try (FileInputStream streamIn = new FileInputStream(in)) {
-      FileDescriptor fdIn = streamIn.getFD();
-      long result = Libcore.os.splice(fdIn, offIn, pipe[1], null /* offOut */ , 10 /* len */, 0 /* flags */);
-      assertEquals(5, result);
-      assertEquals(6, offIn.value);
+        // value hasn't changed
+        assertSame(defaultOs, Os.getDefault());
     }
 
-    // Splice from pipe
-    try (FileOutputStream streamOut = new FileOutputStream(out)) {
-      FileDescriptor fdOut = streamOut.getFD();
-      long result = Libcore.os.splice(pipe[0], null /* offIn */, fdOut, offOut, 10 /* len */, 0 /* flags */);
-      assertEquals(5, result);
-      assertEquals(5, offOut.value);
+    public void testCompareAndSetDefault_comparisonFailure() throws Exception {
+        Os defaultOs = Os.getDefault();
+        Os otherOs = new ForwardingOs(defaultOs) { };
+
+        // current default is non-null, but expect is null
+        assertFalse(Os.compareAndSetDefault(null, otherOs));
+        assertSame(defaultOs, Os.getDefault());
+
+        // current default != expect (both non-null)
+        assertFalse(Os.compareAndSetDefault(otherOs, otherOs));
+        assertSame(defaultOs, Os.getDefault());
     }
-
-    assertEquals("oobar", IoUtils.readFileAsString(out.getPath()));
-
-    Libcore.os.close(pipe[0]);
-    Libcore.os.close(pipe[1]);
-  }
-
-  public void test_splice_errors() throws Exception {
-    File in = createTempFile("splice3", "");
-    File out = createTempFile("splice4", "");
-    FileDescriptor[] pipe = Libcore.os.pipe2(0);
-
-    //.fdIn == null
-    try {
-      Libcore.os.splice(null /* fdIn */, null /* offIn */, pipe[1],
-          null /*offOut*/, 10 /* len */, 0 /* flags */);
-      fail();
-    } catch(ErrnoException expected) {
-      assertEquals(EBADF, expected.errno);
-    }
-
-    //.fdOut == null
-    try {
-      Libcore.os.splice(pipe[0] /* fdIn */, null /* offIn */, null  /* fdOut */,
-          null /*offOut*/, 10 /* len */, 0 /* flags */);
-      fail();
-    } catch(ErrnoException expected) {
-      assertEquals(EBADF, expected.errno);
-    }
-
-    // No pipe fd
-    try (FileOutputStream streamOut = new FileOutputStream(out)) {
-      try (FileInputStream streamIn = new FileInputStream(in)) {
-        FileDescriptor fdIn = streamIn.getFD();
-        FileDescriptor fdOut = streamOut.getFD();
-        Libcore.os.splice(fdIn, null  /* offIn */, fdOut, null /* offOut */, 10 /* len */, 0 /* flags */);
-        fail();
-      } catch(ErrnoException expected) {
-        assertEquals(EINVAL, expected.errno);
-      }
-    }
-
-    Libcore.os.close(pipe[0]);
-    Libcore.os.close(pipe[1]);
-  }
 }
diff --git a/luni/src/test/java/libcore/libcore/net/InetAddressUtilsTest.java b/luni/src/test/java/libcore/libcore/net/InetAddressUtilsTest.java
new file mode 100644
index 0000000..9e3c35f
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/net/InetAddressUtilsTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.net;
+
+import java.net.InetAddress;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import libcore.net.InetAddressUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnitParamsRunner.class)
+public class InetAddressUtilsTest {
+
+    public static String[][] validNumericAddressesAndStringRepresentation() {
+        return new String[][] {
+                // Regular IPv4.
+                { "1.2.3.4", "1.2.3.4" },
+
+                // Regular IPv6.
+                { "2001:4860:800d::68", "2001:4860:800d::68" },
+                { "1234:5678::9ABC:DEF0", "1234:5678::9abc:def0" },
+                { "2001:cdba:9abc:5678::", "2001:cdba:9abc:5678::" },
+                { "::2001:cdba:9abc:5678", "::2001:cdba:9abc:5678" },
+                { "64:ff9b::1.2.3.4", "64:ff9b::102:304" },
+
+                { "::9abc:5678", "::154.188.86.120" },
+
+                // Mapped IPv4
+                { "::ffff:127.0.0.1", "127.0.0.1" },
+
+                // Android does not recognize Octal (leading 0) cases: they are treated as decimal.
+                { "0177.00.00.01", "177.0.0.1" },
+
+                // Verify that examples from JavaDoc work correctly.
+                { "192.0.2.1", "192.0.2.1" },
+                { "2001:db8::1:2", "2001:db8::1:2" },
+        };
+    }
+
+    public static String[] invalidNumericAddresses() {
+        return new String[] {
+                "",
+                " ",
+                "\t",
+                "\n",
+                "1.2.3.4.",
+                "1.2.3",
+                "1.2",
+                "1",
+                "1234",
+                "0",
+                "0x1.0x2.0x3.0x4",
+                "0x7f.0x00.0x00.0x01",
+                "0256.00.00.01",
+                "fred",
+                "www.google.com",
+                // IPv6 encoded for use in URL as defined in RFC 2732
+                "[fe80::6:2222]",
+        };
+    }
+
+    @Parameters(method = "validNumericAddressesAndStringRepresentation")
+    @Test
+    public void parseNumericAddress(String address, String expectedString) {
+        InetAddress inetAddress = InetAddressUtils.parseNumericAddress(address);
+        assertEquals(expectedString, inetAddress.getHostAddress());
+    }
+
+    @Parameters(method = "invalidNumericAddresses")
+    @Test
+    public void test_parseNonNumericAddress(String address) {
+        try {
+            InetAddress inetAddress = InetAddressUtils.parseNumericAddress(address);
+            fail(String.format(
+                    "Address %s is not numeric but was parsed as %s", address, inetAddress));
+        } catch (IllegalArgumentException e) {
+            assertThat(e.getMessage()).contains(address);
+        }
+    }
+
+    @Test
+    public void test_parseNumericAddress_null() {
+        try {
+            InetAddress inetAddress = InetAddressUtils.parseNumericAddress(null);
+            fail(String.format("null is not numeric but was parsed as %s", inetAddress));
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Parameters(method = "validNumericAddressesAndStringRepresentation")
+    @Test
+    public void test_isNumericAddress(String address, String unused) {
+        assertTrue("expected '" + address + "' to be treated as numeric",
+                InetAddressUtils.isNumericAddress(address));
+    }
+
+    @Parameters(method = "invalidNumericAddresses")
+    @Test
+    public void test_isNotNumericAddress(String address) {
+        assertFalse("expected '" + address + "' to be treated as non-numeric",
+                InetAddressUtils.isNumericAddress(address));
+    }
+
+    @Test
+    public void test_isNumericAddress_null() {
+        try {
+            InetAddressUtils.isNumericAddress(null);
+            fail("expected null to throw a NullPointerException");
+        } catch (NullPointerException e) {
+            // 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..7d7617b 100644
--- a/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
+++ b/luni/src/test/java/libcore/libcore/net/MimeUtilsTest.java
@@ -16,78 +16,194 @@
 
 package libcore.libcore.net;
 
-import junit.framework.TestCase;
-
 import libcore.net.MimeUtils;
 
+import junit.framework.TestCase;
+
+import java.util.Locale;
+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_mimeTypeFromExtension() {
+        assertEquals("video/vnd.youtube.yt", MimeUtils.guessMimeTypeFromExtension("yt"));
+    }
+
+    public void test_70851634_extensionFromMimeType() {
+        assertEquals("yt", MimeUtils.guessExtensionFromMimeType("video/vnd.youtube.yt"));
+        assertEquals("yt", MimeUtils.guessExtensionFromMimeType("application/vnd.youtube.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");
+    }
+
+    public void test_120135571_audio() {
+        assertMimeTypeFromExtension("audio/mpeg", "m4r");
+    }
+
+    public void testWifiConfig_xml() {
+        assertExtensionFromMimeType("xml", "application/x-wifi-config");
+        assertMimeTypeFromExtension("text/xml", "xml");
+    }
+
+    // http://b/122734564
+    public void testNonLowercaseMimeType() {
+        // A mixed-case mimeType that appears in mime.types; we expect guessMimeTypeFromExtension()
+        // to return it in lowercase because MimeUtils considers lowercase to be the canonical form.
+        String mimeType = "application/vnd.ms-word.document.macroEnabled.12".toLowerCase(Locale.US);
+        assertBidirectional(mimeType, "docm");
+    }
+
+    // Check that the keys given for lookups in either direction are not case sensitive
+    public void testCaseInsensitiveKeys() {
+        String mimeType = MimeUtils.guessMimeTypeFromExtension("apk");
+        assertNotNull(mimeType);
+
+        assertEquals(mimeType, MimeUtils.guessMimeTypeFromExtension("APK"));
+        assertEquals(mimeType, MimeUtils.guessMimeTypeFromExtension("aPk"));
+
+        assertEquals("apk", MimeUtils.guessExtensionFromMimeType(mimeType));
+        assertEquals("apk", MimeUtils.guessExtensionFromMimeType(mimeType.toUpperCase(Locale.US)));
+        assertEquals("apk", MimeUtils.guessExtensionFromMimeType(mimeType.toLowerCase(Locale.US)));
+    }
+
+    public void test_invalid_empty() {
+        checkInvalidExtension("");
+        checkInvalidMimeType("");
+    }
+
+    public void test_invalid_null() {
+        checkInvalidExtension(null);
+        checkInvalidMimeType(null);
+    }
+
+    public void test_invalid() {
+        checkInvalidMimeType("invalid mime type");
+        checkInvalidExtension("invalid extension");
+    }
+
+    private static void checkInvalidExtension(String s) {
+        assertFalse(MimeUtils.hasExtension(s));
+        assertNull(MimeUtils.guessMimeTypeFromExtension(s));
+    }
+
+    private static void checkInvalidMimeType(String s) {
+        assertFalse(MimeUtils.hasMimeType(s));
+        assertNull(MimeUtils.guessExtensionFromMimeType(s));
+    }
+
+    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/timezone/CountryTimeZonesTest.java b/luni/src/test/java/libcore/libcore/timezone/CountryTimeZonesTest.java
new file mode 100644
index 0000000..2a5f6e2
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/CountryTimeZonesTest.java
@@ -0,0 +1,733 @@
+/*
+ * 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.libcore.timezone;
+
+import org.junit.Test;
+
+import android.icu.util.TimeZone;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import libcore.timezone.CountryTimeZones;
+import libcore.timezone.CountryTimeZones.OffsetResult;
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class CountryTimeZonesTest {
+
+    private static final int HOUR_MILLIS = 60 * 60 * 1000;
+
+    private static final String INVALID_TZ_ID = "Moon/Tranquility_Base";
+
+    // Zones used in the tests. NEW_YORK_TZ and LONDON_TZ chosen because they never overlap but both
+    // have DST.
+    private static final TimeZone NEW_YORK_TZ = TimeZone.getTimeZone("America/New_York");
+    private static final TimeZone LONDON_TZ = TimeZone.getTimeZone("Europe/London");
+    // A zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
+    private static final TimeZone REYKJAVIK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
+    // Another zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for
+    // WHEN_DST.
+    private static final TimeZone UTC_TZ = TimeZone.getTimeZone("Etc/UTC");
+
+    // 22nd July 2017, 13:14:15 UTC (DST time in all the timezones used in these tests that observe
+    // DST).
+    private static final long WHEN_DST = 1500729255000L;
+    // 22nd January 2018, 13:14:15 UTC (non-DST time in all timezones used in these tests).
+    private static final long WHEN_NO_DST = 1516626855000L;
+
+    // The offset applied to most zones during DST.
+    private static final int NORMAL_DST_ADJUSTMENT = HOUR_MILLIS;
+
+    private static final int LONDON_NO_DST_OFFSET_MILLIS = 0;
+    private static final int LONDON_DST_OFFSET_MILLIS = LONDON_NO_DST_OFFSET_MILLIS
+            + NORMAL_DST_ADJUSTMENT;
+
+    private static final int NEW_YORK_NO_DST_OFFSET_MILLIS = -5 * HOUR_MILLIS;
+    private static final int NEW_YORK_DST_OFFSET_MILLIS = NEW_YORK_NO_DST_OFFSET_MILLIS
+            + NORMAL_DST_ADJUSTMENT;
+
+    @Test
+    public void createValidated() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+        assertTrue(countryTimeZones.isForCountryCode("gb"));
+        assertEquals("Europe/London", countryTimeZones.getDefaultTimeZoneId());
+        assertZoneEquals(zone("Europe/London"), countryTimeZones.getDefaultTimeZone());
+        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
+        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+    }
+
+    @Test
+    public void createValidated_nullDefault() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", null, true /* everUsesUtc */, timeZoneMappings("Europe/London"), "test");
+        assertNull(countryTimeZones.getDefaultTimeZoneId());
+    }
+
+    @Test
+    public void createValidated_invalidDefault() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", INVALID_TZ_ID, true /* everUsesUtc */,
+                timeZoneMappings("Europe/London", INVALID_TZ_ID), "test");
+        assertNull(countryTimeZones.getDefaultTimeZoneId());
+        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
+        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+    }
+
+    @Test
+    public void createValidated_unknownTimeZoneIdIgnored() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Unknown_Id", "Europe/London"), "test");
+        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
+        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
+    }
+
+    @Test
+    public void isForCountryCode() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+        assertTrue(countryTimeZones.isForCountryCode("GB"));
+        assertTrue(countryTimeZones.isForCountryCode("Gb"));
+        assertTrue(countryTimeZones.isForCountryCode("gB"));
+    }
+
+    @Test
+    public void structuresAreImmutable() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+
+        assertImmutableTimeZone(countryTimeZones.getDefaultTimeZone());
+
+        List<TimeZone> tzList = countryTimeZones.getIcuTimeZones();
+        assertEquals(1, tzList.size());
+        assertImmutableList(tzList);
+        assertImmutableTimeZone(tzList.get(0));
+
+        List<TimeZoneMapping> timeZoneMappings = countryTimeZones.getTimeZoneMappings();
+        assertEquals(1, timeZoneMappings.size());
+        assertImmutableList(timeZoneMappings);
+    }
+
+    @Test
+    public void lookupByOffsetWithBiasDeprecated_oneCandidate() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"), "test");
+
+        OffsetResult expectedResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, isDst and time.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and time do not match the configured
+        // zone.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        // A sample of a non-matching case with bias.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it doesn't match any of the country's zones.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+
+        // The bias should still be ignored even though it matches the offset information given:
+        // it doesn't match any of the country's configured zones.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(NEW_YORK_DST_OFFSET_MILLIS,
+                true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    @Test
+    public void lookupByOffsetWithBiasDeprecated_multipleNonOverlappingCandidates()
+            throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("America/New_York", "Europe/London"), "test");
+
+        OffsetResult expectedLondonResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+        OffsetResult expectedNewYorkResult = new OffsetResult(NEW_YORK_TZ, true /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, isDst and time.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and time do not match the configured
+        // zone. This is a sample, not complete.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        // A sample of a non-matching case with bias.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
+    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
+    @Test
+    public void lookupByOffsetWithBiasDeprecated_multipleOverlappingCandidates() throws Exception {
+        // Three zones that have the same offset for some of the year. Europe/London changes
+        // offset WHEN_DST, the others do not.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"), "test");
+
+        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
+        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
+        // This is the DST offset for LONDON_TZ.
+        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
+
+        OffsetResult expectedLondonOnlyMatch = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+        OffsetResult expectedReykjavikBestMatch =
+                new OffsetResult(REYKJAVIK_TZ, false /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, isDst and when.
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(dstOffset, true /* isDst */, WHEN_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(dstOffset, true /* isDst */, WHEN_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_DST,
+                        null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and time do not match the configured
+        // zones.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+                true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+                true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+                true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+                false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+
+        // Some bias cases below.
+
+        // Multiple zones match but Reykjavik is the bias.
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
+                        REYKJAVIK_TZ /* bias */));
+
+        // Multiple zones match but London is the bias.
+        OffsetResult expectedLondonBestMatch = new OffsetResult(LONDON_TZ, false /* oneMatch */);
+        assertOffsetResultEquals(expectedLondonBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
+                        LONDON_TZ /* bias */));
+
+        // Multiple zones match but UTC is the bias.
+        OffsetResult expectedUtcResult = new OffsetResult(UTC_TZ, false /* oneMatch */);
+        assertOffsetResultEquals(expectedUtcResult,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
+                        UTC_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS, true /* isDst */,
+                        WHEN_DST, REYKJAVIK_TZ /* bias */));
+    }
+
+    @Test
+    public void lookupByOffsetWithBias_oneCandidate() throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* uses UTC */, timeZoneMappings("Europe/London"),
+                "test");
+
+        OffsetResult expectedResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, isDst and time.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        0 /* no DST */, WHEN_NO_DST, null /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        null /* unknown DST */, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        null /* unknown DST */, WHEN_NO_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, DST offset and time do not match the
+        // configured zone.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        NORMAL_DST_ADJUSTMENT, WHEN_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        0 /* no DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
+                        null /* unknown DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        // A sample of a non-matching case with bias.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it doesn't match any of the country's zones.
+        assertOffsetResultEquals(expectedResult,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
+
+        // The bias should still be ignored even though it matches the offset information given:
+        // it doesn't match any of the country's configured zones.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(NEW_YORK_DST_OFFSET_MILLIS,
+                NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    @Test
+    public void lookupByOffsetWithBias_multipleNonOverlappingCandidates()
+            throws Exception {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* uses UTC */,
+                timeZoneMappings("America/New_York", "Europe/London"), "test");
+
+        OffsetResult expectedLondonResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+        OffsetResult expectedNewYorkResult = new OffsetResult(NEW_YORK_TZ, true /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, DST offset and time.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST, null /* bias */));
+        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
+        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */));
+        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST,
+                null /* bias */));
+
+        // Some lookup failure cases where the offset, DST offset and time do not match the
+        // configured zone. This is a sample, not complete.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
+                NEW_YORK_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST,
+                LONDON_TZ /* bias */));
+
+        // A sample of a non-matching case with bias.
+        assertNull(countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
+                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
+    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
+    @Test
+    public void lookupByOffsetWithBias_multipleOverlappingCandidates() throws Exception {
+        // Three zones that have the same offset for some of the year. Europe/London changes
+        // offset WHEN_DST, the others do not.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* uses UTC */,
+                timeZoneMappings("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"), "test");
+
+        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
+        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
+        // This is the DST offset for LONDON_TZ.
+        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
+
+        OffsetResult expectedLondonOnlyMatch = new OffsetResult(LONDON_TZ, true /* oneMatch */);
+        OffsetResult expectedReykjavikBestMatch =
+                new OffsetResult(REYKJAVIK_TZ, false /* oneMatch */);
+
+        // The three parameters match the configured zone: offset, DST offset and time.
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(dstOffset, NORMAL_DST_ADJUSTMENT, WHEN_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(dstOffset, NORMAL_DST_ADJUSTMENT, WHEN_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_DST,
+                        null /* bias */));
+
+        // Unknown DST cases
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null, WHEN_DST,
+                        null /* bias */));
+        assertNull(countryTimeZones.lookupByOffsetWithBias(dstOffset, null, WHEN_NO_DST,
+                        null /* bias */));
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(dstOffset, null, WHEN_DST,
+                        null /* bias */));
+
+        // Some lookup failure cases where the offset, DST offset and time do not match the
+        // configured zones.
+        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+                NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
+                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
+                0 /* no DST */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+
+        // Some bias cases below.
+
+        // Multiple zones match but Reykjavik is the bias.
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
+                        REYKJAVIK_TZ /* bias */));
+        assertOffsetResultEquals(expectedReykjavikBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
+                        WHEN_NO_DST, REYKJAVIK_TZ /* bias */));
+
+        // Multiple zones match but London is the bias.
+        OffsetResult expectedLondonBestMatch = new OffsetResult(LONDON_TZ, false /* oneMatch */);
+        assertOffsetResultEquals(expectedLondonBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
+                        LONDON_TZ /* bias */));
+        assertOffsetResultEquals(expectedLondonBestMatch,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
+                        WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // Multiple zones match but UTC is the bias.
+        OffsetResult expectedUtcResult = new OffsetResult(UTC_TZ, false /* oneMatch */);
+        assertOffsetResultEquals(expectedUtcResult,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
+                        UTC_TZ /* bias */));
+        assertOffsetResultEquals(expectedUtcResult,
+                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
+                        WHEN_NO_DST, UTC_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertOffsetResultEquals(expectedLondonOnlyMatch,
+                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
+                        NORMAL_DST_ADJUSTMENT, WHEN_DST, REYKJAVIK_TZ /* bias */));
+    }
+
+    @Test
+    public void isDefaultOkForCountryTimeZoneDetection_noZones() {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings(), "test");
+        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+    }
+
+    @Test
+    public void isDefaultOkForCountryTimeZoneDetection_oneZone() {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+    }
+
+    @Test
+    public void isDefaultOkForCountryTimeZoneDetection_twoZones_overlap() {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Europe/London", "Etc/UTC"), "test");
+        // Europe/London is the same as UTC in the Winter, so all the zones have the same offset
+        // in Winter, but not in Summer.
+        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+    }
+
+    @Test
+    public void isDefaultOkForCountryTimeZoneDetection_twoZones_noOverlap() {
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Europe/London", "America/New_York"), "test");
+        // The zones have different offsets all year, so it would never be ok to use the default
+        // zone for the country of "xx".
+        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
+        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
+    }
+
+    @Test
+    public void hasUtcZone_everUseUtcHintOverridesZoneInformation() {
+        // The country has a single zone. Europe/London uses UTC in Winter.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Etc/UTC", false /* everUsesUtc */, timeZoneMappings("Etc/UTC"), "test");
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+    }
+
+    @Test
+    public void hasUtcZone_singleZone() {
+        // The country has a single zone. Europe/London uses UTC in Winter.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+        assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+    }
+
+    @Test
+    public void hasUtcZone_multipleZonesWithUtc() {
+        // The country has multiple zones. Europe/London uses UTC in Winter.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "America/Los_Angeles", true /* everUsesUtc */,
+                timeZoneMappings("America/Los_Angeles", "America/New_York", "Europe/London"),
+                "test");
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+        assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+    }
+
+    @Test
+    public void hasUtcZone_multipleZonesWithoutUtc() {
+        // The country has multiple zones, none of which use UTC.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", "Europe/Paris", false /* everUsesUtc */,
+                timeZoneMappings("America/Los_Angeles", "America/New_York", "Europe/Paris"),
+                "test");
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+    }
+
+    @Test
+    public void hasUtcZone_emptyZones() {
+        // The country has no valid zones.
+        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
+                "xx", INVALID_TZ_ID, false /* everUsesUtc */, timeZoneMappings(INVALID_TZ_ID),
+                "test");
+        assertTrue(countryTimeZones.getTimeZoneMappings().isEmpty());
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
+        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
+    }
+
+    private void assertImmutableTimeZone(TimeZone timeZone) {
+        try {
+            timeZone.setRawOffset(1000);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static <X> void assertImmutableList(List<X> list) {
+        try {
+            list.add(null);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static void assertZoneEquals(TimeZone expected, TimeZone actual) {
+        // TimeZone.equals() only checks the ID, but that's ok for these tests.
+        assertEquals(expected, actual);
+    }
+
+    private static void assertOffsetResultEquals(OffsetResult expected, OffsetResult actual) {
+        assertEquals(expected.mTimeZone.getID(), actual.mTimeZone.getID());
+        assertEquals(expected.mOneMatch, actual.mOneMatch);
+    }
+
+    private static void assertZonesEqual(List<TimeZone> expected, List<TimeZone> actual) {
+        // TimeZone.equals() only checks the ID, but that's ok for these tests.
+        assertEquals(expected, actual);
+    }
+
+    private static TimeZone zone(String id) {
+        return TimeZone.getTimeZone(id);
+    }
+
+    /**
+     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
+     */
+    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
+        return Arrays.stream(timeZoneIds)
+                .map(x -> TimeZoneMapping.createForTests(
+                        x, true /* picker */, null /* notUsedAfter */))
+                .collect(Collectors.toList());
+    }
+
+    private static List<TimeZone> zones(String... ids) {
+        return Arrays.stream(ids).map(TimeZone::getTimeZone).collect(Collectors.toList());
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java b/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java
new file mode 100644
index 0000000..7fc2abf
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.timezone;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import libcore.timezone.CountryTimeZones;
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
+import libcore.timezone.CountryZonesFinder;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+public class CountryZonesFinderTest {
+
+    private static final CountryTimeZones GB_ZONES = CountryTimeZones.createValidated(
+            "gb", "Europe/London", true, timeZoneMappings("Europe/London"), "test");
+
+    private static final CountryTimeZones IM_ZONES = CountryTimeZones.createValidated(
+            "im", "Europe/London", true, timeZoneMappings("Europe/London"), "test");
+
+    private static final CountryTimeZones FR_ZONES = CountryTimeZones.createValidated(
+            "fr", "Europe/Paris", true, timeZoneMappings("Europe/Paris"), "test");
+
+    private static final CountryTimeZones US_ZONES = CountryTimeZones.createValidated(
+            "us", "America/New_York", true,
+            timeZoneMappings("America/New_York", "America/Los_Angeles"), "test");
+
+    @Test
+    public void lookupAllCountryIsoCodes() throws Exception {
+        CountryZonesFinder countryZonesFinder =
+                CountryZonesFinder.createForTests(list(GB_ZONES, FR_ZONES));
+
+        List<String> isoList = countryZonesFinder.lookupAllCountryIsoCodes();
+        assertEqualsAndImmutable(list(GB_ZONES.getCountryIso(), FR_ZONES.getCountryIso()), isoList);
+    }
+
+    @Test
+    public void lookupAllCountryIsoCodes_empty() throws Exception {
+        CountryZonesFinder countryZonesFinder = CountryZonesFinder.createForTests(list());
+        List<String> isoList = countryZonesFinder.lookupAllCountryIsoCodes();
+        assertEqualsAndImmutable(list(), isoList);
+    }
+
+    @Test
+    public void lookupCountryCodesForZoneId() throws Exception {
+        CountryZonesFinder countryZonesFinder =
+                CountryZonesFinder.createForTests(list(GB_ZONES, IM_ZONES, FR_ZONES, US_ZONES));
+
+        assertEqualsAndImmutable(list(GB_ZONES, IM_ZONES),
+                countryZonesFinder.lookupCountryTimeZonesForZoneId("Europe/London"));
+        assertEqualsAndImmutable(list(US_ZONES),
+                countryZonesFinder.lookupCountryTimeZonesForZoneId("America/New_York"));
+        assertEqualsAndImmutable(list(US_ZONES),
+                countryZonesFinder.lookupCountryTimeZonesForZoneId("America/Los_Angeles"));
+        assertEqualsAndImmutable(list(),
+                countryZonesFinder.lookupCountryTimeZonesForZoneId("DOES_NOT_EXIST"));
+    }
+
+    @Test
+    public void lookupCountryTimeZones() throws Exception {
+        CountryZonesFinder countryZonesFinder =
+                CountryZonesFinder.createForTests(list(GB_ZONES, IM_ZONES, FR_ZONES, US_ZONES));
+        assertSame(GB_ZONES, countryZonesFinder.lookupCountryTimeZones(GB_ZONES.getCountryIso()));
+        assertSame(IM_ZONES, countryZonesFinder.lookupCountryTimeZones(IM_ZONES.getCountryIso()));
+        assertNull(countryZonesFinder.lookupCountryTimeZones("DOES_NOT_EXIST"));
+    }
+
+    private static <X> void assertEqualsAndImmutable(List<X> expected, List<X> actual) {
+        assertEquals(expected, actual);
+        assertImmutableList(actual);
+    }
+
+    private static <X> void assertImmutableList(List<X> list) {
+        try {
+            list.add(null);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static <X> List<X> list(X... values) {
+        return Arrays.asList(values);
+    }
+
+    /**
+     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
+     */
+    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
+        return Arrays.stream(timeZoneIds)
+                .map(x -> TimeZoneMapping.createForTests(
+                        x, true /* picker */, null /* notUsedAfter */))
+                .collect(Collectors.toList());
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java b/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java
new file mode 100644
index 0000000..e94b96e
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.libcore.timezone;
+
+import org.junit.Test;
+
+import libcore.timezone.TimeZoneDataFiles;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TimeZoneDataFilesTest {
+
+    private static final String ANDROID_TZDATA_ROOT_ENV = "ANDROID_TZDATA_ROOT";
+    private static final String ANDROID_RUNTIME_ROOT_ENV = "ANDROID_RUNTIME_ROOT";
+
+    @Test
+    public void expectedEnvironmentVariables() {
+        // These environment variables are required to locate data files used by libcore / ICU.
+        assertNotNull(System.getenv(ANDROID_TZDATA_ROOT_ENV));
+        assertNotNull(System.getenv(ANDROID_RUNTIME_ROOT_ENV));
+    }
+
+    @Test
+    public void getTimeZoneFilePaths() {
+        String[] paths = TimeZoneDataFiles.getTimeZoneFilePaths("foo");
+        assertEquals(4, paths.length);
+
+        assertTrue(paths[0].contains("/misc/zoneinfo/current/"));
+        assertTrue(paths[0].endsWith("/foo"));
+
+        assertTrue(paths[1].startsWith(System.getenv(ANDROID_TZDATA_ROOT_ENV)));
+        assertTrue(paths[1].endsWith("/foo"));
+
+        assertTrue(paths[2].startsWith(System.getenv(ANDROID_RUNTIME_ROOT_ENV)));
+        assertTrue(paths[2].endsWith("/foo"));
+
+        assertTrue(paths[3].contains("/usr/share/zoneinfo/"));
+        assertTrue(paths[3].endsWith("/foo"));
+    }
+
+    // http://b/34867424
+    @Test
+    public void generateIcuDataPath_includesTimeZoneOverride() {
+        String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
+        assertEquals(icuDataPath, TimeZoneDataFiles.generateIcuDataPath());
+
+        String[] paths = icuDataPath.split(":");
+        assertEquals(3, paths.length);
+
+        String dataDirPath = paths[0];
+        assertTrue(dataDirPath + " invalid", dataDirPath.contains("/misc/zoneinfo/current/icu"));
+
+        String tzdataModulePath = paths[1];
+        assertTrue(tzdataModulePath + " invalid",
+                tzdataModulePath.startsWith(System.getenv(ANDROID_TZDATA_ROOT_ENV)));
+
+        String runtimeModulePath = paths[2];
+        assertTrue(runtimeModulePath + " invalid",
+                runtimeModulePath.startsWith(System.getenv(ANDROID_RUNTIME_ROOT_ENV)));
+        assertTrue(runtimeModulePath + " invalid", runtimeModulePath.contains("/etc/icu"));
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/TimeZoneFinderTest.java b/luni/src/test/java/libcore/libcore/timezone/TimeZoneFinderTest.java
new file mode 100644
index 0000000..8bfacd8
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/TimeZoneFinderTest.java
@@ -0,0 +1,993 @@
+/*
+ * 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.libcore.timezone;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import android.icu.util.TimeZone;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import libcore.timezone.CountryTimeZones;
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
+import libcore.timezone.CountryZonesFinder;
+import libcore.timezone.TimeZoneFinder;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+public class TimeZoneFinderTest {
+
+    private static final int HOUR_MILLIS = 60 * 60 * 1000;
+
+    // Zones used in the tests. NEW_YORK_TZ and LONDON_TZ chosen because they never overlap but both
+    // have DST.
+    private static final TimeZone NEW_YORK_TZ = TimeZone.getTimeZone("America/New_York");
+    private static final TimeZone LONDON_TZ = TimeZone.getTimeZone("Europe/London");
+    // A zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
+    private static final TimeZone REYKJAVIK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
+    // Another zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for
+    // WHEN_DST.
+    private static final TimeZone UTC_TZ = TimeZone.getTimeZone("Etc/UTC");
+
+    // 22nd July 2017, 13:14:15 UTC (DST time in all the timezones used in these tests that observe
+    // DST).
+    private static final long WHEN_DST = 1500729255000L;
+    // 22nd January 2018, 13:14:15 UTC (non-DST time in all timezones used in these tests).
+    private static final long WHEN_NO_DST = 1516626855000L;
+
+    private static final int LONDON_DST_OFFSET_MILLIS = HOUR_MILLIS;
+    private static final int LONDON_NO_DST_OFFSET_MILLIS = 0;
+
+    private static final int NEW_YORK_DST_OFFSET_MILLIS = -4 * HOUR_MILLIS;
+    private static final int NEW_YORK_NO_DST_OFFSET_MILLIS = -5 * HOUR_MILLIS;
+
+    private Path testDir;
+
+    @Before
+    public void setUp() throws Exception {
+        testDir = Files.createTempDirectory("TimeZoneFinderTest");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Delete the testDir and all contents.
+        Files.walkFileTree(testDir, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                Files.delete(file);
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+                    throws IOException {
+                Files.delete(dir);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    @Test
+    public void createInstanceWithFallback() throws Exception {
+        String validXml1 = "<timezones ianaversion=\"2017c\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n";
+        CountryTimeZones expectedCountryTimeZones1 = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+
+        String validXml2 = "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/Paris\" everutc=\"n\">\n"
+                + "      <id>Europe/Paris</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n";
+        CountryTimeZones expectedCountryTimeZones2 = CountryTimeZones.createValidated(
+                "gb", "Europe/Paris", false /* everUsesUtc */, timeZoneMappings("Europe/Paris"),
+                "test");
+
+        String invalidXml = "<foo></foo>\n";
+        checkValidateThrowsParserException(invalidXml);
+
+        String validFile1 = createFile(validXml1);
+        String validFile2 = createFile(validXml2);
+        String invalidFile = createFile(invalidXml);
+        String missingFile = createMissingFile();
+
+        TimeZoneFinder file1ThenFile2 =
+                TimeZoneFinder.createInstanceWithFallback(validFile1, validFile2);
+        assertEquals("2017c", file1ThenFile2.getIanaVersion());
+        assertEquals(expectedCountryTimeZones1, file1ThenFile2.lookupCountryTimeZones("gb"));
+
+        TimeZoneFinder missingFileThenFile1 =
+                TimeZoneFinder.createInstanceWithFallback(missingFile, validFile1);
+        assertEquals("2017c", missingFileThenFile1.getIanaVersion());
+        assertEquals(expectedCountryTimeZones1, missingFileThenFile1.lookupCountryTimeZones("gb"));
+
+        TimeZoneFinder file2ThenFile1 =
+                TimeZoneFinder.createInstanceWithFallback(validFile2, validFile1);
+        assertEquals("2017b", file2ThenFile1.getIanaVersion());
+        assertEquals(expectedCountryTimeZones2, file2ThenFile1.lookupCountryTimeZones("gb"));
+
+        // We assume the file has been validated so an invalid file is not checked ahead of time.
+        // We will find out when we look something up.
+        TimeZoneFinder invalidThenValid =
+                TimeZoneFinder.createInstanceWithFallback(invalidFile, validFile1);
+        assertNull(invalidThenValid.getIanaVersion());
+        assertNull(invalidThenValid.lookupCountryTimeZones("gb"));
+
+        // This is not a normal case: It would imply a define shipped without a file in /system!
+        TimeZoneFinder missingFiles =
+                TimeZoneFinder.createInstanceWithFallback(missingFile, missingFile);
+        assertNull(missingFiles.getIanaVersion());
+        assertNull(missingFiles.lookupCountryTimeZones("gb"));
+    }
+
+    @Test
+    public void xmlParsing_emptyFile() throws Exception {
+        checkValidateThrowsParserException("");
+    }
+
+    @Test
+    public void xmlParsing_unexpectedRootElement() throws Exception {
+        checkValidateThrowsParserException("<foo></foo>\n");
+    }
+
+    @Test
+    public void xmlParsing_missingCountryZones() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\"></timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_noCountriesOk() throws Exception {
+        validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_unexpectedComments() throws Exception {
+        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <!-- This is a comment -->"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        // This is a crazy comment, but also helps prove that TEXT nodes are coalesced by the
+        // parser.
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/<!-- Don't freak out! -->London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+    }
+
+    @Test
+    public void xmlParsing_unexpectedElementsIgnored() throws Exception {
+        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+
+        String unexpectedElement = "<unexpected-element>\n<a /></unexpected-element>\n";
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  " + unexpectedElement
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    " + unexpectedElement
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      " + unexpectedElement
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "    " + unexpectedElement
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        // This test is important because it ensures we can extend the format in future with
+        // more information.
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "  " + unexpectedElement
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Europe/London", "Europe/Paris"), "test");
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "      " + unexpectedElement
+                + "      <id>Europe/Paris</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+    }
+
+    @Test
+    public void xmlParsing_unexpectedTextIgnored() throws Exception {
+        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+
+        String unexpectedText = "unexpected-text";
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  " + unexpectedText
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    " + unexpectedText
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      " + unexpectedText
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+
+        expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */,
+                timeZoneMappings("Europe/London", "Europe/Paris"), "test");
+        finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "      " + unexpectedText
+                + "      <id>Europe/Paris</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+    }
+
+    @Test
+    public void xmlParsing_truncatedInput() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n");
+
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n");
+
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n");
+
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n");
+
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n");
+
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n");
+    }
+
+    @Test
+    public void xmlParsing_unexpectedChildInTimeZoneIdThrows() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id><unexpected-element /></id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_unknownTimeZoneIdIgnored() throws Exception {
+        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
+                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
+                "test");
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Unknown_Id</id>\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
+    }
+
+    @Test
+    public void xmlParsing_missingCountryCode() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_missingCountryEverUtc() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_badCountryEverUtc() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"occasionally\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_missingCountryDefault() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_badTimeZoneMappingPicker() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id picker=\"sometimes\">Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_timeZoneMappingPicker() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"us\" default=\"America/New_York\" everutc=\"n\">\n"
+                + "      <!-- Explicit picker=\"y\" -->\n"
+                + "      <id picker=\"y\">America/New_York</id>\n"
+                + "      <!-- Implicit picker=\"y\" -->\n"
+                + "      <id>America/Los_Angeles</id>\n"
+                + "      <!-- Explicit picker=\"n\" -->\n"
+                + "      <id picker=\"n\">America/Indiana/Vincennes</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        CountryTimeZones usTimeZones = finder.lookupCountryTimeZones("us");
+        List<TimeZoneMapping> actualTimeZoneMappings = usTimeZones.getTimeZoneMappings();
+        List<TimeZoneMapping> expectedTimeZoneMappings = list(
+                TimeZoneMapping.createForTests(
+                        "America/New_York", true /* shownInPicker */, null /* notUsedAfter */),
+                TimeZoneMapping.createForTests(
+                        "America/Los_Angeles", true /* shownInPicker */, null /* notUsedAfter */),
+                TimeZoneMapping.createForTests(
+                        "America/Indiana/Vincennes", false /* shownInPicker */,
+                        null /* notUsedAfter */)
+        );
+        assertEquals(expectedTimeZoneMappings, actualTimeZoneMappings);
+    }
+
+    @Test
+    public void xmlParsing_badTimeZoneMappingNotAfter() throws Exception {
+        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id notafter=\"sometimes\">Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+    }
+
+    @Test
+    public void xmlParsing_timeZoneMappingNotAfter() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"us\" default=\"America/New_York\" everutc=\"n\">\n"
+                + "      <!-- Explicit notafter -->\n"
+                + "      <id notafter=\"1234\">America/New_York</id>\n"
+                + "      <!-- Missing notafter -->\n"
+                + "      <id>America/Indiana/Vincennes</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        CountryTimeZones usTimeZones = finder.lookupCountryTimeZones("us");
+        List<TimeZoneMapping> actualTimeZoneMappings = usTimeZones.getTimeZoneMappings();
+        List<TimeZoneMapping> expectedTimeZoneMappings = list(
+                TimeZoneMapping.createForTests(
+                        "America/New_York", true /* shownInPicker */, 1234L /* notUsedAfter */),
+                TimeZoneMapping.createForTests(
+                        "America/Indiana/Vincennes", true /* shownInPicker */,
+                        null /* notUsedAfter */)
+        );
+        assertEquals(expectedTimeZoneMappings, actualTimeZoneMappings);
+    }
+
+    @Test
+    public void xmlParsing_unknownCountryReturnsNull() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertNull(finder.lookupTimeZoneIdsByCountry("gb"));
+        assertNull(finder.lookupTimeZonesByCountry("gb"));
+    }
+
+    @Test
+    public void getCountryZonesFinder() throws Exception {
+        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
+                "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "    <country code=\"fr\" default=\"Europe/Paris\" everutc=\"y\">\n"
+                + "      <id>Europe/Paris</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        CountryTimeZones expectedGb = CountryTimeZones.createValidated("gb", "Europe/London", true,
+                timeZoneMappings("Europe/London"), "test");
+        CountryTimeZones expectedFr = CountryTimeZones.createValidated("fr", "Europe/Paris", true,
+                timeZoneMappings("Europe/Paris"), "test");
+        CountryZonesFinder countryZonesFinder = timeZoneFinder.getCountryZonesFinder();
+        assertEquals(list("gb", "fr"), countryZonesFinder.lookupAllCountryIsoCodes());
+        assertEquals(expectedGb, countryZonesFinder.lookupCountryTimeZones("gb"));
+        assertEquals(expectedFr, countryZonesFinder.lookupCountryTimeZones("fr"));
+        assertNull(countryZonesFinder.lookupCountryTimeZones("DOES_NOT_EXIST"));
+    }
+
+    @Test
+    public void getCountryZonesFinder_empty() throws Exception {
+        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
+                "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        CountryZonesFinder countryZonesFinder = timeZoneFinder.getCountryZonesFinder();
+        assertEquals(list(), countryZonesFinder.lookupAllCountryIsoCodes());
+    }
+
+    @Test
+    public void getCountryZonesFinder_invalid() throws Exception {
+        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
+                "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "    <!-- Missing required attributes! -->\n"
+                + "    <country code=\"fr\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertNull(timeZoneFinder.getCountryZonesFinder());
+    }
+
+    @Test
+    public void lookupTimeZonesByCountry_structuresAreImmutable() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        List<TimeZone> gbList = finder.lookupTimeZonesByCountry("gb");
+        assertEquals(1, gbList.size());
+        assertImmutableList(gbList);
+        assertImmutableTimeZone(gbList.get(0));
+
+        // Check country code normalization works too.
+        assertEquals(1, finder.lookupTimeZonesByCountry("GB").size());
+
+        assertNull(finder.lookupTimeZonesByCountry("unknown"));
+    }
+
+    @Test
+    public void lookupTimeZoneIdsByCountry_structuresAreImmutable() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        List<String> gbList = finder.lookupTimeZoneIdsByCountry("gb");
+        assertEquals(1, gbList.size());
+        assertImmutableList(gbList);
+
+        // Check country code normalization works too.
+        assertEquals(1, finder.lookupTimeZoneIdsByCountry("GB").size());
+
+        assertNull(finder.lookupTimeZoneIdsByCountry("unknown"));
+    }
+
+    @Test
+    public void lookupDefaultTimeZoneIdByCountry() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
+
+        // Check country code normalization works too.
+        assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("GB"));
+    }
+
+    /**
+     * At runtime we don't validate too much since there's nothing we can do if the data is
+     * incorrect.
+     */
+    @Test
+    public void lookupDefaultTimeZoneIdByCountry_notCountryTimeZoneButValid() throws Exception {
+        String xml = "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"America/New_York\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n";
+        // validate() should fail because America/New_York is not one of the "gb" zones listed.
+        checkValidateThrowsParserException(xml);
+
+        // But it should still work at runtime.
+        TimeZoneFinder finder = TimeZoneFinder.createInstanceForTests(xml);
+        assertEquals("America/New_York", finder.lookupDefaultTimeZoneIdByCountry("gb"));
+    }
+
+    @Test
+    public void lookupDefaultTimeZoneIdByCountry_invalidDefault() throws Exception {
+        String xml = "<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Moon/Tranquility_Base\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "      <id>Moon/Tranquility_Base</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n";
+        // validate() should pass because the IDs all match.
+        TimeZoneFinder finder = validate(xml);
+
+        // But "Moon/Tranquility_Base" is not a valid time zone ID so should not be used.
+        assertNull(finder.lookupDefaultTimeZoneIdByCountry("gb"));
+    }
+
+    @Test
+    public void lookupTimeZoneByCountryAndOffset_unknownCountry() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        // Demonstrate the arguments work for a known country.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, null /* bias */));
+
+        // Check country code normalization works too.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("XX", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, null /* bias */));
+
+        // Test with an unknown country.
+        String unknownCountryCode = "yy";
+        assertNull(finder.lookupTimeZoneByCountryAndOffset(unknownCountryCode,
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+
+        assertNull(finder.lookupTimeZoneByCountryAndOffset(unknownCountryCode,
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+    }
+
+    @Test
+    public void lookupTimeZoneByCountryAndOffset_oneCandidate() throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        // The three parameters match the configured zone: offset, isDst and when.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, null /* bias */));
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
+                        false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and when do not match the configured
+        // zone.
+        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        TimeZone noDstMatch5 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        TimeZone noDstMatch6 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
+                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        // A sample of a non-matching case with bias.
+        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it doesn't match any of the country's zones.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+
+        // The bias should still be ignored even though it matches the offset information given:
+        // it doesn't match any of the country's configured zones.
+        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", NEW_YORK_DST_OFFSET_MILLIS,
+                true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    @Test
+    public void lookupTimeZoneByCountryAndOffset_multipleNonOverlappingCandidates()
+            throws Exception {
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>America/New_York</id>\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        // The three parameters match the configured zone: offset, isDst and when.
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+        assertZoneEquals(NEW_YORK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
+                NEW_YORK_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
+        assertZoneEquals(NEW_YORK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
+                NEW_YORK_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and when do not match the configured
+        // zone. This is a sample, not complete.
+        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+        TimeZone noDstMatch5 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch5);
+
+        TimeZone noDstMatch6 = finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch6);
+
+        // Some bias cases below.
+
+        // The bias is irrelevant here: it matches what would be returned anyway.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
+                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        // A sample of a non-matching case with bias.
+        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertZoneEquals(LONDON_TZ,
+                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
+                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
+    }
+
+    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
+    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
+    @Test
+    public void lookupTimeZoneByCountryAndOffset_multipleOverlappingCandidates() throws Exception {
+        // Three zones that have the same offset for some of the year. Europe/London changes
+        // offset WHEN_DST, the others do not.
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Atlantic/Reykjavik</id>\n"
+                + "      <id>Europe/London</id>\n"
+                + "      <id>Etc/UTC</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+
+        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
+        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
+        // This is the DST offset for LONDON_TZ.
+        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
+
+        // The three parameters match the configured zone: offset, isDst and when.
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
+                true /* isDst */, WHEN_DST, null /* bias */));
+        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_NO_DST, null /* bias */));
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
+                true /* isDst */, WHEN_DST, null /* bias */));
+        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_NO_DST, null /* bias */));
+        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_DST, null /* bias */));
+
+        // Some lookup failure cases where the offset, isDst and when do not match the configured
+        // zones.
+        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
+                true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch1);
+
+        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                true /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch2);
+
+        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                true /* isDst */, WHEN_NO_DST, null /* bias */);
+        assertNull(noDstMatch3);
+
+        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
+                false /* isDst */, WHEN_DST, null /* bias */);
+        assertNull(noDstMatch4);
+
+
+        // Some bias cases below.
+
+        // The bias is relevant here: it overrides what would be returned naturally.
+        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_NO_DST, null /* bias */));
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
+        assertZoneEquals(UTC_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
+                false /* isDst */, WHEN_NO_DST, UTC_TZ /* bias */));
+
+        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
+        // should not be considered a match.
+        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
+                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, REYKJAVIK_TZ /* bias */));
+    }
+
+    @Test
+    public void xmlParsing_missingIanaVersionAttribute() throws Exception {
+        // The <timezones> element will typically have an ianaversion attribute, but it's not
+        // required for parsing.
+        TimeZoneFinder finder = validate("<timezones>\n"
+                + "  <countryzones>\n"
+                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+                + "      <id>Europe/London</id>\n"
+                + "    </country>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
+
+        assertNull(finder.getIanaVersion());
+    }
+
+    @Test
+    public void getIanaVersion() throws Exception {
+        final String expectedIanaVersion = "2017b";
+
+        TimeZoneFinder finder = validate("<timezones ianaversion=\"" + expectedIanaVersion + "\">\n"
+                + "  <countryzones>\n"
+                + "  </countryzones>\n"
+                + "</timezones>\n");
+        assertEquals(expectedIanaVersion, finder.getIanaVersion());
+    }
+
+    private static void assertImmutableTimeZone(TimeZone timeZone) {
+        try {
+            timeZone.setRawOffset(1000);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static <X> void assertImmutableList(List<X> list) {
+        try {
+            list.add(null);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static void assertZoneEquals(TimeZone expected, TimeZone actual) {
+        // TimeZone.equals() only checks the ID, but that's ok for these tests.
+        assertEquals(expected, actual);
+    }
+
+    private static void checkValidateThrowsParserException(String xml) {
+        try {
+            validate(xml);
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    private static TimeZoneFinder validate(String xml) throws IOException {
+        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(xml);
+        timeZoneFinder.validate();
+        return timeZoneFinder;
+    }
+
+    /**
+     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
+     */
+    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
+        return Arrays.stream(timeZoneIds)
+                .map(x -> TimeZoneMapping.createForTests(
+                        x, true /* showInPicker */, null /* notUsedAfter */))
+                .collect(Collectors.toList());
+    }
+
+    private static <X> List<X> list(X... values) {
+        return Arrays.asList(values);
+    }
+
+    private static <X> List<X> sort(Collection<X> value) {
+        return value.stream().sorted()
+                .collect(Collectors.toList());
+    }
+
+    private String createFile(String fileContent) throws IOException {
+        Path filePath = Files.createTempFile(testDir, null, null);
+        Files.write(filePath, fileContent.getBytes(StandardCharsets.UTF_8));
+        return filePath.toString();
+    }
+
+    private String createMissingFile() throws IOException {
+        Path filePath = Files.createTempFile(testDir, null, null);
+        Files.delete(filePath);
+        return filePath.toString();
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/TzDataSetVersionTest.java b/luni/src/test/java/libcore/libcore/timezone/TzDataSetVersionTest.java
new file mode 100644
index 0000000..75e079b
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/TzDataSetVersionTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.libcore.timezone;
+
+import junit.framework.TestCase;
+
+import libcore.timezone.TzDataSetVersion;
+import libcore.timezone.TzDataSetVersion.TzDataSetException;
+
+public class TzDataSetVersionTest extends TestCase {
+
+    private static final int INVALID_VERSION_LOW = -1;
+    private static final int VALID_VERSION = 23;
+    private static final int INVALID_VERSION_HIGH = 1000;
+    private static final String VALID_RULES_VERSION = "2016a";
+    private static final String INVALID_RULES_VERSION = "A016a";
+
+    public void testConstructorValidation() throws Exception {
+        checkConstructorThrows(
+                INVALID_VERSION_LOW, VALID_VERSION, VALID_RULES_VERSION, VALID_VERSION);
+        checkConstructorThrows(
+                INVALID_VERSION_HIGH, VALID_VERSION, VALID_RULES_VERSION, VALID_VERSION);
+        checkConstructorThrows(
+                VALID_VERSION, INVALID_VERSION_LOW, VALID_RULES_VERSION, VALID_VERSION);
+        checkConstructorThrows(
+                VALID_VERSION, INVALID_VERSION_HIGH, VALID_RULES_VERSION, VALID_VERSION);
+        checkConstructorThrows(VALID_VERSION, VALID_VERSION, INVALID_RULES_VERSION, VALID_VERSION);
+        checkConstructorThrows(VALID_VERSION, VALID_VERSION, VALID_RULES_VERSION,
+                INVALID_VERSION_LOW);
+        checkConstructorThrows(VALID_VERSION, VALID_VERSION, VALID_RULES_VERSION,
+                INVALID_VERSION_HIGH);
+    }
+
+    private static void checkConstructorThrows(
+            int majorVersion, int minorVersion, String rulesVersion, int revision) {
+        try {
+            new TzDataSetVersion(majorVersion, minorVersion, rulesVersion, revision);
+            fail();
+        } catch (TzDataSetException expected) {}
+    }
+
+    public void testConstructor() throws Exception {
+        TzDataSetVersion distroVersion = new TzDataSetVersion(1, 2, VALID_RULES_VERSION, 3);
+        assertEquals(1, distroVersion.formatMajorVersion);
+        assertEquals(2, distroVersion.formatMinorVersion);
+        assertEquals(VALID_RULES_VERSION, distroVersion.rulesVersion);
+        assertEquals(3, distroVersion.revision);
+    }
+
+    public void testToFromBytesRoundTrip() throws Exception {
+        TzDataSetVersion distroVersion = new TzDataSetVersion(1, 2, VALID_RULES_VERSION, 3);
+        assertEquals(distroVersion, TzDataSetVersion.fromBytes(distroVersion.toBytes()));
+    }
+
+    public void testIsCompatibleWithThisDevice() throws Exception {
+        TzDataSetVersion exactMatch = createTzDataSetVersion(
+                TzDataSetVersion.currentFormatMajorVersion(),
+                TzDataSetVersion.currentFormatMinorVersion());
+        assertTrue(TzDataSetVersion.isCompatibleWithThisDevice(exactMatch));
+
+        TzDataSetVersion newerMajor = createTzDataSetVersion(
+                TzDataSetVersion.currentFormatMajorVersion() + 1,
+                TzDataSetVersion.currentFormatMinorVersion());
+        assertFalse(TzDataSetVersion.isCompatibleWithThisDevice(newerMajor));
+
+        TzDataSetVersion newerMinor = createTzDataSetVersion(
+                TzDataSetVersion.currentFormatMajorVersion(),
+                TzDataSetVersion.currentFormatMinorVersion() + 1);
+        assertTrue(TzDataSetVersion.isCompatibleWithThisDevice(newerMinor));
+
+        // The constant versions should never be below 1. We allow 0 but want to start version
+        // numbers at 1 to allow testing of older version logic.
+        assertTrue(TzDataSetVersion.currentFormatMajorVersion() >= 1);
+        assertTrue(TzDataSetVersion.currentFormatMinorVersion() >= 1);
+
+        TzDataSetVersion olderMajor = createTzDataSetVersion(
+                TzDataSetVersion.currentFormatMajorVersion() - 1,
+                TzDataSetVersion.currentFormatMinorVersion());
+        assertFalse(TzDataSetVersion.isCompatibleWithThisDevice(olderMajor));
+
+        TzDataSetVersion olderMinor = createTzDataSetVersion(
+                TzDataSetVersion.currentFormatMajorVersion(),
+                TzDataSetVersion.currentFormatMinorVersion() - 1);
+        assertFalse(TzDataSetVersion.isCompatibleWithThisDevice(olderMinor));
+    }
+
+    private TzDataSetVersion createTzDataSetVersion(int majorFormatVersion, int minorFormatVersion)
+            throws TzDataSetException {
+        return new TzDataSetVersion(majorFormatVersion, minorFormatVersion, VALID_RULES_VERSION, 3);
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/ZoneInfoDBTest.java b/luni/src/test/java/libcore/libcore/timezone/ZoneInfoDBTest.java
new file mode 100644
index 0000000..3f4791c
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/timezone/ZoneInfoDBTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2013 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.timezone;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.timezone.testing.ZoneInfoTestHelper;
+import libcore.util.ZoneInfo;
+import libcore.timezone.ZoneInfoDB;
+
+import static libcore.timezone.ZoneInfoDB.TzData.SIZEOF_INDEX_ENTRY;
+
+public class ZoneInfoDBTest extends junit.framework.TestCase {
+
+  // The base tzdata file, always present on a device.
+  private static final String SYSTEM_TZDATA_FILE =
+      TimeZoneDataFiles.getSystemTimeZoneFile(ZoneInfoDB.TZDATA_FILE);
+
+  // An empty override file should fall back to the default file.
+  public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
+    String emptyFilePath = makeEmptyFile().getPath();
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
+         ZoneInfoDB.TzData dataWithEmptyOverride =
+                 ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, SYSTEM_TZDATA_FILE)) {
+      assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
+      assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
+    }
+  }
+
+  // A corrupt override file should fall back to the default file.
+  public void testLoadTzDataWithFallback_corruptOverrideFile() throws Exception {
+    String corruptFilePath = makeCorruptFile().getPath();
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
+         ZoneInfoDB.TzData dataWithCorruptOverride =
+                 ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, SYSTEM_TZDATA_FILE)) {
+      assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
+      assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
+    }
+  }
+
+  // Given no tzdata files we can use, we should fall back to built-in "GMT".
+  public void testLoadTzDataWithFallback_noGoodFile() throws Exception {
+    String emptyFilePath = makeEmptyFile().getPath();
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath)) {
+      assertEquals("missing", data.getVersion());
+      assertEquals(1, data.getAvailableIDs().length);
+      assertEquals("GMT", data.getAvailableIDs()[0]);
+    }
+  }
+
+  // Given a valid override file, we should find ourselves using that.
+  public void testLoadTzDataWithFallback_goodOverrideFile() throws Exception {
+    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
+    byte[] content = new byte[(int) in.length()];
+    in.readFully(content);
+    in.close();
+
+    // Bump the version number to one long past where humans will be extinct.
+    content[6] = '9';
+    content[7] = '9';
+    content[8] = '9';
+    content[9] = '9';
+    content[10] = 'z';
+
+    File goodFile = makeTemporaryFile(content);
+    try (ZoneInfoDB.TzData dataWithOverride =
+              ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), SYSTEM_TZDATA_FILE);
+         ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
+
+      assertEquals("9999z", dataWithOverride.getVersion());
+      assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
+    } finally {
+      goodFile.delete();
+    }
+  }
+
+  public void testLoadTzData_badHeader() throws Exception {
+    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
+    byte[] content = new byte[(int) in.length()];
+    in.readFully(content);
+    in.close();
+
+    // Break the header.
+    content[0] = 'a';
+    checkInvalidDataDetected(content);
+  }
+
+  public void testLoadTzData_validTestData() throws Exception {
+    byte[] data = new ZoneInfoTestHelper.TzDataBuilder().initializeToValid().build();
+    File testFile = makeTemporaryFile(data);
+    try {
+      assertNotNull(ZoneInfoDB.TzData.loadTzData(testFile.getPath()));
+    } finally {
+      testFile.delete();
+    }
+  }
+
+  public void testLoadTzData_invalidOffsets() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+
+    // Sections must be in the correct order: section sizing is calculated using them.
+    builder.setIndexOffsetOverride(10);
+    builder.setDataOffsetOverride(30);
+
+    byte[] data = builder.build();
+    // The offsets must all be under the total size of the file for this test to be valid.
+    assertTrue(30 < data.length);
+    checkInvalidDataDetected(data);
+  }
+
+  public void testLoadTzData_zoneTabOutsideFile() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder()
+                    .initializeToValid();
+
+    // Sections must be in the correct order: section sizing is calculated using them.
+    builder.setIndexOffsetOverride(10);
+    builder.setDataOffsetOverride(10 + SIZEOF_INDEX_ENTRY);
+    builder.setZoneTabOffsetOverride(3000); // This is invalid if it is outside of the file.
+
+    byte[] data = builder.build();
+    // The zoneTab offset must be outside of the file for this test to be valid.
+    assertTrue(3000 > data.length);
+    checkInvalidDataDetected(data);
+  }
+
+  public void testLoadTzData_nonDivisibleIndex() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+
+    // Sections must be in the correct order: section sizing is calculated using them.
+    int indexOffset = 10;
+    builder.setIndexOffsetOverride(indexOffset);
+    int dataOffset = indexOffset + ZoneInfoDB.TzData.SIZEOF_INDEX_ENTRY - 1;
+    builder.setDataOffsetOverride(dataOffset);
+    builder.setZoneTabOffsetOverride(dataOffset + 40);
+
+    byte[] data = builder.build();
+    // The zoneTab offset must be outside of the file for this test to be valid.
+    assertTrue(3000 > data.length);
+    checkInvalidDataDetected(data);
+  }
+
+  public void testLoadTzData_badId() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+    builder.clearZicData();
+    byte[] validZicData =
+            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
+    builder.addZicData("", validZicData); // "" is an invalid ID
+
+    checkInvalidDataDetected(builder.build());
+  }
+
+  public void testLoadTzData_badIdOrder() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+    builder.clearZicData();
+    byte[] validZicData =
+            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
+    builder.addZicData("Europe/Zurich", validZicData);
+    builder.addZicData("Europe/London", validZicData);
+
+    checkInvalidDataDetected(builder.build());
+  }
+
+  public void testLoadTzData_duplicateId() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+    builder.clearZicData();
+    byte[] validZicData =
+            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
+    builder.addZicData("Europe/London", validZicData);
+    builder.addZicData("Europe/London", validZicData);
+
+    checkInvalidDataDetected(builder.build());
+  }
+
+  public void testLoadTzData_badZicLength() throws Exception {
+    ZoneInfoTestHelper.TzDataBuilder builder =
+            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
+    builder.clearZicData();
+    byte[] invalidZicData = "This is too short".getBytes();
+    builder.addZicData("Europe/London", invalidZicData);
+
+    checkInvalidDataDetected(builder.build());
+  }
+
+  private static void checkInvalidDataDetected(byte[] data) throws Exception {
+    File testFile = makeTemporaryFile(data);
+    try {
+      assertNull(ZoneInfoDB.TzData.loadTzData(testFile.getPath()));
+    } finally {
+      testFile.delete();
+    }
+  }
+
+  // Confirms any caching that exists correctly handles TimeZone mutability.
+  public void testMakeTimeZone_timeZoneMutability() throws Exception {
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
+      String tzId = "Europe/London";
+      ZoneInfo first = data.makeTimeZone(tzId);
+      ZoneInfo second = data.makeTimeZone(tzId);
+      assertNotSame(first, second);
+
+      assertTrue(first.hasSameRules(second));
+
+      first.setID("Not Europe/London");
+
+      assertFalse(first.getID().equals(second.getID()));
+
+      first.setRawOffset(3600);
+      assertFalse(first.getRawOffset() == second.getRawOffset());
+    }
+  }
+
+  public void testMakeTimeZone_notFound() throws Exception {
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
+      assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
+      assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST"));
+    }
+  }
+
+  public void testMakeTimeZone_found() throws Exception {
+    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
+      assertNotNull(data.makeTimeZone("Europe/London"));
+      assertTrue(data.hasTimeZone("Europe/London"));
+    }
+  }
+
+  private static File makeCorruptFile() throws Exception {
+    return makeTemporaryFile("invalid content".getBytes());
+  }
+
+  private static File makeEmptyFile() throws Exception {
+    return makeTemporaryFile(new byte[0]);
+  }
+
+  private static File makeTemporaryFile(byte[] content) throws Exception {
+    File f = File.createTempFile("temp-", ".txt");
+    FileOutputStream fos = new FileOutputStream(f);
+    fos.write(content);
+    fos.close();
+    return f;
+  }
+}
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/libcore/util/CountryTimeZonesTest.java b/luni/src/test/java/libcore/libcore/util/CountryTimeZonesTest.java
deleted file mode 100644
index 3466e7b..0000000
--- a/luni/src/test/java/libcore/libcore/util/CountryTimeZonesTest.java
+++ /dev/null
@@ -1,733 +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.libcore.util;
-
-import org.junit.Test;
-
-import android.icu.util.TimeZone;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import libcore.util.CountryTimeZones;
-import libcore.util.CountryTimeZones.OffsetResult;
-import libcore.util.CountryTimeZones.TimeZoneMapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class CountryTimeZonesTest {
-
-    private static final int HOUR_MILLIS = 60 * 60 * 1000;
-
-    private static final String INVALID_TZ_ID = "Moon/Tranquility_Base";
-
-    // Zones used in the tests. NEW_YORK_TZ and LONDON_TZ chosen because they never overlap but both
-    // have DST.
-    private static final TimeZone NEW_YORK_TZ = TimeZone.getTimeZone("America/New_York");
-    private static final TimeZone LONDON_TZ = TimeZone.getTimeZone("Europe/London");
-    // A zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
-    private static final TimeZone REYKJAVIK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
-    // Another zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for
-    // WHEN_DST.
-    private static final TimeZone UTC_TZ = TimeZone.getTimeZone("Etc/UTC");
-
-    // 22nd July 2017, 13:14:15 UTC (DST time in all the timezones used in these tests that observe
-    // DST).
-    private static final long WHEN_DST = 1500729255000L;
-    // 22nd January 2018, 13:14:15 UTC (non-DST time in all timezones used in these tests).
-    private static final long WHEN_NO_DST = 1516626855000L;
-
-    // The offset applied to most zones during DST.
-    private static final int NORMAL_DST_ADJUSTMENT = HOUR_MILLIS;
-
-    private static final int LONDON_NO_DST_OFFSET_MILLIS = 0;
-    private static final int LONDON_DST_OFFSET_MILLIS = LONDON_NO_DST_OFFSET_MILLIS
-            + NORMAL_DST_ADJUSTMENT;
-
-    private static final int NEW_YORK_NO_DST_OFFSET_MILLIS = -5 * HOUR_MILLIS;
-    private static final int NEW_YORK_DST_OFFSET_MILLIS = NEW_YORK_NO_DST_OFFSET_MILLIS
-            + NORMAL_DST_ADJUSTMENT;
-
-    @Test
-    public void createValidated() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-        assertTrue(countryTimeZones.isForCountryCode("gb"));
-        assertEquals("Europe/London", countryTimeZones.getDefaultTimeZoneId());
-        assertZoneEquals(zone("Europe/London"), countryTimeZones.getDefaultTimeZone());
-        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
-        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
-    }
-
-    @Test
-    public void createValidated_nullDefault() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", null, true /* everUsesUtc */, timeZoneMappings("Europe/London"), "test");
-        assertNull(countryTimeZones.getDefaultTimeZoneId());
-    }
-
-    @Test
-    public void createValidated_invalidDefault() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", INVALID_TZ_ID, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", INVALID_TZ_ID), "test");
-        assertNull(countryTimeZones.getDefaultTimeZoneId());
-        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
-        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
-    }
-
-    @Test
-    public void createValidated_unknownTimeZoneIdIgnored() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Unknown_Id", "Europe/London"), "test");
-        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
-        assertZonesEqual(zones("Europe/London"), countryTimeZones.getIcuTimeZones());
-    }
-
-    @Test
-    public void isForCountryCode() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-        assertTrue(countryTimeZones.isForCountryCode("GB"));
-        assertTrue(countryTimeZones.isForCountryCode("Gb"));
-        assertTrue(countryTimeZones.isForCountryCode("gB"));
-    }
-
-    @Test
-    public void structuresAreImmutable() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-
-        assertImmutableTimeZone(countryTimeZones.getDefaultTimeZone());
-
-        List<TimeZone> tzList = countryTimeZones.getIcuTimeZones();
-        assertEquals(1, tzList.size());
-        assertImmutableList(tzList);
-        assertImmutableTimeZone(tzList.get(0));
-
-        List<TimeZoneMapping> timeZoneMappings = countryTimeZones.getTimeZoneMappings();
-        assertEquals(1, timeZoneMappings.size());
-        assertImmutableList(timeZoneMappings);
-    }
-
-    @Test
-    public void lookupByOffsetWithBiasDeprecated_oneCandidate() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"), "test");
-
-        OffsetResult expectedResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, isDst and time.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        false /* isDst */, WHEN_NO_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and time do not match the configured
-        // zone.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        // A sample of a non-matching case with bias.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it doesn't match any of the country's zones.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-
-        // The bias should still be ignored even though it matches the offset information given:
-        // it doesn't match any of the country's configured zones.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(NEW_YORK_DST_OFFSET_MILLIS,
-                true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    @Test
-    public void lookupByOffsetWithBiasDeprecated_multipleNonOverlappingCandidates()
-            throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("America/New_York", "Europe/London"), "test");
-
-        OffsetResult expectedLondonResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-        OffsetResult expectedNewYorkResult = new OffsetResult(NEW_YORK_TZ, true /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, isDst and time.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
-        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and time do not match the configured
-        // zone. This is a sample, not complete.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        // A sample of a non-matching case with bias.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
-    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
-    @Test
-    public void lookupByOffsetWithBiasDeprecated_multipleOverlappingCandidates() throws Exception {
-        // Three zones that have the same offset for some of the year. Europe/London changes
-        // offset WHEN_DST, the others do not.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"), "test");
-
-        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
-        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
-        // This is the DST offset for LONDON_TZ.
-        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
-
-        OffsetResult expectedLondonOnlyMatch = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-        OffsetResult expectedReykjavikBestMatch =
-                new OffsetResult(REYKJAVIK_TZ, false /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, isDst and when.
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(dstOffset, true /* isDst */, WHEN_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(dstOffset, true /* isDst */, WHEN_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_DST,
-                        null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and time do not match the configured
-        // zones.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
-                true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
-                true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
-                true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
-                false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-
-        // Some bias cases below.
-
-        // Multiple zones match but Reykjavik is the bias.
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
-                        REYKJAVIK_TZ /* bias */));
-
-        // Multiple zones match but London is the bias.
-        OffsetResult expectedLondonBestMatch = new OffsetResult(LONDON_TZ, false /* oneMatch */);
-        assertOffsetResultEquals(expectedLondonBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
-                        LONDON_TZ /* bias */));
-
-        // Multiple zones match but UTC is the bias.
-        OffsetResult expectedUtcResult = new OffsetResult(UTC_TZ, false /* oneMatch */);
-        assertOffsetResultEquals(expectedUtcResult,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, false /* isDst */, WHEN_NO_DST,
-                        UTC_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS, true /* isDst */,
-                        WHEN_DST, REYKJAVIK_TZ /* bias */));
-    }
-
-    @Test
-    public void lookupByOffsetWithBias_oneCandidate() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* uses UTC */, timeZoneMappings("Europe/London"),
-                "test");
-
-        OffsetResult expectedResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, isDst and time.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        0 /* no DST */, WHEN_NO_DST, null /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        null /* unknown DST */, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        null /* unknown DST */, WHEN_NO_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, DST offset and time do not match the
-        // configured zone.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        NORMAL_DST_ADJUSTMENT, WHEN_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        0 /* no DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_NO_DST_OFFSET_MILLIS,
-                        null /* unknown DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        // A sample of a non-matching case with bias.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it doesn't match any of the country's zones.
-        assertOffsetResultEquals(expectedResult,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
-
-        // The bias should still be ignored even though it matches the offset information given:
-        // it doesn't match any of the country's configured zones.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(NEW_YORK_DST_OFFSET_MILLIS,
-                NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    @Test
-    public void lookupByOffsetWithBias_multipleNonOverlappingCandidates()
-            throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* uses UTC */,
-                timeZoneMappings("America/New_York", "Europe/London"), "test");
-
-        OffsetResult expectedLondonResult = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-        OffsetResult expectedNewYorkResult = new OffsetResult(NEW_YORK_TZ, true /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, DST offset and time.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST, null /* bias */));
-        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */));
-        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */));
-        assertOffsetResultEquals(expectedNewYorkResult, countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST,
-                null /* bias */));
-
-        // Some lookup failure cases where the offset, DST offset and time do not match the
-        // configured zone. This is a sample, not complete.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(
-                NEW_YORK_NO_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        OffsetResult noDstMatch5 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        OffsetResult noDstMatch6 = countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, 0 /* no DST */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_NO_DST_OFFSET_MILLIS, null /* unknown DST */, WHEN_NO_DST,
-                LONDON_TZ /* bias */));
-
-        // A sample of a non-matching case with bias.
-        assertNull(countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertOffsetResultEquals(expectedLondonResult, countryTimeZones.lookupByOffsetWithBias(
-                LONDON_DST_OFFSET_MILLIS, NORMAL_DST_ADJUSTMENT, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
-    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
-    @Test
-    public void lookupByOffsetWithBias_multipleOverlappingCandidates() throws Exception {
-        // Three zones that have the same offset for some of the year. Europe/London changes
-        // offset WHEN_DST, the others do not.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* uses UTC */,
-                timeZoneMappings("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"), "test");
-
-        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
-        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
-        // This is the DST offset for LONDON_TZ.
-        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
-
-        OffsetResult expectedLondonOnlyMatch = new OffsetResult(LONDON_TZ, true /* oneMatch */);
-        OffsetResult expectedReykjavikBestMatch =
-                new OffsetResult(REYKJAVIK_TZ, false /* oneMatch */);
-
-        // The three parameters match the configured zone: offset, DST offset and time.
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(dstOffset, NORMAL_DST_ADJUSTMENT, WHEN_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(dstOffset, NORMAL_DST_ADJUSTMENT, WHEN_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_DST,
-                        null /* bias */));
-
-        // Unknown DST cases
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null, WHEN_DST,
-                        null /* bias */));
-        assertNull(countryTimeZones.lookupByOffsetWithBias(dstOffset, null, WHEN_NO_DST,
-                        null /* bias */));
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(dstOffset, null, WHEN_DST,
-                        null /* bias */));
-
-        // Some lookup failure cases where the offset, DST offset and time do not match the
-        // configured zones.
-        OffsetResult noDstMatch1 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
-                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        OffsetResult noDstMatch2 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
-                NORMAL_DST_ADJUSTMENT, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        OffsetResult noDstMatch3 = countryTimeZones.lookupByOffsetWithBias(noDstOffset,
-                NORMAL_DST_ADJUSTMENT, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        OffsetResult noDstMatch4 = countryTimeZones.lookupByOffsetWithBias(dstOffset,
-                0 /* no DST */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-
-        // Some bias cases below.
-
-        // Multiple zones match but Reykjavik is the bias.
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
-                        REYKJAVIK_TZ /* bias */));
-        assertOffsetResultEquals(expectedReykjavikBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
-                        WHEN_NO_DST, REYKJAVIK_TZ /* bias */));
-
-        // Multiple zones match but London is the bias.
-        OffsetResult expectedLondonBestMatch = new OffsetResult(LONDON_TZ, false /* oneMatch */);
-        assertOffsetResultEquals(expectedLondonBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
-                        LONDON_TZ /* bias */));
-        assertOffsetResultEquals(expectedLondonBestMatch,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
-                        WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // Multiple zones match but UTC is the bias.
-        OffsetResult expectedUtcResult = new OffsetResult(UTC_TZ, false /* oneMatch */);
-        assertOffsetResultEquals(expectedUtcResult,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, 0 /* no DST */, WHEN_NO_DST,
-                        UTC_TZ /* bias */));
-        assertOffsetResultEquals(expectedUtcResult,
-                countryTimeZones.lookupByOffsetWithBias(noDstOffset, null /* unknown DST */,
-                        WHEN_NO_DST, UTC_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertOffsetResultEquals(expectedLondonOnlyMatch,
-                countryTimeZones.lookupByOffsetWithBias(LONDON_DST_OFFSET_MILLIS,
-                        NORMAL_DST_ADJUSTMENT, WHEN_DST, REYKJAVIK_TZ /* bias */));
-    }
-
-    @Test
-    public void isDefaultOkForCountryTimeZoneDetection_noZones() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings(), "test");
-        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
-        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
-    }
-
-    @Test
-    public void isDefaultOkForCountryTimeZoneDetection_oneZone() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
-        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
-    }
-
-    @Test
-    public void isDefaultOkForCountryTimeZoneDetection_twoZones_overlap() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", "Etc/UTC"), "test");
-        // Europe/London is the same as UTC in the Winter, so all the zones have the same offset
-        // in Winter, but not in Summer.
-        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
-        assertTrue(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
-    }
-
-    @Test
-    public void isDefaultOkForCountryTimeZoneDetection_twoZones_noOverlap() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", "America/New_York"), "test");
-        // The zones have different offsets all year, so it would never be ok to use the default
-        // zone for the country of "xx".
-        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_DST));
-        assertFalse(countryTimeZones.isDefaultOkForCountryTimeZoneDetection(WHEN_NO_DST));
-    }
-
-    @Test
-    public void hasUtcZone_everUseUtcHintOverridesZoneInformation() {
-        // The country has a single zone. Europe/London uses UTC in Winter.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Etc/UTC", false /* everUsesUtc */, timeZoneMappings("Etc/UTC"), "test");
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    @Test
-    public void hasUtcZone_singleZone() {
-        // The country has a single zone. Europe/London uses UTC in Winter.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    @Test
-    public void hasUtcZone_multipleZonesWithUtc() {
-        // The country has multiple zones. Europe/London uses UTC in Winter.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "America/Los_Angeles", true /* everUsesUtc */,
-                timeZoneMappings("America/Los_Angeles", "America/New_York", "Europe/London"),
-                "test");
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertTrue(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    @Test
-    public void hasUtcZone_multipleZonesWithoutUtc() {
-        // The country has multiple zones, none of which use UTC.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/Paris", false /* everUsesUtc */,
-                timeZoneMappings("America/Los_Angeles", "America/New_York", "Europe/Paris"),
-                "test");
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    @Test
-    public void hasUtcZone_emptyZones() {
-        // The country has no valid zones.
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", INVALID_TZ_ID, false /* everUsesUtc */, timeZoneMappings(INVALID_TZ_ID),
-                "test");
-        assertTrue(countryTimeZones.getTimeZoneMappings().isEmpty());
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    private void assertImmutableTimeZone(TimeZone timeZone) {
-        try {
-            timeZone.setRawOffset(1000);
-            fail();
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-
-    private static <X> void assertImmutableList(List<X> list) {
-        try {
-            list.add(null);
-            fail();
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-
-    private static void assertZoneEquals(TimeZone expected, TimeZone actual) {
-        // TimeZone.equals() only checks the ID, but that's ok for these tests.
-        assertEquals(expected, actual);
-    }
-
-    private static void assertOffsetResultEquals(OffsetResult expected, OffsetResult actual) {
-        assertEquals(expected.mTimeZone.getID(), actual.mTimeZone.getID());
-        assertEquals(expected.mOneMatch, actual.mOneMatch);
-    }
-
-    private static void assertZonesEqual(List<TimeZone> expected, List<TimeZone> actual) {
-        // TimeZone.equals() only checks the ID, but that's ok for these tests.
-        assertEquals(expected, actual);
-    }
-
-    private static TimeZone zone(String id) {
-        return TimeZone.getTimeZone(id);
-    }
-
-    /**
-     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
-     */
-    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
-        return Arrays.stream(timeZoneIds)
-                .map(x -> TimeZoneMapping.createForTests(
-                        x, true /* picker */, null /* notUsedAfter */))
-                .collect(Collectors.toList());
-    }
-
-    private static List<TimeZone> zones(String... ids) {
-        return Arrays.stream(ids).map(TimeZone::getTimeZone).collect(Collectors.toList());
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/CountryZonesFinderTest.java b/luni/src/test/java/libcore/libcore/util/CountryZonesFinderTest.java
deleted file mode 100644
index eca59a0..0000000
--- a/luni/src/test/java/libcore/libcore/util/CountryZonesFinderTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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 org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import libcore.util.CountryTimeZones;
-import libcore.util.CountryTimeZones.TimeZoneMapping;
-import libcore.util.CountryZonesFinder;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.fail;
-
-public class CountryZonesFinderTest {
-
-    private static final CountryTimeZones GB_ZONES = CountryTimeZones.createValidated(
-            "gb", "Europe/London", true, timeZoneMappings("Europe/London"), "test");
-
-    private static final CountryTimeZones IM_ZONES = CountryTimeZones.createValidated(
-            "im", "Europe/London", true, timeZoneMappings("Europe/London"), "test");
-
-    private static final CountryTimeZones FR_ZONES = CountryTimeZones.createValidated(
-            "fr", "Europe/Paris", true, timeZoneMappings("Europe/Paris"), "test");
-
-    private static final CountryTimeZones US_ZONES = CountryTimeZones.createValidated(
-            "us", "America/New_York", true,
-            timeZoneMappings("America/New_York", "America/Los_Angeles"), "test");
-
-    @Test
-    public void lookupAllCountryIsoCodes() throws Exception {
-        CountryZonesFinder countryZonesFinder =
-                CountryZonesFinder.createForTests(list(GB_ZONES, FR_ZONES));
-
-        List<String> isoList = countryZonesFinder.lookupAllCountryIsoCodes();
-        assertEqualsAndImmutable(list(GB_ZONES.getCountryIso(), FR_ZONES.getCountryIso()), isoList);
-    }
-
-    @Test
-    public void lookupAllCountryIsoCodes_empty() throws Exception {
-        CountryZonesFinder countryZonesFinder = CountryZonesFinder.createForTests(list());
-        List<String> isoList = countryZonesFinder.lookupAllCountryIsoCodes();
-        assertEqualsAndImmutable(list(), isoList);
-    }
-
-    @Test
-    public void lookupCountryCodesForZoneId() throws Exception {
-        CountryZonesFinder countryZonesFinder =
-                CountryZonesFinder.createForTests(list(GB_ZONES, IM_ZONES, FR_ZONES, US_ZONES));
-
-        assertEqualsAndImmutable(list(GB_ZONES, IM_ZONES),
-                countryZonesFinder.lookupCountryTimeZonesForZoneId("Europe/London"));
-        assertEqualsAndImmutable(list(US_ZONES),
-                countryZonesFinder.lookupCountryTimeZonesForZoneId("America/New_York"));
-        assertEqualsAndImmutable(list(US_ZONES),
-                countryZonesFinder.lookupCountryTimeZonesForZoneId("America/Los_Angeles"));
-        assertEqualsAndImmutable(list(),
-                countryZonesFinder.lookupCountryTimeZonesForZoneId("DOES_NOT_EXIST"));
-    }
-
-    @Test
-    public void lookupCountryTimeZones() throws Exception {
-        CountryZonesFinder countryZonesFinder =
-                CountryZonesFinder.createForTests(list(GB_ZONES, IM_ZONES, FR_ZONES, US_ZONES));
-        assertSame(GB_ZONES, countryZonesFinder.lookupCountryTimeZones(GB_ZONES.getCountryIso()));
-        assertSame(IM_ZONES, countryZonesFinder.lookupCountryTimeZones(IM_ZONES.getCountryIso()));
-        assertNull(countryZonesFinder.lookupCountryTimeZones("DOES_NOT_EXIST"));
-    }
-
-    private static <X> void assertEqualsAndImmutable(List<X> expected, List<X> actual) {
-        assertEquals(expected, actual);
-        assertImmutableList(actual);
-    }
-
-    private static <X> void assertImmutableList(List<X> list) {
-        try {
-            list.add(null);
-            fail();
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-
-    private static <X> List<X> list(X... values) {
-        return Arrays.asList(values);
-    }
-
-    /**
-     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
-     */
-    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
-        return Arrays.stream(timeZoneIds)
-                .map(x -> TimeZoneMapping.createForTests(
-                        x, true /* picker */, null /* notUsedAfter */))
-                .collect(Collectors.toList());
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
index 978ec37..64128da 100644
--- a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
+++ b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
@@ -29,11 +29,10 @@
     private ClassLoader classLoader = NativeAllocationRegistryTest.class.getClassLoader();
 
     private static class TestConfig {
-        public boolean useAllocator;
+        public boolean treatAsMalloced;
         public boolean shareRegistry;
 
-        public TestConfig(boolean useAllocator, boolean shareRegistry) {
-            this.useAllocator = useAllocator;
+        public TestConfig(boolean treatAsMalloced, boolean shareRegistry) {
             this.shareRegistry = shareRegistry;
         }
     }
@@ -66,57 +65,57 @@
 
         final int nativeSize = size/2;
         int javaSize = size/2;
-        NativeAllocationRegistry registry = new NativeAllocationRegistry(
-                classLoader, getNativeFinalizer(), nativeSize);
+        NativeAllocationRegistry registry = null;
+        int numAllocationsToSimulate = 10 * expectedMaxNumAllocations;
 
         // Allocate more native allocations than will fit in memory. This should
         // not throw OutOfMemoryError because the few allocations we save
         // references to should easily fit.
-        for (int i = 0; i < expectedMaxNumAllocations * 10; i++) {
-            if (!config.shareRegistry) {
-                registry = new NativeAllocationRegistry(
-                    classLoader, getNativeFinalizer(), nativeSize);
+        for (int i = 0; i < numAllocationsToSimulate; i++) {
+            if (!config.shareRegistry || registry == null) {
+                if (config.treatAsMalloced) {
+                    registry = NativeAllocationRegistry.createMalloced(
+                            classLoader, getNativeFinalizer(), nativeSize);
+                } else {
+                    registry = NativeAllocationRegistry.createNonmalloced(
+                            classLoader, getNativeFinalizer(), nativeSize);
+                }
             }
 
             final Allocation alloc = new Allocation();
             alloc.javaAllocation = new byte[javaSize];
-            if (config.useAllocator) {
-                NativeAllocationRegistry.Allocator allocator
-                  = new NativeAllocationRegistry.Allocator() {
-                    public long allocate() {
-                        alloc.nativeAllocation = doNativeAllocation(nativeSize);
-                        return alloc.nativeAllocation;
-                    }
-                };
-                registry.registerNativeAllocation(alloc, allocator);
-            } else {
-                alloc.nativeAllocation = doNativeAllocation(nativeSize);
-                registry.registerNativeAllocation(alloc, alloc.nativeAllocation);
-            }
+            alloc.nativeAllocation = doNativeAllocation(nativeSize);
+            registry.registerNativeAllocation(alloc, alloc.nativeAllocation);
 
             saved[i%numSavedAllocations] = alloc;
         }
 
         // Verify most of the allocations have been freed.
+        // Since we use fairly large Java objects, this doesn't test the GC triggering
+        // effect; we do that elsewhere.
         long nativeBytes = getNumNativeBytesAllocated();
+        long nativeReachableBytes = numSavedAllocations * nativeSize;
         assertTrue("Excessive native bytes still allocated (" + nativeBytes + ")"
                 + " given max memory of (" + max + ")", nativeBytes < 2 * max);
+        assertTrue("Too few native bytes still allocated (" + nativeBytes + "); "
+                + nativeReachableBytes + " bytes are reachable",
+                nativeBytes >= nativeReachableBytes);
     }
 
-    public void testNativeAllocationAllocatorAndSharedRegistry() {
-        testNativeAllocation(new TestConfig(true, true));
+    public void testNativeAllocationNonmallocNoSharedRegistry() {
+        testNativeAllocation(new TestConfig(false, false));
     }
 
-    public void testNativeAllocationNoAllocatorAndSharedRegistry() {
+    public void testNativeAllocationNonmallocSharedRegistry() {
         testNativeAllocation(new TestConfig(false, true));
     }
 
-    public void testNativeAllocationAllocatorAndNoSharedRegistry() {
+    public void testNativeAllocationMallocNoSharedRegistry() {
         testNativeAllocation(new TestConfig(true, false));
     }
 
-    public void testNativeAllocationNoAllocatorAndNoSharedRegistry() {
-        testNativeAllocation(new TestConfig(false, false));
+    public void testNativeAllocationMallocSharedRegistry() {
+        testNativeAllocation(new TestConfig(true, true));
     }
 
     public void testBadSize() {
@@ -175,28 +174,6 @@
                 registry.registerNativeAllocation(referent, 0);
             }
         });
-
-        // referent should not be null
-        assertThrowsIllegalArgumentException(new Runnable() {
-            public void run() {
-                registry.registerNativeAllocation(null,
-                        new NativeAllocationRegistry.Allocator() {
-                            public long allocate() {
-                                // The allocate function ought not to be called.
-                                fail("allocate function called");
-                                return dummyNativePtr;
-                            }
-                        });
-            }
-        });
-
-        // Allocation that returns null should have no effect.
-        assertNull(registry.registerNativeAllocation(referent,
-                    new NativeAllocationRegistry.Allocator() {
-                        public long allocate() {
-                            return 0;
-                        }
-                    }));
     }
 
     private static void assertThrowsIllegalArgumentException(Runnable runnable) {
diff --git a/luni/src/test/java/libcore/libcore/util/TimeZoneDataFilesTest.java b/luni/src/test/java/libcore/libcore/util/TimeZoneDataFilesTest.java
deleted file mode 100644
index 0f118a1..0000000
--- a/luni/src/test/java/libcore/libcore/util/TimeZoneDataFilesTest.java
+++ /dev/null
@@ -1,52 +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.libcore.util;
-
-import org.junit.Test;
-
-import libcore.util.TimeZoneDataFiles;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class TimeZoneDataFilesTest {
-
-    @Test
-    public void getTimeZoneFilePaths() {
-        String[] paths = TimeZoneDataFiles.getTimeZoneFilePaths("foo");
-        assertEquals(2, paths.length);
-
-        assertTrue(paths[0].contains("/misc/zoneinfo/current/"));
-        assertTrue(paths[0].endsWith("foo"));
-
-        assertTrue(paths[1].contains("/usr/share/zoneinfo/"));
-        assertTrue(paths[1].endsWith("foo"));
-    }
-
-    // http://b/34867424
-    @Test
-    public void generateIcuDataPath_includesTimeZoneOverride() {
-        String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
-        assertEquals(icuDataPath, TimeZoneDataFiles.generateIcuDataPath());
-
-        String[] paths = icuDataPath.split(":");
-        assertEquals(2, paths.length);
-
-        assertTrue(paths[0].contains("/misc/zoneinfo/current/icu"));
-        assertTrue(paths[1].contains("/usr/icu"));
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java b/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
deleted file mode 100644
index d3a0e03..0000000
--- a/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
+++ /dev/null
@@ -1,993 +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.libcore.util;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import android.icu.util.TimeZone;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-import libcore.util.CountryTimeZones;
-import libcore.util.CountryTimeZones.TimeZoneMapping;
-import libcore.util.CountryZonesFinder;
-import libcore.util.TimeZoneFinder;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-public class TimeZoneFinderTest {
-
-    private static final int HOUR_MILLIS = 60 * 60 * 1000;
-
-    // Zones used in the tests. NEW_YORK_TZ and LONDON_TZ chosen because they never overlap but both
-    // have DST.
-    private static final TimeZone NEW_YORK_TZ = TimeZone.getTimeZone("America/New_York");
-    private static final TimeZone LONDON_TZ = TimeZone.getTimeZone("Europe/London");
-    // A zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
-    private static final TimeZone REYKJAVIK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
-    // Another zone that matches LONDON_TZ for WHEN_NO_DST. It does not have DST so differs for
-    // WHEN_DST.
-    private static final TimeZone UTC_TZ = TimeZone.getTimeZone("Etc/UTC");
-
-    // 22nd July 2017, 13:14:15 UTC (DST time in all the timezones used in these tests that observe
-    // DST).
-    private static final long WHEN_DST = 1500729255000L;
-    // 22nd January 2018, 13:14:15 UTC (non-DST time in all timezones used in these tests).
-    private static final long WHEN_NO_DST = 1516626855000L;
-
-    private static final int LONDON_DST_OFFSET_MILLIS = HOUR_MILLIS;
-    private static final int LONDON_NO_DST_OFFSET_MILLIS = 0;
-
-    private static final int NEW_YORK_DST_OFFSET_MILLIS = -4 * HOUR_MILLIS;
-    private static final int NEW_YORK_NO_DST_OFFSET_MILLIS = -5 * HOUR_MILLIS;
-
-    private Path testDir;
-
-    @Before
-    public void setUp() throws Exception {
-        testDir = Files.createTempDirectory("TimeZoneFinderTest");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // Delete the testDir and all contents.
-        Files.walkFileTree(testDir, new SimpleFileVisitor<Path>() {
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                    throws IOException {
-                Files.delete(file);
-                return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException exc)
-                    throws IOException {
-                Files.delete(dir);
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-
-    @Test
-    public void createInstanceWithFallback() throws Exception {
-        String validXml1 = "<timezones ianaversion=\"2017c\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n";
-        CountryTimeZones expectedCountryTimeZones1 = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-
-        String validXml2 = "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/Paris\" everutc=\"n\">\n"
-                + "      <id>Europe/Paris</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n";
-        CountryTimeZones expectedCountryTimeZones2 = CountryTimeZones.createValidated(
-                "gb", "Europe/Paris", false /* everUsesUtc */, timeZoneMappings("Europe/Paris"),
-                "test");
-
-        String invalidXml = "<foo></foo>\n";
-        checkValidateThrowsParserException(invalidXml);
-
-        String validFile1 = createFile(validXml1);
-        String validFile2 = createFile(validXml2);
-        String invalidFile = createFile(invalidXml);
-        String missingFile = createMissingFile();
-
-        TimeZoneFinder file1ThenFile2 =
-                TimeZoneFinder.createInstanceWithFallback(validFile1, validFile2);
-        assertEquals("2017c", file1ThenFile2.getIanaVersion());
-        assertEquals(expectedCountryTimeZones1, file1ThenFile2.lookupCountryTimeZones("gb"));
-
-        TimeZoneFinder missingFileThenFile1 =
-                TimeZoneFinder.createInstanceWithFallback(missingFile, validFile1);
-        assertEquals("2017c", missingFileThenFile1.getIanaVersion());
-        assertEquals(expectedCountryTimeZones1, missingFileThenFile1.lookupCountryTimeZones("gb"));
-
-        TimeZoneFinder file2ThenFile1 =
-                TimeZoneFinder.createInstanceWithFallback(validFile2, validFile1);
-        assertEquals("2017b", file2ThenFile1.getIanaVersion());
-        assertEquals(expectedCountryTimeZones2, file2ThenFile1.lookupCountryTimeZones("gb"));
-
-        // We assume the file has been validated so an invalid file is not checked ahead of time.
-        // We will find out when we look something up.
-        TimeZoneFinder invalidThenValid =
-                TimeZoneFinder.createInstanceWithFallback(invalidFile, validFile1);
-        assertNull(invalidThenValid.getIanaVersion());
-        assertNull(invalidThenValid.lookupCountryTimeZones("gb"));
-
-        // This is not a normal case: It would imply a define shipped without a file in /system!
-        TimeZoneFinder missingFiles =
-                TimeZoneFinder.createInstanceWithFallback(missingFile, missingFile);
-        assertNull(missingFiles.getIanaVersion());
-        assertNull(missingFiles.lookupCountryTimeZones("gb"));
-    }
-
-    @Test
-    public void xmlParsing_emptyFile() throws Exception {
-        checkValidateThrowsParserException("");
-    }
-
-    @Test
-    public void xmlParsing_unexpectedRootElement() throws Exception {
-        checkValidateThrowsParserException("<foo></foo>\n");
-    }
-
-    @Test
-    public void xmlParsing_missingCountryZones() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\"></timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_noCountriesOk() throws Exception {
-        validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_unexpectedComments() throws Exception {
-        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <!-- This is a comment -->"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        // This is a crazy comment, but also helps prove that TEXT nodes are coalesced by the
-        // parser.
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/<!-- Don't freak out! -->London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-    }
-
-    @Test
-    public void xmlParsing_unexpectedElementsIgnored() throws Exception {
-        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-
-        String unexpectedElement = "<unexpected-element>\n<a /></unexpected-element>\n";
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  " + unexpectedElement
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    " + unexpectedElement
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      " + unexpectedElement
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "    " + unexpectedElement
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        // This test is important because it ensures we can extend the format in future with
-        // more information.
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "  " + unexpectedElement
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", "Europe/Paris"), "test");
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "      " + unexpectedElement
-                + "      <id>Europe/Paris</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-    }
-
-    @Test
-    public void xmlParsing_unexpectedTextIgnored() throws Exception {
-        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-
-        String unexpectedText = "unexpected-text";
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  " + unexpectedText
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    " + unexpectedText
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      " + unexpectedText
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-
-        expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", "Europe/Paris"), "test");
-        finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "      " + unexpectedText
-                + "      <id>Europe/Paris</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-    }
-
-    @Test
-    public void xmlParsing_truncatedInput() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n");
-
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n");
-
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n");
-
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n");
-
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n");
-
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n");
-    }
-
-    @Test
-    public void xmlParsing_unexpectedChildInTimeZoneIdThrows() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id><unexpected-element /></id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_unknownTimeZoneIdIgnored() throws Exception {
-        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", true /* everUsesUtc */, timeZoneMappings("Europe/London"),
-                "test");
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Unknown_Id</id>\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-    }
-
-    @Test
-    public void xmlParsing_missingCountryCode() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_missingCountryEverUtc() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_badCountryEverUtc() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"occasionally\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_missingCountryDefault() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_badTimeZoneMappingPicker() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id picker=\"sometimes\">Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_timeZoneMappingPicker() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"us\" default=\"America/New_York\" everutc=\"n\">\n"
-                + "      <!-- Explicit picker=\"y\" -->\n"
-                + "      <id picker=\"y\">America/New_York</id>\n"
-                + "      <!-- Implicit picker=\"y\" -->\n"
-                + "      <id>America/Los_Angeles</id>\n"
-                + "      <!-- Explicit picker=\"n\" -->\n"
-                + "      <id picker=\"n\">America/Indiana/Vincennes</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        CountryTimeZones usTimeZones = finder.lookupCountryTimeZones("us");
-        List<TimeZoneMapping> actualTimeZoneMappings = usTimeZones.getTimeZoneMappings();
-        List<TimeZoneMapping> expectedTimeZoneMappings = list(
-                TimeZoneMapping.createForTests(
-                        "America/New_York", true /* shownInPicker */, null /* notUsedAfter */),
-                TimeZoneMapping.createForTests(
-                        "America/Los_Angeles", true /* shownInPicker */, null /* notUsedAfter */),
-                TimeZoneMapping.createForTests(
-                        "America/Indiana/Vincennes", false /* shownInPicker */,
-                        null /* notUsedAfter */)
-        );
-        assertEquals(expectedTimeZoneMappings, actualTimeZoneMappings);
-    }
-
-    @Test
-    public void xmlParsing_badTimeZoneMappingNotAfter() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id notafter=\"sometimes\">Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_timeZoneMappingNotAfter() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"us\" default=\"America/New_York\" everutc=\"n\">\n"
-                + "      <!-- Explicit notafter -->\n"
-                + "      <id notafter=\"1234\">America/New_York</id>\n"
-                + "      <!-- Missing notafter -->\n"
-                + "      <id>America/Indiana/Vincennes</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        CountryTimeZones usTimeZones = finder.lookupCountryTimeZones("us");
-        List<TimeZoneMapping> actualTimeZoneMappings = usTimeZones.getTimeZoneMappings();
-        List<TimeZoneMapping> expectedTimeZoneMappings = list(
-                TimeZoneMapping.createForTests(
-                        "America/New_York", true /* shownInPicker */, 1234L /* notUsedAfter */),
-                TimeZoneMapping.createForTests(
-                        "America/Indiana/Vincennes", true /* shownInPicker */,
-                        null /* notUsedAfter */)
-        );
-        assertEquals(expectedTimeZoneMappings, actualTimeZoneMappings);
-    }
-
-    @Test
-    public void xmlParsing_unknownCountryReturnsNull() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertNull(finder.lookupTimeZoneIdsByCountry("gb"));
-        assertNull(finder.lookupTimeZonesByCountry("gb"));
-    }
-
-    @Test
-    public void getCountryZonesFinder() throws Exception {
-        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
-                "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "    <country code=\"fr\" default=\"Europe/Paris\" everutc=\"y\">\n"
-                + "      <id>Europe/Paris</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        CountryTimeZones expectedGb = CountryTimeZones.createValidated("gb", "Europe/London", true,
-                timeZoneMappings("Europe/London"), "test");
-        CountryTimeZones expectedFr = CountryTimeZones.createValidated("fr", "Europe/Paris", true,
-                timeZoneMappings("Europe/Paris"), "test");
-        CountryZonesFinder countryZonesFinder = timeZoneFinder.getCountryZonesFinder();
-        assertEquals(list("gb", "fr"), countryZonesFinder.lookupAllCountryIsoCodes());
-        assertEquals(expectedGb, countryZonesFinder.lookupCountryTimeZones("gb"));
-        assertEquals(expectedFr, countryZonesFinder.lookupCountryTimeZones("fr"));
-        assertNull(countryZonesFinder.lookupCountryTimeZones("DOES_NOT_EXIST"));
-    }
-
-    @Test
-    public void getCountryZonesFinder_empty() throws Exception {
-        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
-                "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        CountryZonesFinder countryZonesFinder = timeZoneFinder.getCountryZonesFinder();
-        assertEquals(list(), countryZonesFinder.lookupAllCountryIsoCodes());
-    }
-
-    @Test
-    public void getCountryZonesFinder_invalid() throws Exception {
-        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(
-                "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "    <!-- Missing required attributes! -->\n"
-                + "    <country code=\"fr\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertNull(timeZoneFinder.getCountryZonesFinder());
-    }
-
-    @Test
-    public void lookupTimeZonesByCountry_structuresAreImmutable() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        List<TimeZone> gbList = finder.lookupTimeZonesByCountry("gb");
-        assertEquals(1, gbList.size());
-        assertImmutableList(gbList);
-        assertImmutableTimeZone(gbList.get(0));
-
-        // Check country code normalization works too.
-        assertEquals(1, finder.lookupTimeZonesByCountry("GB").size());
-
-        assertNull(finder.lookupTimeZonesByCountry("unknown"));
-    }
-
-    @Test
-    public void lookupTimeZoneIdsByCountry_structuresAreImmutable() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        List<String> gbList = finder.lookupTimeZoneIdsByCountry("gb");
-        assertEquals(1, gbList.size());
-        assertImmutableList(gbList);
-
-        // Check country code normalization works too.
-        assertEquals(1, finder.lookupTimeZoneIdsByCountry("GB").size());
-
-        assertNull(finder.lookupTimeZoneIdsByCountry("unknown"));
-    }
-
-    @Test
-    public void lookupDefaultTimeZoneIdByCountry() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("gb"));
-
-        // Check country code normalization works too.
-        assertEquals("Europe/London", finder.lookupDefaultTimeZoneIdByCountry("GB"));
-    }
-
-    /**
-     * At runtime we don't validate too much since there's nothing we can do if the data is
-     * incorrect.
-     */
-    @Test
-    public void lookupDefaultTimeZoneIdByCountry_notCountryTimeZoneButValid() throws Exception {
-        String xml = "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"America/New_York\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n";
-        // validate() should fail because America/New_York is not one of the "gb" zones listed.
-        checkValidateThrowsParserException(xml);
-
-        // But it should still work at runtime.
-        TimeZoneFinder finder = TimeZoneFinder.createInstanceForTests(xml);
-        assertEquals("America/New_York", finder.lookupDefaultTimeZoneIdByCountry("gb"));
-    }
-
-    @Test
-    public void lookupDefaultTimeZoneIdByCountry_invalidDefault() throws Exception {
-        String xml = "<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Moon/Tranquility_Base\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "      <id>Moon/Tranquility_Base</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n";
-        // validate() should pass because the IDs all match.
-        TimeZoneFinder finder = validate(xml);
-
-        // But "Moon/Tranquility_Base" is not a valid time zone ID so should not be used.
-        assertNull(finder.lookupDefaultTimeZoneIdByCountry("gb"));
-    }
-
-    @Test
-    public void lookupTimeZoneByCountryAndOffset_unknownCountry() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        // Demonstrate the arguments work for a known country.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, null /* bias */));
-
-        // Check country code normalization works too.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("XX", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, null /* bias */));
-
-        // Test with an unknown country.
-        String unknownCountryCode = "yy";
-        assertNull(finder.lookupTimeZoneByCountryAndOffset(unknownCountryCode,
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
-
-        assertNull(finder.lookupTimeZoneByCountryAndOffset(unknownCountryCode,
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
-    }
-
-    @Test
-    public void lookupTimeZoneByCountryAndOffset_oneCandidate() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        // The three parameters match the configured zone: offset, isDst and when.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, null /* bias */));
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
-                        false /* isDst */, WHEN_NO_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and when do not match the configured
-        // zone.
-        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        TimeZone noDstMatch5 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        TimeZone noDstMatch6 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
-                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        // A sample of a non-matching case with bias.
-        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it doesn't match any of the country's zones.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-
-        // The bias should still be ignored even though it matches the offset information given:
-        // it doesn't match any of the country's configured zones.
-        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", NEW_YORK_DST_OFFSET_MILLIS,
-                true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    @Test
-    public void lookupTimeZoneByCountryAndOffset_multipleNonOverlappingCandidates()
-            throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>America/New_York</id>\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        // The three parameters match the configured zone: offset, isDst and when.
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
-        assertZoneEquals(NEW_YORK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
-                NEW_YORK_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */));
-        assertZoneEquals(NEW_YORK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
-                NEW_YORK_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and when do not match the configured
-        // zone. This is a sample, not complete.
-        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                NEW_YORK_NO_DST_OFFSET_MILLIS, true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-        TimeZone noDstMatch5 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch5);
-
-        TimeZone noDstMatch6 = finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_NO_DST_OFFSET_MILLIS, false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch6);
-
-        // Some bias cases below.
-
-        // The bias is irrelevant here: it matches what would be returned anyway.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, LONDON_TZ /* bias */));
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_NO_DST_OFFSET_MILLIS,
-                        false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        // A sample of a non-matching case with bias.
-        assertNull(finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                true /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertZoneEquals(LONDON_TZ,
-                finder.lookupTimeZoneByCountryAndOffset("xx", LONDON_DST_OFFSET_MILLIS,
-                        true /* isDst */, WHEN_DST, NEW_YORK_TZ /* bias */));
-    }
-
-    // This is an artificial case very similar to America/Denver and America/Phoenix in the US: both
-    // have the same offset for 6 months of the year but diverge. Australia/Lord_Howe too.
-    @Test
-    public void lookupTimeZoneByCountryAndOffset_multipleOverlappingCandidates() throws Exception {
-        // Three zones that have the same offset for some of the year. Europe/London changes
-        // offset WHEN_DST, the others do not.
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"xx\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Atlantic/Reykjavik</id>\n"
-                + "      <id>Europe/London</id>\n"
-                + "      <id>Etc/UTC</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-
-        // This is the no-DST offset for LONDON_TZ, REYKJAVIK_TZ. UTC_TZ.
-        final int noDstOffset = LONDON_NO_DST_OFFSET_MILLIS;
-        // This is the DST offset for LONDON_TZ.
-        final int dstOffset = LONDON_DST_OFFSET_MILLIS;
-
-        // The three parameters match the configured zone: offset, isDst and when.
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
-                true /* isDst */, WHEN_DST, null /* bias */));
-        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_NO_DST, null /* bias */));
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
-                true /* isDst */, WHEN_DST, null /* bias */));
-        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_NO_DST, null /* bias */));
-        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_DST, null /* bias */));
-
-        // Some lookup failure cases where the offset, isDst and when do not match the configured
-        // zones.
-        TimeZone noDstMatch1 = finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
-                true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch1);
-
-        TimeZone noDstMatch2 = finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                true /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch2);
-
-        TimeZone noDstMatch3 = finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                true /* isDst */, WHEN_NO_DST, null /* bias */);
-        assertNull(noDstMatch3);
-
-        TimeZone noDstMatch4 = finder.lookupTimeZoneByCountryAndOffset("xx", dstOffset,
-                false /* isDst */, WHEN_DST, null /* bias */);
-        assertNull(noDstMatch4);
-
-
-        // Some bias cases below.
-
-        // The bias is relevant here: it overrides what would be returned naturally.
-        assertZoneEquals(REYKJAVIK_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_NO_DST, null /* bias */));
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_NO_DST, LONDON_TZ /* bias */));
-        assertZoneEquals(UTC_TZ, finder.lookupTimeZoneByCountryAndOffset("xx", noDstOffset,
-                false /* isDst */, WHEN_NO_DST, UTC_TZ /* bias */));
-
-        // The bias should be ignored: it matches a configured zone, but the offset is wrong so
-        // should not be considered a match.
-        assertZoneEquals(LONDON_TZ, finder.lookupTimeZoneByCountryAndOffset("xx",
-                LONDON_DST_OFFSET_MILLIS, true /* isDst */, WHEN_DST, REYKJAVIK_TZ /* bias */));
-    }
-
-    @Test
-    public void xmlParsing_missingIanaVersionAttribute() throws Exception {
-        // The <timezones> element will typically have an ianaversion attribute, but it's not
-        // required for parsing.
-        TimeZoneFinder finder = validate("<timezones>\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(list("Europe/London"), finder.lookupTimeZoneIdsByCountry("gb"));
-
-        assertNull(finder.getIanaVersion());
-    }
-
-    @Test
-    public void getIanaVersion() throws Exception {
-        final String expectedIanaVersion = "2017b";
-
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"" + expectedIanaVersion + "\">\n"
-                + "  <countryzones>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertEquals(expectedIanaVersion, finder.getIanaVersion());
-    }
-
-    private static void assertImmutableTimeZone(TimeZone timeZone) {
-        try {
-            timeZone.setRawOffset(1000);
-            fail();
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-
-    private static <X> void assertImmutableList(List<X> list) {
-        try {
-            list.add(null);
-            fail();
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-
-    private static void assertZoneEquals(TimeZone expected, TimeZone actual) {
-        // TimeZone.equals() only checks the ID, but that's ok for these tests.
-        assertEquals(expected, actual);
-    }
-
-    private static void checkValidateThrowsParserException(String xml) {
-        try {
-            validate(xml);
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    private static TimeZoneFinder validate(String xml) throws IOException {
-        TimeZoneFinder timeZoneFinder = TimeZoneFinder.createInstanceForTests(xml);
-        timeZoneFinder.validate();
-        return timeZoneFinder;
-    }
-
-    /**
-     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
-     */
-    private static List<TimeZoneMapping> timeZoneMappings(String... timeZoneIds) {
-        return Arrays.stream(timeZoneIds)
-                .map(x -> TimeZoneMapping.createForTests(
-                        x, true /* showInPicker */, null /* notUsedAfter */))
-                .collect(Collectors.toList());
-    }
-
-    private static <X> List<X> list(X... values) {
-        return Arrays.asList(values);
-    }
-
-    private static <X> List<X> sort(Collection<X> value) {
-        return value.stream().sorted()
-                .collect(Collectors.toList());
-    }
-
-    private String createFile(String fileContent) throws IOException {
-        Path filePath = Files.createTempFile(testDir, null, null);
-        Files.write(filePath, fileContent.getBytes(StandardCharsets.UTF_8));
-        return filePath.toString();
-    }
-
-    private String createMissingFile() throws IOException {
-        Path filePath = Files.createTempFile(testDir, null, null);
-        Files.delete(filePath);
-        return filePath.toString();
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/libcore/util/ZoneInfoDBTest.java
deleted file mode 100644
index c394fcb..0000000
--- a/luni/src/test/java/libcore/libcore/util/ZoneInfoDBTest.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2013 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 java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-import libcore.tzdata.testing.ZoneInfoTestHelper;
-import libcore.util.TimeZoneDataFiles;
-import libcore.util.ZoneInfo;
-import libcore.util.ZoneInfoDB;
-
-import static libcore.util.ZoneInfoDB.TzData.SIZEOF_INDEX_ENTRY;
-
-public class ZoneInfoDBTest extends junit.framework.TestCase {
-
-  // The base tzdata file, always present on a device.
-  private static final String SYSTEM_TZDATA_FILE =
-      TimeZoneDataFiles.getSystemTimeZoneFile(ZoneInfoDB.TZDATA_FILE);
-
-  // An empty override file should fall back to the default file.
-  public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
-    String emptyFilePath = makeEmptyFile().getPath();
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
-         ZoneInfoDB.TzData dataWithEmptyOverride =
-                 ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, SYSTEM_TZDATA_FILE)) {
-      assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
-      assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
-    }
-  }
-
-  // A corrupt override file should fall back to the default file.
-  public void testLoadTzDataWithFallback_corruptOverrideFile() throws Exception {
-    String corruptFilePath = makeCorruptFile().getPath();
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
-         ZoneInfoDB.TzData dataWithCorruptOverride =
-                 ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, SYSTEM_TZDATA_FILE)) {
-      assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
-      assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
-    }
-  }
-
-  // Given no tzdata files we can use, we should fall back to built-in "GMT".
-  public void testLoadTzDataWithFallback_noGoodFile() throws Exception {
-    String emptyFilePath = makeEmptyFile().getPath();
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath)) {
-      assertEquals("missing", data.getVersion());
-      assertEquals(1, data.getAvailableIDs().length);
-      assertEquals("GMT", data.getAvailableIDs()[0]);
-    }
-  }
-
-  // Given a valid override file, we should find ourselves using that.
-  public void testLoadTzDataWithFallback_goodOverrideFile() throws Exception {
-    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
-    byte[] content = new byte[(int) in.length()];
-    in.readFully(content);
-    in.close();
-
-    // Bump the version number to one long past where humans will be extinct.
-    content[6] = '9';
-    content[7] = '9';
-    content[8] = '9';
-    content[9] = '9';
-    content[10] = 'z';
-
-    File goodFile = makeTemporaryFile(content);
-    try (ZoneInfoDB.TzData dataWithOverride =
-              ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), SYSTEM_TZDATA_FILE);
-         ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
-
-      assertEquals("9999z", dataWithOverride.getVersion());
-      assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
-    } finally {
-      goodFile.delete();
-    }
-  }
-
-  public void testLoadTzData_badHeader() throws Exception {
-    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
-    byte[] content = new byte[(int) in.length()];
-    in.readFully(content);
-    in.close();
-
-    // Break the header.
-    content[0] = 'a';
-    checkInvalidDataDetected(content);
-  }
-
-  public void testLoadTzData_validTestData() throws Exception {
-    byte[] data = new ZoneInfoTestHelper.TzDataBuilder().initializeToValid().build();
-    File testFile = makeTemporaryFile(data);
-    try {
-      assertNotNull(ZoneInfoDB.TzData.loadTzData(testFile.getPath()));
-    } finally {
-      testFile.delete();
-    }
-  }
-
-  public void testLoadTzData_invalidOffsets() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-
-    // Sections must be in the correct order: section sizing is calculated using them.
-    builder.setIndexOffsetOverride(10);
-    builder.setDataOffsetOverride(30);
-
-    byte[] data = builder.build();
-    // The offsets must all be under the total size of the file for this test to be valid.
-    assertTrue(30 < data.length);
-    checkInvalidDataDetected(data);
-  }
-
-  public void testLoadTzData_zoneTabOutsideFile() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder()
-                    .initializeToValid();
-
-    // Sections must be in the correct order: section sizing is calculated using them.
-    builder.setIndexOffsetOverride(10);
-    builder.setDataOffsetOverride(10 + SIZEOF_INDEX_ENTRY);
-    builder.setZoneTabOffsetOverride(3000); // This is invalid if it is outside of the file.
-
-    byte[] data = builder.build();
-    // The zoneTab offset must be outside of the file for this test to be valid.
-    assertTrue(3000 > data.length);
-    checkInvalidDataDetected(data);
-  }
-
-  public void testLoadTzData_nonDivisibleIndex() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-
-    // Sections must be in the correct order: section sizing is calculated using them.
-    int indexOffset = 10;
-    builder.setIndexOffsetOverride(indexOffset);
-    int dataOffset = indexOffset + ZoneInfoDB.TzData.SIZEOF_INDEX_ENTRY - 1;
-    builder.setDataOffsetOverride(dataOffset);
-    builder.setZoneTabOffsetOverride(dataOffset + 40);
-
-    byte[] data = builder.build();
-    // The zoneTab offset must be outside of the file for this test to be valid.
-    assertTrue(3000 > data.length);
-    checkInvalidDataDetected(data);
-  }
-
-  public void testLoadTzData_badId() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-    builder.clearZicData();
-    byte[] validZicData =
-            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
-    builder.addZicData("", validZicData); // "" is an invalid ID
-
-    checkInvalidDataDetected(builder.build());
-  }
-
-  public void testLoadTzData_badIdOrder() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-    builder.clearZicData();
-    byte[] validZicData =
-            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
-    builder.addZicData("Europe/Zurich", validZicData);
-    builder.addZicData("Europe/London", validZicData);
-
-    checkInvalidDataDetected(builder.build());
-  }
-
-  public void testLoadTzData_duplicateId() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-    builder.clearZicData();
-    byte[] validZicData =
-            new ZoneInfoTestHelper.ZicDataBuilder().initializeToValid().build();
-    builder.addZicData("Europe/London", validZicData);
-    builder.addZicData("Europe/London", validZicData);
-
-    checkInvalidDataDetected(builder.build());
-  }
-
-  public void testLoadTzData_badZicLength() throws Exception {
-    ZoneInfoTestHelper.TzDataBuilder builder =
-            new ZoneInfoTestHelper.TzDataBuilder().initializeToValid();
-    builder.clearZicData();
-    byte[] invalidZicData = "This is too short".getBytes();
-    builder.addZicData("Europe/London", invalidZicData);
-
-    checkInvalidDataDetected(builder.build());
-  }
-
-  private static void checkInvalidDataDetected(byte[] data) throws Exception {
-    File testFile = makeTemporaryFile(data);
-    try {
-      assertNull(ZoneInfoDB.TzData.loadTzData(testFile.getPath()));
-    } finally {
-      testFile.delete();
-    }
-  }
-
-  // Confirms any caching that exists correctly handles TimeZone mutability.
-  public void testMakeTimeZone_timeZoneMutability() throws Exception {
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
-      String tzId = "Europe/London";
-      ZoneInfo first = data.makeTimeZone(tzId);
-      ZoneInfo second = data.makeTimeZone(tzId);
-      assertNotSame(first, second);
-
-      assertTrue(first.hasSameRules(second));
-
-      first.setID("Not Europe/London");
-
-      assertFalse(first.getID().equals(second.getID()));
-
-      first.setRawOffset(3600);
-      assertFalse(first.getRawOffset() == second.getRawOffset());
-    }
-  }
-
-  public void testMakeTimeZone_notFound() throws Exception {
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
-      assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
-      assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST"));
-    }
-  }
-
-  public void testMakeTimeZone_found() throws Exception {
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
-      assertNotNull(data.makeTimeZone("Europe/London"));
-      assertTrue(data.hasTimeZone("Europe/London"));
-    }
-  }
-
-  public void testGetRulesVersion() throws Exception {
-    try (ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE)) {
-      String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(SYSTEM_TZDATA_FILE));
-      assertEquals(data.getVersion(), rulesVersion);
-    }
-  }
-
-  public void testGetRulesVersion_corruptFile() throws Exception {
-    File corruptFilePath = makeCorruptFile();
-    try {
-      ZoneInfoDB.TzData.getRulesVersion(corruptFilePath);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  public void testGetRulesVersion_emptyFile() throws Exception {
-    File emptyFilePath = makeEmptyFile();
-    try {
-      ZoneInfoDB.TzData.getRulesVersion(emptyFilePath);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  public void testGetRulesVersion_missingFile() throws Exception {
-    File missingFile = makeMissingFile();
-    try {
-      ZoneInfoDB.TzData.getRulesVersion(missingFile);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  private static File makeMissingFile() throws Exception {
-    File file = File.createTempFile("temp-", ".txt");
-    assertTrue(file.delete());
-    assertFalse(file.exists());
-    return file;
-  }
-
-  private static File makeCorruptFile() throws Exception {
-    return makeTemporaryFile("invalid content".getBytes());
-  }
-
-  private static File makeEmptyFile() throws Exception {
-    return makeTemporaryFile(new byte[0]);
-  }
-
-  private static File makeTemporaryFile(byte[] content) throws Exception {
-    File f = File.createTempFile("temp-", ".txt");
-    FileOutputStream fos = new FileOutputStream(f);
-    fos.write(content);
-    fos.close();
-    return f;
-  }
-}
diff --git a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
index e7761a2..cddf41b 100644
--- a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
+++ b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
@@ -21,12 +21,14 @@
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.nio.ByteBuffer;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.Date;
 import libcore.io.BufferIterator;
-import libcore.tzdata.testing.ZoneInfoTestHelper;
+import libcore.timezone.ZoneInfoDB;
+import libcore.timezone.testing.ZoneInfoTestHelper;
 import libcore.util.ZoneInfo;
-import libcore.util.ZoneInfoDB;
 
 /**
  * Tests for {@link ZoneInfo}
@@ -57,16 +59,19 @@
     ZoneInfo zoneInfo = createZoneInfo(transitions, types);
 
     // If there are no transitions then the offset should be constant irrespective of the time.
-    assertEquals(secondsInMillis(4800), zoneInfo.getOffset(Long.MIN_VALUE));
-    assertEquals(secondsInMillis(4800), zoneInfo.getOffset(0));
-    assertEquals(secondsInMillis(4800), zoneInfo.getOffset(Long.MAX_VALUE));
+    Instant[] times = {
+            Instant.ofEpochMilli(Long.MIN_VALUE),
+            Instant.ofEpochMilli(0),
+            Instant.ofEpochMilli(Long.MAX_VALUE),
+    };
+    assertOffsetAt(zoneInfo, offsetFromSeconds(4800), times);
 
     // No transitions means no DST.
     assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
 
     // The raw offset should be the offset of the first type.
-    assertEquals(secondsInMillis(4800), zoneInfo.getRawOffset());
+    assertRawOffset(zoneInfo, offsetFromSeconds(4800));
   }
 
   /**
@@ -82,16 +87,15 @@
     ZoneInfo zoneInfo = createZoneInfo(transitions, types);
 
     // Any time before the first transition is assumed to use the first standard transition.
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(-2)));
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(0));
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(2)));
+    Instant[] times = { timeFromSeconds(-2), timeFromSeconds(0), timeFromSeconds(2) };
+    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), times);
 
     // No transitions means no DST.
     assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
 
     // The raw offset should be the offset of the first type.
-    assertEquals(secondsInMillis(3600), zoneInfo.getRawOffset());
+    assertRawOffset(zoneInfo, offsetFromSeconds(3600));
   }
 
   /**
@@ -127,22 +131,25 @@
         { 5400, 0 }
     };
     ZoneInfo zoneInfo = createZoneInfo(transitions, types);
+    Instant transitionTime = timeFromSeconds(-5);
 
     // Even a millisecond before a transition means that the transition is not active.
-    assertEquals(1800000, zoneInfo.getOffset(secondsInMillis(-5) - 1));
-    assertFalse(zoneInfo.inDaylightTime(new Date(secondsInMillis(-5) - 1)));
+    Instant beforeTransitionTime = transitionTime.minusMillis(1);
+    assertOffsetAt(zoneInfo, offsetFromSeconds(1800), beforeTransitionTime);
+    assertInDaylightTime(zoneInfo, beforeTransitionTime, false);
 
     // A time equal to the transition point activates the transition.
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(-5)));
-    assertTrue(zoneInfo.inDaylightTime(new Date(secondsInMillis(-5))));
+    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), transitionTime);
+    assertInDaylightTime(zoneInfo, transitionTime, true);
 
     // A time after the transition point but before the next activates the transition.
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(-5) + 1));
-    assertTrue(zoneInfo.inDaylightTime(new Date(secondsInMillis(-5) + 1)));
+    Instant afterTransitionTime = transitionTime.plusMillis(1);
+    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), afterTransitionTime);
+    assertInDaylightTime(zoneInfo, afterTransitionTime, true);
 
     assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
-    assertEquals(secondsInMillis(5400), zoneInfo.getRawOffset());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
+    assertRawOffset(zoneInfo, offsetFromSeconds(5400));
   }
 
   /**
@@ -162,21 +169,25 @@
     };
     ZoneInfo zoneInfo = createZoneInfo(transitions, types);
 
+    Instant transitionTime = timeFromSeconds(5);
+
     // Even a millisecond before a transition means that the transition is not active.
-    assertEquals(secondsInMillis(1800), zoneInfo.getOffset(secondsInMillis(5) - 1));
-    assertFalse(zoneInfo.inDaylightTime(new Date(secondsInMillis(5) - 1)));
+    Instant beforeTransitionTime = transitionTime.minusMillis(1);
+    assertOffsetAt(zoneInfo, offsetFromSeconds(1800), beforeTransitionTime);
+    assertInDaylightTime(zoneInfo, beforeTransitionTime, false);
 
     // A time equal to the transition point activates the transition.
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(5)));
-    assertTrue(zoneInfo.inDaylightTime(new Date(secondsInMillis(5))));
+    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), transitionTime);
+    assertInDaylightTime(zoneInfo, transitionTime, true);
 
     // A time after the transition point but before the next activates the transition.
-    assertEquals(secondsInMillis(3600), zoneInfo.getOffset(secondsInMillis(5) + 1));
-    assertTrue(zoneInfo.inDaylightTime(new Date(secondsInMillis(5) + 1)));
+    Instant afterTransitionTime = transitionTime.plusMillis(1);
+    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), afterTransitionTime);
+    assertInDaylightTime(zoneInfo, afterTransitionTime, true);
 
     assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
-    assertEquals(secondsInMillis(5400), zoneInfo.getRawOffset());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
+    assertRawOffset(zoneInfo, offsetFromSeconds(5400));
   }
 
   /**
@@ -197,19 +208,19 @@
     // The expected DST savings is the difference between the DST offset (which includes the
     // raw offset) and the preceding non-DST offset (which should just be the raw offset).
     // Or in other words (5400 - 3600) * 1000
-    int expectedDSTSavings = secondsInMillis(5400 - 3600);
+    Duration expectedDSTSavings = offsetFromSeconds(5400 - 3600);
 
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, secondsInMillis(-700));
+    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-700));
 
     assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertEquals(expectedDSTSavings, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, expectedDSTSavings);
 
     // Now create one a few milliseconds before the DST transition to make sure that rounding
     // errors don't cause a problem.
-    zoneInfo = createZoneInfo(transitions, types, secondsInMillis(-100) - 5);
+    zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-100).minusMillis(5));
 
     assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertEquals(expectedDSTSavings, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, expectedDSTSavings);
   }
 
   /**
@@ -230,20 +241,19 @@
     // The expected DST savings is the difference between the DST offset (which includes the
     // raw offset) and the preceding non-DST offset (which should just be the raw offset).
     // Or in other words (7200 - 3600) * 1000
-    int expectedDSTSavings = secondsInMillis(7200 - 3600);
+    Duration expectedDSTSavings = offsetFromSeconds(7200 - 3600);
 
-    ZoneInfo zoneInfo = createZoneInfo(
-            transitions, types, secondsInMillis(4500) /* currentTimeMillis */);
+    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(4500) /* currentTime */);
 
     assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertEquals(expectedDSTSavings, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, expectedDSTSavings);
 
     // Now create one a few milliseconds before the DST transition to make sure that rounding
     // errors don't cause a problem.
-    zoneInfo = createZoneInfo(transitions, types, secondsInMillis(6000) - 5);
+    zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(6000).minusMillis(5));
 
     assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertEquals(expectedDSTSavings, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, expectedDSTSavings);
   }
 
   /**
@@ -262,18 +272,17 @@
         { 1800, 1 },
         { 5400, 0 }
     };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types,
-            secondsInMillis(-1) /* currentTimeMillis */);
+    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-1) /* currentTime */);
 
     assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
 
     // Now create one a few milliseconds after the DST transition to make sure that rounding
     // errors don't cause a problem.
-    zoneInfo = createZoneInfo(transitions, types, secondsInMillis(-2000) + 5);
+    zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-2000).plusMillis(5));
 
     assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
   }
 
   /**
@@ -292,17 +301,146 @@
         { 1800, 1 },
         { 5400, 0 }
     };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, secondsInMillis(4700));
+    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(4700));
 
     assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
 
     // Now create one a few milliseconds after the DST transition to make sure that rounding
     // errors don't cause a problem.
-    zoneInfo = createZoneInfo(transitions, types, secondsInMillis(4000) + 5);
+    zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(4000).plusMillis(5));
 
     assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
+  }
+
+  /**
+   * TimeZone APIs use long times in millis. Android uses TZif version 1 format data which
+   * uses 32-bit time values for transitions so it only gives accurate results for times in that
+   * range.
+   *
+   * <p>Newer versions of zic after 2014b introduce an explicit transition at the earliest
+   * representable time, which is Integer.MIN_VALUE for TZif version 1 files. Previously the type
+   * used was left implicit and readers were expected to use the first non-DST type in the file.
+   * This extra transition mostly went away again with zic 2018f.
+   *
+   * <p>Testing newer zic versions demonstrated that Android had been mishandling the lookup of
+   * offset for times before the first transition. The logic has been corrected. This test would
+   * fail on versions of Android <= P.
+   */
+  public void testReadTimeZone_Bug118835133_extraFirstTransition() throws Exception {
+    // A time before the first representable time in a TZif version 1 file.
+    Instant before32BitTime = timeFromSeconds(Integer.MIN_VALUE).minusMillis(1);
+
+    // Times between the start of the 32-bit time range and the first "official" transition.
+    Instant[] earlyTimes = {
+            timeFromSeconds(Integer.MIN_VALUE),
+            timeFromSeconds(Integer.MIN_VALUE).plusMillis(1),
+    };
+
+    Instant firstRealTransitionTime = timeFromSeconds(1000);
+    Instant afterFirstRealTransitionTime = firstRealTransitionTime.plusSeconds(1);
+    Instant[] afterFirstRealTransitionTimes = {
+            firstRealTransitionTime,
+            afterFirstRealTransitionTime,
+    };
+
+    // A time to use as currentTime when building the TimeZone. Important for the getRawOffset()
+    // calculation.
+    Instant currentTime = afterFirstRealTransitionTime;
+
+    Duration type0Offset = offsetFromSeconds(0);
+    Duration type1Offset = offsetFromSeconds(1800);
+    Duration type2Offset = offsetFromSeconds(3600);
+    int[][] types = {
+            { offsetToSeconds(type0Offset), 0 }, // 1st type, used before first known transition.
+            { offsetToSeconds(type1Offset), 0 },
+            { offsetToSeconds(type2Offset), 0 },
+    };
+
+    // Creates a simulation of zic version <= 2014b or zic version >= 2018f where there is often
+    // no explicit transition at Integer.MIN_VALUE seconds in TZif version 1 data.
+    {
+      int[][] transitions = {
+              { timeToSeconds(firstRealTransitionTime), 2 /* type 2 */ },
+      };
+      ZoneInfo oldZoneInfo = createZoneInfo(transitions, types, currentTime);
+      assertRawOffset(oldZoneInfo, type2Offset);
+
+      // We use the first non-DST type for times before the first transition.
+      assertOffsetAt(oldZoneInfo, type0Offset, before32BitTime);
+      assertOffsetAt(oldZoneInfo, type0Offset, earlyTimes);
+
+      // This is after the first transition, so type 2.
+      assertOffsetAt(oldZoneInfo, type2Offset, afterFirstRealTransitionTimes);
+    }
+
+    // Creates a simulation of zic version > 2014b and zic version < 2018f where there is usually an
+    // explicit transition at Integer.MIN_VALUE seconds for TZif version 1 data.
+    {
+      int[][] transitions = {
+              { Integer.MIN_VALUE, 1 /* type 1 */ }, // The extra transition added by zic.
+              { timeToSeconds(firstRealTransitionTime), 2 /* type 2 */ },
+      };
+      ZoneInfo newZoneInfo = createZoneInfo(transitions, types, currentTime);
+      assertRawOffset(newZoneInfo, type2Offset);
+
+      // We use the first non-DST type for times before the first transition.
+      assertOffsetAt(newZoneInfo, type0Offset, before32BitTime);
+
+      // After the first transition, so type 1.
+      assertOffsetAt(newZoneInfo, type1Offset, earlyTimes);
+
+      // This is after the second transition, so type 2.
+      assertOffsetAt(newZoneInfo, type2Offset, afterFirstRealTransitionTimes);
+    }
+  }
+
+  /**
+   * Newer versions of zic after 2014b sometime introduce an explicit transition at
+   * Integer.MAX_VALUE.
+   */
+  public void testReadTimeZone_Bug118835133_extraLastTransition() throws Exception {
+    // An arbitrary time to use as currentTime. Not important for this test.
+    Instant currentTime = timeFromSeconds(4000);
+
+    // Offset before time 1000 should be consistent.
+    Instant[] timesToCheck = {
+            timeFromSeconds(2100), // arbitrary time > 2000
+            timeFromSeconds(Integer.MAX_VALUE).minusMillis(1),
+            timeFromSeconds(Integer.MAX_VALUE),
+            timeFromSeconds(Integer.MAX_VALUE).plusMillis(1),
+    };
+
+    int latestOffsetSeconds = 3600;
+    int[][] types = {
+            { 1800, 0 },
+            { latestOffsetSeconds, 0 },
+    };
+    Duration expectedLateOffset = offsetFromSeconds(latestOffsetSeconds);
+
+    // Create a simulation of zic version <= 2014b where there is usually no explicit transition at
+    // Integer.MAX_VALUE seconds.
+    {
+      int[][] transitions = {
+              { 1000, 0 },
+              { 2000, 1 },
+      };
+      ZoneInfo oldZoneInfo = createZoneInfo(transitions, types, currentTime);
+      assertOffsetAt(oldZoneInfo, expectedLateOffset, timesToCheck);
+    }
+
+    // Create a simulation of zic version > 2014b where there is sometimes an explicit transition at
+    // Integer.MAX_VALUE seconds.
+    {
+      int[][] transitions = {
+              { 1000, 0 },
+              { 2000, 1 },
+              { Integer.MAX_VALUE, 1}, // The extra transition.
+      };
+      ZoneInfo newZoneInfo = createZoneInfo(transitions, types, currentTime);
+      assertOffsetAt(newZoneInfo, expectedLateOffset, timesToCheck);
+    }
   }
 
   /**
@@ -316,10 +454,11 @@
     Arrays.fill(types, new int[2]);
     types[255] = new int[] { 3600, 0 };
 
-    ZoneInfo zoneInfo = createZoneInfo(getName(), transitions, types, (long) Integer.MIN_VALUE);
+    ZoneInfo zoneInfo = createZoneInfo(getName(), transitions, types,
+            timeFromSeconds(Integer.MIN_VALUE));
 
     assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertEquals(0, zoneInfo.getDSTSavings());
+    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
 
     // Make sure that WallTime works properly with a ZoneInfo with 256 types.
     ZoneInfo.WallTime wallTime = new ZoneInfo.WallTime();
@@ -356,7 +495,7 @@
     ZoneInfoTestHelper.ZicDataBuilder builder =
             new ZoneInfoTestHelper.ZicDataBuilder()
                     .initializeToValid();
-    assertNotNull(createZoneInfo(getName(), System.currentTimeMillis(), builder.build()));
+    assertNotNull(createZoneInfo(getName(), Instant.now(), builder.build()));
   }
 
   public void testReadTimeZone_badMagic() throws Exception {
@@ -365,7 +504,7 @@
                     .initializeToValid()
                     .setMagic(0xdeadbeef); // Bad magic.
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), builder.build());
+      createZoneInfo(getName(), Instant.now(), builder.build());
       fail();
     } catch (IOException expected) {}
   }
@@ -380,7 +519,7 @@
                     .setTypeCountOverride(257);
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail("Did not detect too many types");
     } catch (IOException expected) {
     }
@@ -396,7 +535,7 @@
                     .setTransitionCountOverride(2001);
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail("Did not detect too many transitions");
     } catch (IOException expected) {
     }
@@ -412,7 +551,7 @@
                     .setTypeCountOverride(-1);
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail();
     } catch (IOException expected) {
     }
@@ -428,7 +567,7 @@
                     .setTransitionCountOverride(-1);
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail();
     } catch (IOException expected) {
     }
@@ -452,7 +591,7 @@
 
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail();
     } catch (IOException expected) {
     }
@@ -476,7 +615,7 @@
 
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail();
     } catch (IOException expected) {
     }
@@ -500,7 +639,7 @@
 
     byte[] bytes = builder.build();
     try {
-      createZoneInfo(getName(), System.currentTimeMillis(), bytes);
+      createZoneInfo(getName(), Instant.now(), bytes);
       fail();
     } catch (IOException expected) {
     }
@@ -536,7 +675,8 @@
         { 1800, 1 },
         { 5400, 0 }
     };
-    ZoneInfo zoneInfoCreated = createZoneInfo("test", transitions, types, secondsInMillis(-1));
+    ZoneInfo zoneInfoCreated = createZoneInfo(
+            "test", transitions, types, timeFromSeconds(-1));
 
     assertEquals("Read ZoneInfo does not match created one", zoneInfoCreated, zoneInfoRead);
     assertEquals("useDaylightTime() mismatch",
@@ -545,33 +685,74 @@
         zoneInfoCreated.getDSTSavings(), zoneInfoRead.getDSTSavings());
   }
 
-  private static int secondsInMillis(int seconds) {
-    return seconds * 1000;
+  private static void assertRawOffset(ZoneInfo zoneInfo, Duration expectedOffset) {
+    assertEquals(expectedOffset.toMillis(), zoneInfo.getRawOffset());
+  }
+
+  private static void assertDSTSavings(ZoneInfo zoneInfo, Duration expectedDSTSavings) {
+    assertEquals(expectedDSTSavings.toMillis(), zoneInfo.getDSTSavings());
+  }
+
+  private static void assertInDaylightTime(ZoneInfo zoneInfo, Instant time, boolean expectedValue) {
+    assertEquals(expectedValue, zoneInfo.inDaylightTime(new Date(time.toEpochMilli())));
+  }
+
+  private static void assertOffsetAt(
+          ZoneInfo zoneInfo, Duration expectedOffset, Instant... times) {
+    for (Instant time : times) {
+      assertEquals("Unexpected offset at " + time,
+              expectedOffset.toMillis(), zoneInfo.getOffset(time.toEpochMilli()));
+    }
+  }
+
+  private static Instant timeFromSeconds(int timeInSeconds) {
+    return Instant.ofEpochSecond(timeInSeconds);
+  }
+
+  private static int timeToSeconds(Instant time) {
+    long seconds = time.getEpochSecond();
+    if (seconds < Integer.MIN_VALUE || seconds > Integer.MAX_VALUE) {
+      fail("Time out of seconds range: " + time);
+    }
+    return (int) seconds;
+  }
+
+  private static Duration offsetFromSeconds(int offsetSeconds) {
+    return Duration.ofSeconds(offsetSeconds);
+  }
+
+  private static int offsetToSeconds(Duration offset) {
+    long seconds = offset.getSeconds();
+    if (seconds < Integer.MIN_VALUE || seconds > Integer.MAX_VALUE) {
+      fail("Offset out of seconds range: " + offset);
+    }
+    return (int) seconds;
   }
 
   private ZoneInfo createZoneInfo(int[][] transitions, int[][] types)
       throws Exception {
-    return createZoneInfo(getName(), transitions, types, System.currentTimeMillis());
+    return createZoneInfo(getName(), transitions, types, Instant.now());
   }
 
-  private ZoneInfo createZoneInfo(int[][] transitions, int[][] types,
-      long currentTimeMillis) throws Exception {
-    return createZoneInfo(getName(), transitions, types, currentTimeMillis);
+  private ZoneInfo createZoneInfo(int[][] transitions, int[][] types, Instant currentTime)
+          throws Exception {
+    return createZoneInfo(getName(), transitions, types, currentTime);
   }
 
   private ZoneInfo createZoneInfo(String name, int[][] transitions, int[][] types,
-      long currentTimeMillis) throws Exception {
+          Instant currentTime) throws Exception {
 
     ZoneInfoTestHelper.ZicDataBuilder builder =
             new ZoneInfoTestHelper.ZicDataBuilder()
                     .setTransitionsAndTypes(transitions, types);
-    return createZoneInfo(name, currentTimeMillis, builder.build());
+    return createZoneInfo(name, currentTime, builder.build());
   }
 
-  private ZoneInfo createZoneInfo(String name, long currentTimeMillis, byte[] bytes)
+  private ZoneInfo createZoneInfo(String name, Instant currentTime, byte[] bytes)
           throws IOException {
     ByteBufferIterator bufferIterator = new ByteBufferIterator(ByteBuffer.wrap(bytes));
-    return ZoneInfo.readTimeZone("TimeZone for '" + name + "'", bufferIterator, currentTimeMillis);
+    return ZoneInfo.readTimeZone(
+            "TimeZone for '" + name + "'", bufferIterator, currentTime.toEpochMilli());
   }
 
   /**
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/sun/security/x509/Utils.java b/luni/src/test/java/libcore/sun/security/x509/Utils.java
new file mode 100644
index 0000000..aa53726
--- /dev/null
+++ b/luni/src/test/java/libcore/sun/security/x509/Utils.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 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.security.x509;
+
+import junit.framework.Assert;
+
+import java.util.function.Function;
+
+class Utils extends Assert {
+    /**
+     * Many classes in this package can be created using a bit array, and the toString method
+     * depends only on the bit array. The logic for toString was changed in rev/04cda5b7a3c1.
+     * The expected result is the same before and after the change.
+     * @param parts The different parts of the result
+     * @param objectCreator Function to create a new instance of the class tested.
+     * @param prefix prefix in all toString results
+     * @param suffix suffix in all toString results
+     */
+    static void test_toString_bitArrayBasedClass(
+            String[] parts,
+            Function<byte[], Object> objectCreator,
+            String prefix,
+            String suffix) {
+        testWithEachSinglePart(parts, objectCreator, prefix, suffix);
+        testWithAllParts(parts, objectCreator, prefix, suffix);
+        testWithNoParts(parts, objectCreator, prefix, suffix);
+        testWithEveryOtherPart(parts, objectCreator, prefix, suffix);
+    }
+
+    private static void testWithEachSinglePart(
+            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
+        int bitCounter = 0, byteCounter = 1;
+        for (int i = 0; i < parts.length; i++) {
+            byte[] ba = new byte[byteCounter];
+            ba[byteCounter - 1] = (byte) (1 << (7 - bitCounter));
+            bitCounter++;
+            if (bitCounter == 8) {
+                bitCounter = 0;
+                byteCounter++;
+            }
+            Object o =  objectCreator.apply(ba);
+            assertEquals(prefix + parts[i] + suffix, o.toString());
+        }
+    }
+
+    private static void testWithAllParts(
+            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
+        int bitsInAByte = 8;
+        int allOnesLength = (parts.length + bitsInAByte - 1) / bitsInAByte;
+        byte[] allOnes = new byte[allOnesLength];
+
+        for (int i = 0; i < allOnes.length; i++) {
+            allOnes[i] = -1;
+        }
+        assertEquals(prefix + String.join("", parts)
+                + suffix, objectCreator.apply(allOnes).toString());
+    }
+
+    private static void testWithNoParts(
+            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
+        // Test with empty array
+        assertEquals(prefix + suffix, objectCreator.apply(new byte[0]).toString());
+
+        // Test with array will all zeros
+        assertEquals(prefix + suffix, objectCreator.apply(new byte[parts.length]).toString());
+    }
+
+    private static void testWithEveryOtherPart(
+            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
+        int bitsInAByte = 8;
+        byte[] ba = new byte[(parts.length + bitsInAByte - 1) / bitsInAByte];
+        String expectedResult = new String();
+        for (int i = 0; i < parts.length; i += 2) {
+            ba[i / bitsInAByte] = (byte) 170; // Binary 10101010
+            expectedResult += parts[i];
+        }
+        assertEquals(prefix + expectedResult + suffix, objectCreator.apply(ba).toString());
+    }
+}
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/crypto/tests/javax/crypto/CipherSpiTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
index 1a2ac23..ee3bc8c 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
@@ -121,6 +121,16 @@
         }
 
         @Override
+        protected void engineUpdateAAD(byte[] src, int offset, int len) {
+            super.engineUpdateAAD(src, offset, len);
+        }
+
+        @Override
+        protected void engineUpdateAAD(ByteBuffer buf) {
+            super.engineUpdateAAD(buf);
+        }
+
+        @Override
         protected int engineGetKeySize(Key key) throws InvalidKeyException {
             return super.engineGetKeySize(key);
         }
@@ -301,6 +311,32 @@
         assertTrue("Incorrect result", cSpi.engineDoFinal(bb1, bb2) > 0);
     }
 
+    /**
+     * Test for <code>engineUpdateAAD(ByteBuffer)</code> method
+     * Assertion: It throws UnsupportedOperationException if it is not overridden
+     */
+    public void testCipherSpi07() {
+        Mock_CipherSpi cSpi = new Mock_CipherSpi();
+        try {
+            cSpi.engineUpdateAAD(ByteBuffer.wrap(new byte[] { 0x00, 0x01}));
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    /**
+     * Test for <code>engineUpdateAAD(byte[], int, int)</code> method
+     * Assertion: It throws UnsupportedOperationException if it is not overridden
+     */
+    public void testCipherSpi08() {
+        Mock_CipherSpi cSpi = new Mock_CipherSpi();
+        try {
+            cSpi.engineUpdateAAD(new byte[] { 0x00, 0x01}, 0, 2);
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
     public void testCrypt_doNotCallPositionInNonArrayBackedInputBuffer() throws Exception {
         ByteBuffer nonArrayBackedInputBuffer = new MockNonArrayBackedByteBuffer(10, false);
         ByteBuffer nonArrayBackedOutputBuffer = new MockNonArrayBackedByteBuffer(10, false);
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
index 2159e78..a6c663f 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
@@ -50,45 +50,6 @@
                 2211791113380396553L);
     }
 
-    public void test_getParams_initToHardCoded() throws Exception {
-        // (p, g) values from RFC 7919, Appendix A (2048-bit group)
-        String pStr = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
-                "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
-                "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
-                "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
-                "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
-                "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
-                "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
-                "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
-                "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
-                "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
-                "886B423861285C97FFFFFFFFFFFFFFFF";
-        BigInteger p = new BigInteger(new BigInteger(pStr, 16).toByteArray());
-        BigInteger g = BigInteger.valueOf(2);
-        KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
-        kg.initialize(new DHParameterSpec(p, g), new SecureRandom());
-        check_getParams(kg);
-    }
-
-    public void test_getParams_initToRandom192bit() throws Exception {
-        KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
-        // DH group generation is slow, so we test with a small (insecure) value
-        kg.initialize(192);
-        check_getParams(kg);
-    }
-
-    private static void check_getParams(KeyPairGenerator kg) throws Exception {
-        KeyPair kp1 = kg.genKeyPair();
-        KeyPair kp2 = kg.genKeyPair();
-        DHPrivateKey pk1 = (DHPrivateKey) kp1.getPrivate();
-        DHPrivateKey pk2 = (DHPrivateKey) kp2.getPrivate();
-
-        assertTrue(pk1.getX().getClass().getCanonicalName().equals("java.math.BigInteger"));
-        assertTrue(pk1.getParams().getClass().getCanonicalName().equals("javax.crypto.spec.DHParameterSpec"));
-        assertFalse(pk1.equals(pk2));
-        assertTrue(pk1.getX().equals(pk1.getX()));
-    }
-
     public class checkDHPrivateKey implements DHPrivateKey {
         public String getAlgorithm() {
             return "SecretKey";
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
index 3920466..25c0b63 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
@@ -50,45 +50,6 @@
                 -6628103563352519193L);
     }
 
-    public void test_getParams_initToHardCoded() throws Exception {
-        // (p, g) values from RFC 7919, Appendix A (2048-bit group)
-        String pStr = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
-                "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
-                "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
-                "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
-                "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
-                "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
-                "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
-                "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
-                "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
-                "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
-                "886B423861285C97FFFFFFFFFFFFFFFF";
-        BigInteger p = new BigInteger(new BigInteger(pStr, 16).toByteArray());
-        BigInteger g = BigInteger.valueOf(2);
-        KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
-        kg.initialize(new DHParameterSpec(p, g), new SecureRandom());
-        check_getParams(kg);
-    }
-
-    public void test_getParams_initToRandom192bit() throws Exception {
-        KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
-        // DH group generation is slow, so we test with a small (insecure) value
-        kg.initialize(192);
-        check_getParams(kg);
-    }
-
-    private void check_getParams(KeyPairGenerator kg) {
-        KeyPair kp1 = kg.genKeyPair();
-        KeyPair kp2 = kg.genKeyPair();
-        DHPublicKey pk1 = (DHPublicKey) kp1.getPublic();
-        DHPublicKey pk2 = (DHPublicKey) kp2.getPublic();
-
-        assertTrue(pk1.getY().getClass().getCanonicalName().equals("java.math.BigInteger"));
-        assertTrue(pk2.getParams().getClass().getCanonicalName().equals("javax.crypto.spec.DHParameterSpec"));
-        assertFalse(pk1.equals(pk2));
-        assertTrue(pk1.getY().equals(pk1.getY()));
-    }
-
     public class checkDHPublicKey implements DHPublicKey {
         public String getAlgorithm() {
             return "SecretKey";
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..fe454db 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
@@ -22,12 +22,21 @@
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-import junit.framework.TestCase;
-
+import libcore.junit.junit3.TestCaseWithRules;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-public class PatternTest extends TestCase {
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+
+import static java.util.Arrays.asList;
+
+public class PatternTest extends TestCaseWithRules {
+    @Rule
+    public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
     String[] testPatterns = {
             "(a|b)*abb",
             "(1*2*3*4*)*567",
@@ -76,18 +85,21 @@
         assertNotSame(p.matcher("a"), p.matcher("a"));
     }
 
-    public void testSplitCharSequenceInt() {
+    public void testSplitCharSequenceBug6193() {
         // splitting CharSequence which ends with pattern
-        // bug6193
         assertEquals(",,".split(",", 3).length, 3);
         assertEquals(",,".split(",", 4).length, 3);
-        // bug6193
-        // bug5391
+    }
+
+    public void testSplitCharSequenceBug5391() {
         assertEquals(Pattern.compile("o").split("boo:and:foo", 5).length, 5);
         assertEquals(Pattern.compile("b").split("ab", -1).length, 2);
-        // bug5391
-        String s[];
+    }
+
+    public void testSplitCharSequence() {
         Pattern pat = Pattern.compile("x");
+        String[] s;
+
         s = pat.split("zxx:zzz:zxx", 10);
         assertEquals(s.length, 5);
         s = pat.split("zxx:zzz:zxx", 3);
@@ -96,9 +108,31 @@
         assertEquals(s.length, 5);
         s = pat.split("zxx:zzz:zxx", 0);
         assertEquals(s.length, 3);
-        // other splitting
-        // negative limit
+
         pat = Pattern.compile("b");
+        s = pat.split("abccbadfebb");
+        assertEquals(s.length, 3);
+        s = pat.split("");
+        assertEquals(s.length, 1);
+
+        pat = Pattern.compile("");
+        s = pat.split("");
+        assertEquals(s.length, 1);
+        s = pat.split("abccbadfe");
+        assertEquals(s.length, 9);
+    }
+
+    public void testBug6544() {
+        String s = "";
+        String[] arr = s.split(":");
+        assertEquals(arr.length, 1);
+    }
+
+    public void testSplitCharSequenceNegativeLimit() {
+        // negative limit
+        Pattern pat = Pattern.compile("b");
+        String[] s;
+
         s = pat.split("abccbadfebb", -1);
         assertEquals(s.length, 5);
         s = pat.split("", -1);
@@ -107,9 +141,13 @@
         s = pat.split("", -1);
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe", -1);
-        assertEquals(s.length, 11);
-        // zero limit
-        pat = Pattern.compile("b");
+        assertEquals(s.length, 10);
+    }
+
+    public void testSplitCharSequenceZeroLimit() {
+        String[] s;
+        Pattern pat = Pattern.compile("b");
+
         s = pat.split("abccbadfebb", 0);
         assertEquals(s.length, 3);
         s = pat.split("", 0);
@@ -118,9 +156,13 @@
         s = pat.split("", 0);
         assertEquals(s.length, 1);
         s = pat.split("abccbadfe", 0);
-        assertEquals(s.length, 10);
-        // positive limit
-        pat = Pattern.compile("b");
+        assertEquals(s.length, 9);
+    }
+
+    public void testSplitCharSequencePositiveLimitCase1() {
+        String[] s;
+        Pattern pat = Pattern.compile("b");
+
         s = pat.split("abccbadfebb", 12);
         assertEquals(s.length, 5);
         s = pat.split("", 6);
@@ -129,9 +171,13 @@
         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");
+    public void testSplitCharSequencePositiveLimitCase2() {
+        String[] s;
+        Pattern pat = Pattern.compile("b");
+
         s = pat.split("abccbadfebb", 5);
         assertEquals(s.length, 5);
         s = pat.split("", 1);
@@ -139,10 +185,14 @@
         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");
+    public void testSplitCharSequencePositiveLimitCase3() {
+        Pattern pat = Pattern.compile("b");
+        String[] s;
+
         s = pat.split("abccbadfebb", 3);
         assertEquals(s.length, 3);
         pat = Pattern.compile("");
@@ -150,23 +200,50 @@
         assertEquals(s.length, 5);
     }
 
-    public void testSplitCharSequence() {
-        String s[];
-        Pattern pat = Pattern.compile("b");
-        s = pat.split("abccbadfebb");
-        assertEquals(s.length, 3);
-        s = pat.split("");
-        assertEquals(s.length, 1);
-        pat = Pattern.compile("");
-        s = pat.split("");
-        assertEquals(s.length, 1);
-        s = pat.split("abccbadfe");
-        assertEquals(s.length, 10);
-        // bug6544
-        String s1 = "";
-        String[] arr = s1.split(":");
-        assertEquals(arr.length, 1);
-        // bug6544
+    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)));
+    }
+
+    @TargetSdkVersion(28)
+    public void testSplitOnEmptyPattern_api28() {
+        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)")));
+    }
+
+    @TargetSdkVersion(28)
+    public void testMatchBeginningOfInputSequence_api28() {
+        // 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 testPattern() {
@@ -181,8 +258,7 @@
         }
     }
 
-    public void testCompile() {
-        /* Positive assertion test. */
+    public void testCompile_Valid() {
         for (String aPattern : testPatterns) {
             try {
                 Pattern p = Pattern.compile(aPattern);
@@ -191,7 +267,6 @@
             }
         }
 
-        /* Positive assertion test with alternative templates. */
         for (String aPattern : testPatternsAlt) {
             try {
                 Pattern p = Pattern.compile(aPattern);
@@ -199,8 +274,9 @@
                 fail("Unexpected exception: " + e);
             }
         }
+    }
 
-        /* Negative assertion test. */
+    public void testCompile_WrongPatternsFail() {
         for (String aPattern : wrongTestPatterns) {
             try {
                 Pattern p = Pattern.compile(aPattern);
@@ -213,126 +289,163 @@
         }
     }
 
-    public void testFlags() {
-        String baseString;
-        String testString;
-        Pattern pat;
-        Matcher mat;
-
-        baseString = "((?i)|b)a";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase1() {
+        String baseString = "((?i)|b)a";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        baseString = "(?i)a|b";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase2() {
+        String baseString = "(?i)a|b";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)a|b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase3() {
+        String baseString = "(?i)a|b";
+        String testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "c|(?i)a|b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase4() {
+        String baseString = "c|(?i)a|b";
+        String testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)a|(?s)b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase5() {
+        String baseString = "(?i)a|(?s)b";
+        String testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)a|(?-i)b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase6() {
+        String baseString = "(?i)a|(?-i)b";
+        String testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        baseString = "(?i)a|(?-i)c|b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase7() {
+        String baseString = "(?i)a|(?-i)c|b";
+        String testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        baseString = "(?i)a|(?-i)c|(?i)b";
-        testString = "B";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase8() {
+       String  baseString = "(?i)a|(?-i)c|(?i)b";
+       String  testString = "B";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)a|(?-i)b";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase9() {
+        String baseString = "(?i)a|(?-i)b";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "((?i))a";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase10() {
+        String baseString = "((?i))a";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        baseString = "|(?i)|a";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase11() {
+        String baseString = "|(?i)|a";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)((?s)a.)";
-        testString = "A\n";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase12() {
+        String baseString = "(?i)((?s)a.)";
+        String testString = "A\n";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)((?-i)a)";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase13() {
+        String baseString = "(?i)((?-i)a)";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        baseString = "(?i)(?s:a.)";
-        testString = "A\n";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase14() {
+        String baseString = "(?i)(?s:a.)";
+        String testString = "A\n";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)fgh(?s:aa)";
-        testString = "fghAA";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase15() {
+        String baseString = "(?i)fgh(?s:aa)";
+        String testString = "fghAA";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?i)((?-i))a";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase16() {
+        String baseString = "(?i)((?-i))a";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "abc(?i)d";
-        testString = "ABCD";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase17() {
+        String baseString = "abc(?i)d";
+        String testString = "ABCD";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        testString = "abcD";
-        mat = pat.matcher(testString);
+    public void testFlagsCase18() {
+        String baseString = "abc(?i)d";
+        String testString = "abcD";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "a(?i)a(?-i)a(?i)a(?-i)a";
-        testString = "aAaAa";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testFlagsCase19() {
+        String baseString = "a(?i)a(?-i)a(?i)a(?-i)a";
+        String testString = "aAaAa";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        testString = "aAAAa";
-        mat = pat.matcher(testString);
+    public void testFlagsCase20() {
+        String baseString = "a(?i)a(?-i)a(?i)a(?-i)a";
+        String testString = "aAAAa";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
     }
 
@@ -833,20 +946,23 @@
         Pattern.compile("\\p{Lower}");
     }
 
-    public void testNonCaptConstr() {
-        // Flags
+    public void testCapture_Flags() {
         Pattern pat = Pattern.compile("(?i)b*(?-i)a*");
         assertTrue(pat.matcher("bBbBaaaa").matches());
         assertFalse(pat.matcher("bBbBAaAa").matches());
+    }
 
-        // Non-capturing groups
-        pat = Pattern.compile("(?i:b*)a*");
+    public void testCapture_NonCaptGroups() {
+        Pattern pat = Pattern.compile("(?i:b*)a*");
         assertTrue(pat.matcher("bBbBaaaa").matches());
         assertFalse(pat.matcher("bBbBAaAa").matches());
+    }
 
-        pat = Pattern
-        // 1 2 3 4 5 6 7 8 9 10 11
-                .compile("(?:-|(-?\\d+\\d\\d\\d))?(?:-|-(\\d\\d))?(?:-|-(\\d\\d))?(T)?(?:(\\d\\d):(\\d\\d):(\\d\\d)(\\.\\d+)?)?(?:(?:((?:\\+|\\-)\\d\\d):(\\d\\d))|(Z))?");
+    public void testCapture() {
+        Pattern pat = Pattern
+                // 1 2 3 4 5 6 7 8 9 10 11
+                .compile(
+                        "(?:-|(-?\\d+\\d\\d\\d))?(?:-|-(\\d\\d))?(?:-|-(\\d\\d))?(T)?(?:(\\d\\d):(\\d\\d):(\\d\\d)(\\.\\d+)?)?(?:(?:((?:\\+|\\-)\\d\\d):(\\d\\d))|(Z))?");
         Matcher mat = pat.matcher("-1234-21-31T41:51:61.789+71:81");
         assertTrue(mat.matches());
         assertEquals("-1234", mat.group(1));
@@ -859,36 +975,49 @@
         assertEquals(".789", mat.group(8));
         assertEquals("+71", mat.group(9));
         assertEquals("81", mat.group(10));
+    }
 
-        // positive lookahead
-        pat = Pattern.compile(".*\\.(?=log$).*$");
+    public void testCapture_PositiveLookahead() {
+        Pattern pat = Pattern.compile(".*\\.(?=log$).*$");
         assertTrue(pat.matcher("a.b.c.log").matches());
         assertFalse(pat.matcher("a.b.c.log.").matches());
+    }
 
-        // negative lookahead
-        pat = Pattern.compile(".*\\.(?!log$).*$");
+    public void testCapture_NegativeLookahead() {
+        Pattern pat = Pattern.compile(".*\\.(?!log$).*$");
         assertFalse(pat.matcher("abc.log").matches());
         assertTrue(pat.matcher("abc.logg").matches());
+    }
 
-        // positive lookbehind
-        pat = Pattern.compile(".*(?<=abc)\\.log$");
+    public void testCapture_PositiveLookbehind() {
+        Pattern pat = Pattern.compile(".*(?<=abc)\\.log$");
         assertFalse(pat.matcher("cde.log").matches());
         assertTrue(pat.matcher("abc.log").matches());
+    }
 
-        // negative lookbehind
-        pat = Pattern.compile(".*(?<!abc)\\.log$");
+    public void testCapture_NegativeLookbehind() {
+        Pattern pat = Pattern.compile(".*(?<!abc)\\.log$");
         assertTrue(pat.matcher("cde.log").matches());
         assertFalse(pat.matcher("abc.log").matches());
+    }
 
-        // atomic group
-        pat = Pattern.compile("(?>a*)abb");
+    public void testCapture_AtomicGroupCase1() {
+        Pattern pat = Pattern.compile("(?>a*)abb");
         assertFalse(pat.matcher("aaabb").matches());
-        pat = Pattern.compile("(?>a*)bb");
-        assertTrue(pat.matcher("aaabb").matches());
+    }
 
-        pat = Pattern.compile("(?>a|aa)aabb");
+    public void testCapture_AtomicGroupCase2() {
+        Pattern pat = Pattern.compile("(?>a*)bb");
         assertTrue(pat.matcher("aaabb").matches());
-        pat = Pattern.compile("(?>aa|a)aabb");
+    }
+
+    public void testCapture_AtomicGroupCase3() {
+        Pattern pat = Pattern.compile("(?>a|aa)aabb");
+        assertTrue(pat.matcher("aaabb").matches());
+    }
+
+    public void testCapture_AtomicGroupCase4() {
+        Pattern pat = Pattern.compile("(?>aa|a)aabb");
         assertFalse(pat.matcher("aaabb").matches());
 
 // BEGIN Android-removed
@@ -926,88 +1055,115 @@
         assertTrue(mat.matches());
     }
 
-    public void testAlternations() {
+    public void testAlternationsCase1() {
         String baseString = "|a|bc";
         Pattern pat = Pattern.compile(baseString);
         Matcher mat = pat.matcher("");
 
         assertTrue(mat.matches());
+    }
 
-        baseString = "a||bc";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("");
-        assertTrue(mat.matches());
-
-        baseString = "a|bc|";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("");
-        assertTrue(mat.matches());
-
-        baseString = "a|b|";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("");
-        assertTrue(mat.matches());
-
-        baseString = "a(|b|cd)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "a(b||cd)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "a(b|cd|)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "a(b|c|)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "a(|)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "|";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("");
-        assertTrue(mat.matches());
-
-        baseString = "a(?:|)e";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("ae");
-        assertTrue(mat.matches());
-
-        baseString = "a||||bc";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("");
-        assertTrue(mat.matches());
-
-        baseString = "(?i-is)|a";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher("a");
+    public void testAlternationsCase2() {
+        String baseString = "a||bc";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("");
         assertTrue(mat.matches());
     }
 
-    public void testMatchWithGroups() {
+    public void testAlternationsCase3() {
+        String baseString = "a|bc|";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase4() {
+        String baseString = "a|b|";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase5() {
+        String baseString = "a(|b|cd)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase6() {
+        String baseString = "a(b||cd)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase7() {
+        String baseString = "a(b|cd|)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase8() {
+        String baseString = "a(b|c|)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase9() {
+        String baseString = "a(|)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase10() {
+        String baseString = "|";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase11() {
+        String baseString = "a(?:|)e";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("ae");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase12() {
+        String baseString = "a||||bc";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("");
+        assertTrue(mat.matches());
+    }
+
+    public void testAlternationsCase13() {
+        String baseString = "(?i-is)|a";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher("a");
+        assertTrue(mat.matches());
+    }
+
+    public void testMatchWithGroups14() {
         String baseString = "jwkerhjwehrkwjehrkwjhrwkjehrjwkehrjkwhrkwehrkwhrkwrhwkhrwkjehr";
         String pattern = ".*(..).*\\1.*";
         assertTrue(Pattern.compile(pattern).matcher(baseString).matches());
+    }
 
-        baseString = "saa";
-        pattern = ".*(.)\\1";
+    public void testMatchWithGroups15() {
+        String baseString = "saa";
+        String pattern = ".*(.)\\1";
         assertTrue(Pattern.compile(pattern).matcher(baseString).matches());
         assertTrue(Pattern.compile(pattern).matcher(baseString).find());
     }
 
     public void testSplitEmptyCharSequence() {
-        String s1 = "";
-        String[] arr = s1.split(":");
+        String s = "";
+        String[] arr = s.split(":");
+
         assertEquals(arr.length, 1);
     }
 
@@ -1023,49 +1179,66 @@
         assertTrue(Pattern.matches("(?i-:AbC)", "ABC"));
     }
 
-    public void testEmptyGroups() {
+    public void testEmptyGroupsCase1() {
         Pattern pat = Pattern.compile("ab(?>)cda");
         Matcher mat = pat.matcher("abcda");
-        assertTrue(mat.matches());
 
-        pat = Pattern.compile("ab()");
-        mat = pat.matcher("ab");
-        assertTrue(mat.matches());
-
-        pat = Pattern.compile("abc(?:)(..)");
-        mat = pat.matcher("abcgf");
         assertTrue(mat.matches());
     }
 
-    public void testEmbeddedFlags() {
+    public void testEmptyGroupsCase2() {
+        Pattern pat = Pattern.compile("ab()");
+        Matcher mat = pat.matcher("ab");
+
+        assertTrue(mat.matches());
+    }
+
+    public void testEmptyGroupsCase3() {
+        Pattern pat = Pattern.compile("abc(?:)(..)");
+        Matcher mat = pat.matcher("abcgf");
+
+        assertTrue(mat.matches());
+    }
+
+    public void testEmbeddedFlagsCase1() {
         String baseString = "(?i)((?s)a)";
         String testString = "A";
         Pattern pat = Pattern.compile(baseString);
         Matcher mat = pat.matcher(testString);
-        assertTrue(mat.matches());
 
-        baseString = "(?x)(?i)(?s)(?d)a";
-        testString = "A";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "(?x)(?i)(?s)(?d)a.";
-        testString = "a\n";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testEmbeddedFlagsCase2() {
+        String baseString = "(?x)(?i)(?s)(?d)a";
+        String testString = "A";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
+
         assertTrue(mat.matches());
+    }
 
-        baseString = "abc(?x:(?i)(?s)(?d)a.)";
-        testString = "abcA\n";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testEmbeddedFlagsCase3() {
+        String baseString = "(?x)(?i)(?s)(?d)a.";
+        String testString = "a\n";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        baseString = "abc((?x)d)(?i)(?s)a";
-        testString = "abcdA";
-        pat = Pattern.compile(baseString);
-        mat = pat.matcher(testString);
+    public void testEmbeddedFlagsCase4() {
+        String baseString = "abc(?x:(?i)(?s)(?d)a.)";
+        String testString = "abcA\n";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testEmbeddedFlagsCase5() {
+        String baseString = "abc((?x)d)(?i)(?s)a";
+        String testString = "abcdA";
+        Pattern pat = Pattern.compile(baseString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
     }
 
@@ -1137,73 +1310,119 @@
         assertNotNull(pattern);
     }
 
-    public void testRangesWithSurrogatesSupplementary() {
+    public void testRangesWithSurrogatesSupplementaryCase1() {
         String patString = "[abc\uD8D2]";
         String testString = "\uD8D2";
         Pattern pat = Pattern.compile(patString);
         Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        testString = "a";
-        mat = pat.matcher(testString);
-        assertTrue(mat.matches());
-
-        testString = "ef\uD8D2\uDD71gh";
-        mat = pat.matcher(testString);
-        assertFalse(mat.find());
-
-        testString = "ef\uD8D2gh";
-        mat = pat.matcher(testString);
-        assertTrue(mat.find());
-
-        patString = "[abc\uD8D3&&[c\uD8D3]]";
-        testString = "c";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-        assertTrue(mat.matches());
-
-        testString = "a";
-        mat = pat.matcher(testString);
-        assertFalse(mat.matches());
-
-        testString = "ef\uD8D3\uDD71gh";
-        mat = pat.matcher(testString);
-        assertFalse(mat.find());
-
-        testString = "ef\uD8D3gh";
-        mat = pat.matcher(testString);
-        assertTrue(mat.find());
-
-        patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]";
-        testString = "c";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-        assertTrue(mat.matches());
-
-        testString = "\uDBEE\uDF0C";
-        mat = pat.matcher(testString);
-        assertTrue(mat.matches());
-
-        testString = "ef\uD8D3\uDD71gh";
-        mat = pat.matcher(testString);
-        assertFalse(mat.find());
-
-        testString = "ef\uD8D3gh";
-        mat = pat.matcher(testString);
-        assertTrue(mat.find());
-
-        patString = "[abc\uDBFC]\uDDC2cd";
-        testString = "\uDBFC\uDDC2cd";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-        assertFalse(mat.matches());
-
-        testString = "a\uDDC2cd";
-        mat = pat.matcher(testString);
+    public void testRangesWithSurrogatesSupplementaryCase2() {
+        String patString = "[abc\uD8D2]";
+        String testString = "a";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
     }
 
-    public void testSequencesWithSurrogatesSupplementary() {
+    public void testRangesWithSurrogatesSupplementaryCase3() {
+        String patString = "[abc\uD8D2]";
+        String testString = "ef\uD8D2\uDD71gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase4() {
+        String patString = "[abc\uD8D2]";
+        String testString = "ef\uD8D2gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase5() {
+        String patString = "[abc\uD8D3&&[c\uD8D3]]";
+        String testString = "c";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase6() {
+        String patString = "[abc\uD8D3&&[c\uD8D3]]";
+        String testString = "a";;
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.matches());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase7() {
+        String patString = "[abc\uD8D3&&[c\uD8D3]]";
+        String testString = "ef\uD8D3\uDD71gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase8() {
+        String patString = "[abc\uD8D3&&[c\uD8D3]]";
+        String testString = "ef\uD8D3gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase9() {
+        String patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]";
+        String testString = "c";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase10() {
+        String patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]";
+        String testString = "\uDBEE\uDF0C";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase11() {
+        String patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]";
+        String testString = "ef\uD8D3\uDD71gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase12() {
+        String patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]";
+        String testString = "ef\uD8D3gh";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.find());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase13() {
+        String patString = "[abc\uDBFC]\uDDC2cd";
+        String testString = "\uDBFC\uDDC2cd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.matches());
+    }
+
+    public void testRangesWithSurrogatesSupplementaryCase14() {
+        String patString = "[abc\uDBFC]\uDDC2cd";
+        String testString = "a\uDDC2cd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testSequencesWithSurrogatesSupplementaryCase1() {
         String patString = "abcd\uD8D3";
         String testString = "abcd\uD8D3\uDFFC";
         Pattern pat = Pattern.compile(patString);
@@ -1214,97 +1433,155 @@
 // might want to duplicate.
 //        assertFalse(mat.find());
 // END Android-changed
+    }
 
-        testString = "abcd\uD8D3abc";
-        mat = pat.matcher(testString);
-        assertTrue(mat.find());
 
-        patString = "ab\uDBEFcd";
-        testString = "ab\uDBEFcd";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-        assertTrue(mat.matches());
-
-        patString = "\uDFFCabcd";
-        testString = "\uD8D3\uDFFCabcd";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-        assertFalse(mat.find());
-
-        testString = "abc\uDFFCabcdecd";
-        mat = pat.matcher(testString);
-        assertTrue(mat.find());
-
-        patString = "\uD8D3\uDFFCabcd";
-        testString = "abc\uD8D3\uD8D3\uDFFCabcd";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testSequencesWithSurrogatesSupplementaryCase2() {
+        String patString = "abcd\uD8D3";
+        String testString = "abcd\uD8D3abc";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
     }
 
-    public void testPredefinedClassesWithSurrogatesSupplementary() {
+    public void testSequencesWithSurrogatesSupplementaryCase3() {
+        String patString = "ab\uDBEFcd";
+        String testString = "ab\uDBEFcd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.matches());
+    }
+
+    public void testSequencesWithSurrogatesSupplementaryCase4() {
+        String patString = "\uDFFCabcd";
+        String testString = "\uD8D3\uDFFCabcd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertFalse(mat.find());
+    }
+
+    public void testSequencesWithSurrogatesSupplementaryCase5() {
+        String patString = "\uDFFCabcd";
+        String testString = "abc\uDFFCabcdecd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.find());
+    }
+
+    public void testSequencesWithSurrogatesSupplementaryCase6String () {
+        String patString = "\uD8D3\uDFFCabcd";
+        String testString = "abc\uD8D3\uD8D3\uDFFCabcd";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
+        assertTrue(mat.find());
+    }
+
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase1() {
         String patString = "[123\\D]";
         String testString = "a";
         Pattern pat = Pattern.compile(patString);
         Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        testString = "5";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase2() {
+        String patString = "[123\\D]";
+        String testString = "5";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.find());
+    }
 
-        testString = "3";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase3() {
+        String patString = "[123\\D]";
+        String testString = "3";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase4() {
         // low surrogate
-        testString = "\uDFC4";
-        mat = pat.matcher(testString);
+        String patString = "[123\\D]";
+        String testString = "\uDFC4";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase5() {
         // high surrogate
-        testString = "\uDADA";
-        mat = pat.matcher(testString);
+        String patString = "[123\\D]";
+        String testString = "\uDADA";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        testString = "\uDADA\uDFC4";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase6() {
+        String patString = "[123\\D]";
+        String testString = "\uDADA\uDFC4";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        patString = "[123[^\\p{javaDigit}]]";
-        testString = "a";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase7() {
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "a";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        testString = "5";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase8() {
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "5";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.find());
+    }
 
-        testString = "3";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase9() {
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "3";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase10() {
         // low surrogate
-        testString = "\uDFC4";
-        mat = pat.matcher(testString);
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "\uDFC4";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase11() {
         // high surrogate
-        testString = "\uDADA";
-        mat = pat.matcher(testString);
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "\uDADA";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        testString = "\uDADA\uDFC4";
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase12() {
+        String patString = "[123[^\\p{javaDigit}]]";
+        String testString = "\uDADA\uDFC4";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase13() {
         // surrogate characters
-        patString = "\\p{Cs}";
-        testString = "\uD916\uDE27";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
-
+        String patString = "\\p{Cs}";
+        String testString = "\uD916\uDE27";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         /*
          * see http://www.unicode.org/reports/tr18/#Supplementary_Characters we
          * have to treat text as code points not code units. \\p{Cs} matches any
@@ -1313,69 +1590,104 @@
          * nothing
          */
         // assertFalse(mat.find());
+    }
+
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase14() {
         // swap low and high surrogates
-        testString = "\uDE27\uD916";
-        mat = pat.matcher(testString);
+        String patString = "\\p{Cs}";
+        String testString = "\uDE27\uD916";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        patString = "[\uD916\uDE271\uD91623&&[^\\p{Cs}]]";
-        testString = "1";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase15() {
+        String patString = "[\uD916\uDE271\uD91623&&[^\\p{Cs}]]";
+        String testString = "1";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
-        testString = "\uD916";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase16() {
+        String patString = "[\uD916\uDE271\uD91623&&[^\\p{Cs}]]";
+        String testString = "\uD916";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.find());
+    }
 
-        testString = "\uD916\uDE27";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase17() {
+        String patString = "[\uD916\uDE271\uD91623&&[^\\p{Cs}]]";
+        String testString = "\uD916\uDE27";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.find());
+    }
 
+    public void testPredefinedClassesWithSurrogatesSupplementaryCase18() {
         // \uD9A0\uDE8E=\u7828E
         // \u78281=\uD9A0\uDE81
-        patString = "[a-\uD9A0\uDE8E]";
-        testString = "\uD9A0\uDE81";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+        String patString = "[a-\uD9A0\uDE8E]";
+        String testString = "\uD9A0\uDE81";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
     }
 
-    public void testDotConstructionWithSurrogatesSupplementary() {
+    public void testDotConstructionWithSurrogatesSupplementaryCase1() {
         String patString = ".";
         String testString = "\uD9A0\uDE81";
         Pattern pat = Pattern.compile(patString);
         Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        testString = "\uDE81";
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase2() {
+        String patString = ".";
+        String testString = "\uDE81";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        testString = "\uD9A0";
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase3() {
+        String patString = ".";
+        String testString = "\uD9A0";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        testString = "\n";
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase4() {
+        String patString = ".";
+        String testString = "\n";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        patString = ".*\uDE81";
-        testString = "\uD9A0\uDE81\uD9A0\uDE81\uD9A0\uDE81";
-        pat = Pattern.compile(patString);
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase5() {
+        String patString = ".*\uDE81";
+        String testString = "\uD9A0\uDE81\uD9A0\uDE81\uD9A0\uDE81";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertFalse(mat.matches());
+    }
 
-        testString = "\uD9A0\uDE81\uD9A0\uDE81\uDE81";
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase6() {
+        String patString = ".*\uDE81";
+        String testString = "\uD9A0\uDE81\uD9A0\uDE81\uDE81";
+        Pattern pat = Pattern.compile(patString);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
+    }
 
-        patString = ".*";
-        testString = "\uD9A0\uDE81\n\uD9A0\uDE81\uD9A0\n\uDE81";
-        pat = Pattern.compile(patString, Pattern.DOTALL);
-        mat = pat.matcher(testString);
+    public void testDotConstructionWithSurrogatesSupplementaryCase7() {
+        String patString = ".*";
+        String testString = "\uD9A0\uDE81\n\uD9A0\uDE81\uD9A0\n\uDE81";
+        Pattern pat = Pattern.compile(patString, Pattern.DOTALL);
+        Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
     }
 
@@ -1430,7 +1742,9 @@
         Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
 
+        patString = "\uD9A0\uDE81*abc";
         testString = "abc";
+        pat = Pattern.compile(patString);
         mat = pat.matcher(testString);
         assertTrue(mat.matches());
     }
@@ -1442,21 +1756,26 @@
         Matcher mat = pat.matcher(testString);
         assertTrue(mat.matches());
 
+        patString = "\uDE81|\uD9A0\uDE81|\uD9A0";
         testString = "\uDE81";
+        pat = Pattern.compile(patString);
         mat = pat.matcher(testString);
         assertTrue(mat.matches());
 
+        patString = "\uDE81|\uD9A0\uDE81|\uD9A0";
         testString = "\uD9A0\uDE81";
+        pat = Pattern.compile(patString);
         mat = pat.matcher(testString);
         assertTrue(mat.matches());
 
+        patString = "\uDE81|\uD9A0\uDE81|\uD9A0";
         testString = "\uDE81\uD9A0";
+        pat = Pattern.compile(patString);
         mat = pat.matcher(testString);
         assertFalse(mat.matches());
     }
 
     public void testGroupsWithSurrogatesSupplementary() {
-
         //this pattern matches nothing
         String patString = "(\uD9A0)\uDE81";
         String testString = "\uD9A0\uDE81";
@@ -1868,15 +2187,22 @@
     }
 
     public void testSplitAsStream() {
-        String s[];
-        Pattern pat = Pattern.compile("b");
+        Pattern pat;
+        String[] s;
+
+        pat = Pattern.compile("b");
         s = pat.splitAsStream("abccbadfebb").toArray(String[]::new);
         assertEquals(s.length, 3);
+
+        pat = Pattern.compile("b");
         s = pat.splitAsStream("").toArray(String[]::new);
         assertEquals(s.length, 0);
+
         pat = Pattern.compile("");
         s = pat.splitAsStream("").toArray(String[]::new);
         assertEquals(s.length, 0);
+
+        pat = Pattern.compile("");
         s = pat.splitAsStream("abccbadfe").toArray(String[]::new);
         assertEquals(s.length, 9);
     }
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/luni/src/test/java/tests/com/android/org/bouncycastle/crypto/digests/DigestTest.java b/luni/src/test/java/tests/com/android/org/bouncycastle/crypto/digests/DigestTest.java
new file mode 100644
index 0000000..3cf8071
--- /dev/null
+++ b/luni/src/test/java/tests/com/android/org/bouncycastle/crypto/digests/DigestTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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 tests.com.android.org.bouncycastle.crypto.digests;
+
+import junit.framework.TestCase;
+
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.org.bouncycastle.crypto.digests.MD5Digest;
+import com.android.org.bouncycastle.crypto.digests.OpenSSLDigest;
+import com.android.org.bouncycastle.crypto.digests.SHA1Digest;
+import com.android.org.bouncycastle.crypto.digests.SHA256Digest;
+import com.android.org.bouncycastle.crypto.digests.SHA384Digest;
+import com.android.org.bouncycastle.crypto.digests.SHA512Digest;
+import tests.util.SummaryStatistics;
+
+/**
+ * Implements unit tests for our JNI wrapper around OpenSSL. We use the
+ * existing Bouncy Castle implementation as our test oracle.
+ */
+public class DigestTest extends TestCase {
+
+    /**
+     * Processes the two given message digests for the same data and checks
+     * the results. Requirement is that the results must be equal, the digest
+     * implementations must have the same properties, and the new implementation
+     * must be faster than the old one.
+     *
+     * @param oldDigest The old digest implementation, provided by Bouncy Castle
+     * @param newDigest The new digest implementation, provided by OpenSSL
+     */
+    public void doTestMessageDigest(Digest oldDigest, Digest newDigest) {
+        final int WARMUP = 10;
+        final int ITERATIONS = 100;
+
+        byte[] data = new byte[1024];
+
+        byte[] oldHash = new byte[oldDigest.getDigestSize()];
+        byte[] newHash = new byte[newDigest.getDigestSize()];
+
+        assertEquals("Hash names must be equal",
+                     oldDigest.getAlgorithmName(), newDigest.getAlgorithmName());
+        assertEquals("Hash sizes must be equal",
+                     oldHash.length, newHash.length);
+        assertEquals("Hash block sizes must be equal",
+                     ((ExtendedDigest)oldDigest).getByteLength(),
+                     ((ExtendedDigest)newDigest).getByteLength());
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (byte)i;
+        }
+
+        SummaryStatistics oldTime = new SummaryStatistics();
+        SummaryStatistics newTime = new SummaryStatistics();
+
+        for (int j = 0; j < ITERATIONS + WARMUP; j++) {
+            long t0 = System.nanoTime();
+            for (int i = 0; i < 4; i++) {
+                oldDigest.update(data, 0, data.length);
+            }
+            int oldLength = oldDigest.doFinal(oldHash, 0);
+            long t1 = System.nanoTime();
+
+            if (j >= WARMUP) {
+                oldTime.add(t1 - t0);
+            }
+
+            long t2 = System.nanoTime();
+            for (int i = 0; i < 4; i++) {
+                newDigest.update(data, 0, data.length);
+            }
+            int newLength = newDigest.doFinal(newHash, 0);
+            long t3 = System.nanoTime();
+
+            if (j >= WARMUP) {
+              newTime.add(t3 - t2);
+            }
+
+            assertEquals("Hash sizes must be equal", oldLength, newLength);
+
+            for (int i = 0; i < oldLength; i++) {
+                assertEquals("Hashes[" + i + "] must be equal", oldHash[i], newHash[i]);
+            }
+        }
+
+        System.out.println("Time for " + ITERATIONS + " x old hash processing: "
+                + oldTime.toString());
+        System.out.println("Time for " + ITERATIONS + " x new hash processing: "
+                + newTime.toString());
+    }
+
+    /**
+     * Tests the MD5 implementation.
+     */
+    public void testMD5() {
+        Digest oldDigest = new MD5Digest();
+        Digest newDigest = new OpenSSLDigest.MD5();
+        doTestMessageDigest(oldDigest, newDigest);
+    }
+
+    /**
+     * Tests the SHA-1 implementation.
+     */
+    public void testSHA1() {
+        Digest oldDigest = new SHA1Digest();
+        Digest newDigest = new OpenSSLDigest.SHA1();
+        doTestMessageDigest(oldDigest, newDigest);
+    }
+
+    /**
+     * Tests the SHA-256 implementation.
+     */
+    public void testSHA256() {
+        Digest oldDigest = new SHA256Digest();
+        Digest newDigest = new OpenSSLDigest.SHA256();
+        doTestMessageDigest(oldDigest, newDigest);
+    }
+
+    /**
+     * Tests the SHA-384 implementation.
+     */
+    public void testSHA384() {
+        Digest oldDigest = new SHA384Digest();
+        Digest newDigest = new OpenSSLDigest.SHA384();
+        doTestMessageDigest(oldDigest, newDigest);
+    }
+
+    /**
+     * Tests the SHA-512 implementation.
+     */
+    public void testSHA512() {
+        Digest oldDigest = new SHA512Digest();
+        Digest newDigest = new OpenSSLDigest.SHA512();
+        doTestMessageDigest(oldDigest, newDigest);
+    }
+}
diff --git a/luni/src/test/java/tests/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java b/luni/src/test/java/tests/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
new file mode 100644
index 0000000..40ba176
--- /dev/null
+++ b/luni/src/test/java/tests/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2012 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 tests.com.android.org.bouncycastle.jce.provider;
+
+import junit.framework.TestCase;
+
+import com.android.org.bouncycastle.jce.provider.CertBlacklist;
+import com.android.org.bouncycastle.util.encoders.Base64;
+import com.android.org.bouncycastle.util.encoders.Hex;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CertBlacklistTest extends TestCase {
+
+    private File tmpFile;
+
+    private Set<String> DEFAULT_PUBKEYS;
+    private Set<String> DEFAULT_SERIALS;
+
+    public static final String TEST_CERT = "" +
+                    "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" +
+                    "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" +
+                    "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" +
+                    "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" +
+                    "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" +
+                    "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" +
+                    "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" +
+                    "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" +
+                    "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" +
+                    "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" +
+                    "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" +
+                    "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" +
+                    "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" +
+                    "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" +
+                    "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" +
+                    "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" +
+                    "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM=";
+
+    public static final String TURKTRUST_1 = "" +
+                    "MIIFPTCCBCWgAwIBAgICCCcwDQYJKoZIhvcNAQEFBQAwgawxPTA7BgNVBAMMNFTDnFJLVFJVU1Qg" +
+                    "RWxla3Ryb25payBTdW51Y3UgU2VydGlmaWthc8SxIEhpem1ldGxlcmkxCzAJBgNVBAYTAlRSMV4w" +
+                    "XAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE" +
+                    "n2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtICAyMDA1MB4XDTExMDgwODA3MDc1MVoXDTIx" +
+                    "MDcwNjA3MDc1MVowbjELMAkGA1UEBhMCVFIxDzANBgNVBAgMBkFOS0FSQTEPMA0GA1UEBwwGQU5L" +
+                    "QVJBMQwwCgYDVQQKDANFR08xGDAWBgNVBAsMD0VHTyBCSUxHSSBJU0xFTTEVMBMGA1UEAwwMKi5F" +
+                    "R08uR09WLlRSMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5zoj2Bpdl7R1M/zF6Qf" +
+                    "4su2F8vDqISKvuTuyJhNAHhFGHCsHjaixGMHspuz0l3V50kq/ECWbN8kKaeTrB112QOrWTU276iu" +
+                    "p1Gh+OlEOiR9vlQ4VAP00dWUjD6z9HQFCi8W3EsEtiiHiYOU9BcPpPkaUbECwP4nGVwR8aPwhB5P" +
+                    "GBJc98romdvciYkUpSOOwkuSRtooA7tRlLFu72QaNpXN1NueB36I3aajPk0YyiXy2w8XlgK7QI4P" +
+                    "SSBnSq+QblFocWVmLhF94je7py6lCnllrIFXpR3FWZLD5GcI6HKlBS78AQ+IMBLFHhsEVw5NQj90" +
+                    "chSZClfBWBZzIaV9RwIDAQABo4IBpDCCAaAwHwYDVR0jBBgwFoAUq042AzDS29UKaL6HpVBs/PZw" +
+                    "pSUwHQYDVR0OBBYEFGT7G4Y9uEryRIL5Vj3qJsD047M0MA4GA1UdDwEB/wQEAwIBBjBFBgNVHSAE" +
+                    "PjA8MDoGCWCGGAMAAwEBATAtMCsGCCsGAQUFBwIBFh9odHRwOi8vd3d3LnR1cmt0cnVzdC5jb20u" +
+                    "dHIvc3VlMA8GA1UdEwEB/wQFMAMBAf8wSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL3d3dy50dXJr" +
+                    "dHJ1c3QuY29tLnRyL3NpbC9UVVJLVFJVU1RfU1NMX1NJTF9zMi5jcmwwgaoGCCsGAQUFBwEBBIGd" +
+                    "MIGaMG4GCCsGAQUFBzAChmJodHRwOi8vd3d3LnR1cmt0cnVzdC5jb20udHIvc2VydGlmaWthbGFy" +
+                    "L1RVUktUUlVTVF9FbGVrdHJvbmlrX1N1bnVjdV9TZXJ0aWZpa2FzaV9IaXptZXRsZXJpX3MyLmNy" +
+                    "dDAoBggrBgEFBQcwAYYcaHR0cDovL29jc3AudHVya3RydXN0LmNvbS50cjANBgkqhkiG9w0BAQUF" +
+                    "AAOCAQEAj89QCCyoW0S20EcYDZAnvFLFmougK97Bt68iV1OM622+Cyeyf4Sz+1LBk1f9ni3fGT0Q" +
+                    "+RWZJYWq5YuSBiLVgk3NLcxnwe3wmnvErUgq1QDtAaNlBWMEMklOlWGfJ0eWaillUskJbDd4KwgZ" +
+                    "HDEj7g/jYEQqU1t0zoJdwM/zNsnLHkhwcWZ5PQnnbpff1Ct/1LH/8pdy2eRDmRmqniLUh8r2lZfJ" +
+                    "eudVZG6yIbxsqP3t2JCq5c2P1jDhAGF3g9DiskH0CzsRdbVpoWdr+PY1Xz/19G8XEpX9r+IBJhLd" +
+                    "bkpVo0Qh0A10mzFP/GUk5f/8nho2HvLaVMhWv1qKcF8IhQ==";
+
+    public static final String TURKTRUST_2 = "" +
+                    "MIID8DCCAtigAwIBAgICCGQwDQYJKoZIhvcNAQEFBQAwgawxPTA7BgNVBAMMNFTDnFJLVFJVU1Qg" +
+                    "RWxla3Ryb25payBTdW51Y3UgU2VydGlmaWthc8SxIEhpem1ldGxlcmkxCzAJBgNVBAYTAlRSMV4w" +
+                    "XAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE" +
+                    "n2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtICAyMDA1MB4XDTExMDgwODA3MDc1MVoXDTIx" +
+                    "MDgwNTA3MDc1MVowgaMxCzAJBgNVBAYTAlRSMRAwDgYDVQQIEwdMZWZrb3NhMRAwDgYDVQQHEwdM" +
+                    "ZWZrb3NhMRwwGgYDVQQKExNLS1RDIE1lcmtleiBCYW5rYXNpMSYwJAYDVQQDEx1lLWlzbGVtLmtr" +
+                    "dGNtZXJrZXpiYW5rYXNpLm9yZzEqMCgGCSqGSIb3DQEJARYbaWxldGlAa2t0Y21lcmtlemJhbmth" +
+                    "c2kub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1hUpuRFY67NsZ6C9rzRAPCb" +
+                    "9RVpi4nZzJIA1TvIfr4hMPM0X5jseMf5GvgJQ+cBMZtooDd7BbZNy2z7O5A+8PYFaMDdokCENx2e" +
+                    "PIqAVuO6C5UAqM7J3n6RrhjOvqiw6dTQMbtXhjFao+YMuBVvRuuhGHBDK3Je64T/KLzcmAUlRJEu" +
+                    "y+ZMe7AatUaSDr/jy5DMA5xEYOdsnS5Zo30lRG+9vqbxb8CQi+E97sNjY+W4lEgJKQWMNh5rCxo4" +
+                    "Hinkm3CKyKX3PAS+DDVI3LQiCiIQUOMA2+1P5aTPTkpqlbjqhbWTWAPWOKCF9d83p3RMXOYt5Gah" +
+                    "S8rg5u6+toEC1QIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkq" +
+                    "hkiG9w0BAQUFAAOCAQEAwjWz5tsUvYORVW8KJSK/biHFrAnFotMtoTKEewRmnYaYjwXIr1IPaBqh" +
+                    "jkGGviLN2eOH/v97Uli6HC4lzhKHfMQUS9KF/f5nGcH8iQBy/gmFsfJQ1KDC6GNM4CfMGIzyxjYh" +
+                    "P0VzdUtKX3PAl5EqgMUcdqRDy6Ruz55+JkdvCL1nAC7xH+czJcZVwysTdGfLTCh6VtYPgIkeL6U8" +
+                    "3xQAyMuOHm72exJljYFqIsiNvGE0KufCqCuH1PD97IXMrLlwGmKKg5jP349lySBpJjm6RDqCTT+6" +
+                    "dUl2jkVbeNmco99Y7AOdtLsOdXBMCo5x8lK8zwQWFrzEms0joHXCpWfGWA==";
+
+    public static final String ANSSI = "" +
+                    "MIIDbDCCAlSgAwIBAgIDAx2nMA0GCSqGSIb3DQEBBQUAMEsxCzAJBgNVBAYTAkZSMQ4wDAYDVQQK" +
+                    "EwVER1RQRTEsMCoGA1UEAxMjQUMgREdUUEUgU2lnbmF0dXJlIEF1dGhlbnRpZmljYXRpb24wHhcN" +
+                    "MTMwNzE4MTAwNTI4WhcNMTQwNzE4MTAwNTI4WjA+MQswCQYDVQQGEwJGUjETMBEGA1UECgwKREcg" +
+                    "VHLDqXNvcjEaMBgGA1UEAwwRQUMgREcgVHLDqXNvciBTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IB" +
+                    "DwAwggEKAoIBAQDI0WFSUyY+MmtFkqFjTefoFyDgh9b1C/2YvSIvT8oCH62JWT5rpeTCZwaXbqWc" +
+                    "jaNfzggqaFsokqfhBif43HNHNtNJmvKE32VcuLB0SpsLR/1VeTd9F99C1JeHVa+nelumOHEfouX8" +
+                    "rRFrxNXNIYTVeiENT8Y2YqRb/XAril9g7i674uFzLiNR/t/N/F8Exujv9U8m8rmgud/+tG9WDRaD" +
+                    "Jwoj3ZFCOnL5qLnSUEcS6TzWpozLmC2JVO5GZKGGd7qC9FjdBkVilkbVIEGSrYvz2Uz2v5IGqMBI" +
+                    "QaFL/kSYWxGTaedTOk2drFEApp9AEPTfv1NwCWBfegsGQrHUROM3AgMBAAGjZjBkMBIGA1UdEwEB" +
+                    "/wQIMAYBAf8CAQQwHQYDVR0OBBYEFAAMW8lJqJW0DtAv5p3Mjogxvh9lMB8GA1UdIwQYMBaAFOnb" +
+                    "kI/9W5nkFTvwYlyn5A1Y6IeZMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAtDfG" +
+                    "HkHOLW2d9fiMtwtkEwDauISJLJyCjoRmawzmQbIZXq7HaLliVfE0sdfKUm0iQ0im1/CpnJLPoTeK" +
+                    "yBHvNu1ubLc2m+9dabAYhF3pVdKC+gNaAzBXZ9Gt0p1CLk1lf8Hg+R10HN2IPCv7V/crz2Ga+c23" +
+                    "4P3pfwYW8+Nd7alGCuvqot6UYXOlheF7zWUkHn6z6tvY+9oMDHKSUAthhA/FB50JgJU89zyTv1eg" +
+                    "Y3ldKwvYBW3W3yNZdTHbPyNsPJdhqA55mDNsteE5YTp1PyySDb1MSVrbxDEruoH6ZE99Hob4Ih8A" +
+                    "mn7MHZatGClECgjXWFZ2Gxa7OUCaQpcH8g==";
+
+    public CertBlacklistTest() throws IOException {
+        tmpFile = File.createTempFile("test", "");
+        DEFAULT_PUBKEYS = getDefaultPubkeys();
+        DEFAULT_SERIALS = getDefaultSerials();
+        tmpFile.delete();
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        tmpFile = File.createTempFile("test", "");
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            tmpFile.delete();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    private Set<String> getPubkeyBlacklist(String path) throws IOException {
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist(path, "");
+        // call readPubkeyBlacklist
+        Set<byte[]> arr = bl.pubkeyBlacklist;
+        // convert the results to a hashset of strings
+        Set<String> results = new HashSet<String>();
+        for (byte[] value: arr) {
+            results.add(new String(value));
+        }
+        return results;
+    }
+
+    private Set<String> getSerialBlacklist(String path) throws IOException {
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist("", path);
+        // call readPubkeyBlacklist
+        Set<BigInteger> arr = bl.serialBlacklist;
+        // convert the results to a hashset of strings
+        Set<String> results = new HashSet<String>();
+        for (BigInteger value: arr) {
+            results.add(value.toString(16));
+        }
+        return results;
+    }
+
+    private static String getHash(PublicKey publicKey) throws Exception {
+        byte[] encoded = publicKey.getEncoded();
+        MessageDigest digest = MessageDigest.getInstance("SHA1");
+        byte[] hexlifiedHash = Hex.encode(digest.digest(encoded));
+        return new String(hexlifiedHash);
+    }
+
+    private Set<String> getDefaultPubkeys() throws IOException {
+        return getPubkeyBlacklist("");
+    }
+
+    private Set<String> getDefaultSerials() throws IOException {
+        return getSerialBlacklist("");
+    }
+
+    private Set<String> getCurrentPubkeyBlacklist() throws IOException {
+        return getPubkeyBlacklist(tmpFile.getCanonicalPath());
+    }
+
+    private Set<String> getCurrentSerialBlacklist() throws IOException {
+        return getSerialBlacklist(tmpFile.getCanonicalPath());
+    }
+
+    private void blacklistToFile(String blacklist) throws IOException {
+        FileOutputStream out = new FileOutputStream(tmpFile);
+        out.write(blacklist.toString().getBytes());
+        out.close();
+    }
+
+    private void writeBlacklist(HashSet<String> values) throws IOException {
+        StringBuilder result = new StringBuilder();
+        // join the values into a string
+        for (String value : values) {
+            if (result.length() != 0) {
+                result.append(",");
+            }
+            result.append(value);
+        }
+        blacklistToFile(result.toString());
+    }
+
+    private static PublicKey createPublicKey(String cert) throws Exception {
+        byte[] derCert = Base64.decode(cert.getBytes());
+        InputStream istream = new ByteArrayInputStream(derCert);
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        return cf.generateCertificate(istream).getPublicKey();
+    }
+
+    private static BigInteger createSerialNumber(String cert) throws Exception {
+        byte[] derCert = Base64.decode(cert.getBytes());
+        InputStream istream = new ByteArrayInputStream(derCert);
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        X509Certificate xCert = (X509Certificate)cf.generateCertificate(istream);
+        return xCert.getSerialNumber();
+    }
+
+    public void testPubkeyBlacklistLegit() throws Exception {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default pubkeys into the bl
+        bl.addAll(DEFAULT_PUBKEYS);
+        // do the test
+        assertEquals(bl, getCurrentPubkeyBlacklist());
+    }
+
+    public void testLegitPubkeyIsntBlacklisted() throws Exception {
+        // build the public key
+        PublicKey pk = createPublicKey(TEST_CERT);
+        // write that to the test blacklist
+        writeBlacklist(new HashSet<String>());
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), "");
+        // check to make sure it isn't blacklisted
+        assertEquals(bl.isPublicKeyBlackListed(pk), false);
+    }
+
+    public void testPubkeyIsBlacklisted() throws Exception {
+        // build the public key
+        PublicKey pk = createPublicKey(TEST_CERT);
+        // get its hash
+        String hash = getHash(pk);
+        // write that to the test blacklist
+        HashSet<String> testBlackList = new HashSet<String>();
+        testBlackList.add(hash);
+        writeBlacklist(testBlackList);
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), "");
+        // check to make sure it isn't blacklited
+        assertTrue(bl.isPublicKeyBlackListed(pk));
+    }
+
+    public void testSerialBlacklistLegit() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default serials into the bl
+        bl.addAll(DEFAULT_SERIALS);
+        // do the test
+        assertEquals(bl, getCurrentSerialBlacklist());
+    }
+
+    public void testPubkeyBlacklistMultipleLegit() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default pubkeys into the bl
+        bl.addAll(DEFAULT_PUBKEYS);
+        // do the test
+        assertEquals(bl, getCurrentPubkeyBlacklist());
+    }
+
+    public void testSerialBlacklistMultipleLegit() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
+        bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default serials into the bl
+        bl.addAll(DEFAULT_SERIALS);
+        // do the test
+        assertEquals(bl, getCurrentSerialBlacklist());
+    }
+
+    public void testPubkeyBlacklistMultipleBad() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
+        bl.add("");
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default pubkeys into the bl
+        bl.addAll(DEFAULT_PUBKEYS);
+        // remove the bad one
+        bl.remove("");
+        // do the test- results should be all but the bad one are handled
+        assertEquals(bl, getCurrentPubkeyBlacklist());
+    }
+
+    public void testSerialBlacklistMultipleBad() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
+        bl.add("");
+        bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default serials into the bl
+        bl.addAll(DEFAULT_SERIALS);
+        // remove the bad one
+        bl.remove("");
+        // do the test- results should be all but the bad one are handled
+        assertEquals(bl, getCurrentSerialBlacklist());
+    }
+
+    public void testPubkeyBlacklistDoesntExist() throws IOException {
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+    }
+
+    public void testSerialBlacklistDoesntExist() throws IOException {
+        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
+    }
+
+    public void testPubkeyBlacklistNotHexValues() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
+        // write the blacklist
+        writeBlacklist(bl);
+        // do the test
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+    }
+
+    public void testSerialBlacklistNotHexValues() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
+        // write the blacklist
+        writeBlacklist(bl);
+        // do the test
+        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
+    }
+
+    public void testPubkeyBlacklistIncorrectLength() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091cc");
+        // write the blacklist
+        writeBlacklist(bl);
+        // do the test
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+    }
+
+    public void testSerialBlacklistZero() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("0");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default serials
+        bl.addAll(DEFAULT_SERIALS);
+        // do the test
+        assertEquals(bl, getCurrentSerialBlacklist());
+    }
+
+    public void testSerialBlacklistNegative() throws IOException {
+        // build the blacklist
+        HashSet<String> bl = new HashSet<String>();
+        bl.add("-1");
+        // write the blacklist
+        writeBlacklist(bl);
+        // add the default serials
+        bl.addAll(DEFAULT_SERIALS);
+        // do the test
+        assertEquals(bl, getCurrentSerialBlacklist());
+    }
+
+    public void testTurkTrustIntermediate1PubkeyBlacklist() throws Exception {
+        // build the public key
+        PublicKey pk = createPublicKey(TURKTRUST_1);
+        // write that to the test blacklist
+        writeBlacklist(new HashSet<String>());
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist();
+        // check to make sure it isn't blacklisted
+        assertEquals(bl.isPublicKeyBlackListed(pk), true);
+    }
+
+    public void testTurkTrustIntermediate2PubkeyBlacklist() throws Exception {
+        // build the public key
+        PublicKey pk = createPublicKey(TURKTRUST_2);
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist();
+        // check to make sure it isn't blacklisted
+        assertEquals(bl.isPublicKeyBlackListed(pk), true);
+    }
+
+    public void testANSSIIntermediatePubkeyBlacklist() throws Exception {
+        // build the public key
+        PublicKey pk = createPublicKey(ANSSI);
+        // set our blacklist path
+        CertBlacklist bl = new CertBlacklist();
+        // check to make sure it isn't blacklisted
+        assertEquals(bl.isPublicKeyBlackListed(pk), true);
+    }
+
+    private static void printHash(String cert) throws Exception {
+        System.out.println("CERTIFICATE PUBLIC KEY HASH: " + getHash(createPublicKey(cert)));
+    }
+
+    private static void printSerial(String cert) throws Exception {
+        System.out.println("CERTIFICATE SERIAL NUMBER: " + createSerialNumber(cert).toString(16));
+    }
+}
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTest.java b/luni/src/test/java/tests/targets/security/MessageDigestTest.java
new file mode 100644
index 0000000..553119f
--- /dev/null
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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 tests.targets.security;
+
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.Locale;
+import junit.framework.TestCase;
+
+public abstract class MessageDigestTest extends TestCase {
+
+    private String digestAlgorithmName;
+
+    MessageDigestTest(String digestAlgorithmName) {
+        super();
+        this.digestAlgorithmName = digestAlgorithmName;
+    }
+
+    private MessageDigest digest;
+    private InputStream sourceData;
+    private byte[] checkDigest;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        this.source3 = getLongMessage(1000000);
+        this.digest = MessageDigest.getInstance(digestAlgorithmName);
+        this.sourceData = getSourceData();
+        this.checkDigest = getCheckDigest();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        // This is critical. The MessageDigest tests consume a lot of memory due
+        // to the 1 MB buffers being allocated. We need to make sure all data is
+        // freed after each test. Otherwise the Android runtime simply dies at
+        // some point.
+        source1 = null;
+        source2 = null;
+        source3 = null;
+
+        expected1 = null;
+        expected2 = null;
+        expected3 = null;
+
+        digest = null;
+        sourceData.close();
+        sourceData = null;
+        checkDigest = null;
+
+        System.gc();
+    }
+
+    private InputStream getSourceData() {
+        InputStream sourceStream = getClass().getResourceAsStream(digestAlgorithmName + ".data");
+        assertNotNull("digest source data not found: " + digestAlgorithmName, sourceStream);
+        return sourceStream;
+    }
+
+    private byte[] getCheckDigest() throws Exception {
+        InputStream checkDigestStream =
+                getClass().getResourceAsStream(digestAlgorithmName + ".check");
+        byte[] checkDigest = new byte[digest.getDigestLength()];
+        int read;
+        int index = 0;
+        while ((read = checkDigestStream.read()) != -1) {
+            checkDigest[index++] = (byte)read;
+        }
+        checkDigestStream.close();
+        return checkDigest;
+    }
+
+    public void testMessageDigest1() throws Exception {
+        byte[] buf = new byte[128];
+        int read;
+        while ((read = sourceData.read(buf)) != -1) {
+            digest.update(buf, 0, read);
+        }
+        sourceData.close();
+
+        byte[] computedDigest = digest.digest();
+
+        assertNotNull("computed digest is is null", computedDigest);
+        assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
+
+        for (int i = 0; i < checkDigest.length; i++) {
+            assertEquals("byte " + i + " of computed and check digest differ",
+                         checkDigest[i], computedDigest[i]);
+        }
+    }
+
+    public void testMessageDigest2() throws Exception {
+        int val;
+        while ((val = sourceData.read()) != -1) {
+            digest.update((byte)val);
+        }
+        sourceData.close();
+
+        byte[] computedDigest = digest.digest();
+
+        assertNotNull("computed digest is is null", computedDigest);
+        assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
+
+        for (int i = 0; i < checkDigest.length; i++) {
+            assertEquals("byte " + i + " of computed and check digest differ",
+                         checkDigest[i], computedDigest[i]);
+        }
+    }
+
+
+    /**
+     * Official FIPS180-2 testcases
+     */
+
+    String source1;
+    String source2;
+    private String source3;
+    String expected1;
+    String expected2;
+    String expected3;
+
+    private String getLongMessage(int length) {
+        StringBuilder sourceBuilder = new StringBuilder(length);
+        for (int i = 0; i < length / 10; i++) {
+            sourceBuilder.append("aaaaaaaaaa");
+        }
+        return sourceBuilder.toString();
+    }
+
+    public void testfips180_2_singleblock() {
+
+        digest.update(source1.getBytes(), 0, source1.length());
+
+        byte[] computedDigest = digest.digest();
+
+        assertNotNull("computed digest is null", computedDigest);
+
+        String actual = digestToString(computedDigest);
+        assertEquals("computed and check digest differ", expected1, actual);
+    }
+
+    private String digestToString(byte[] computedDigest) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b : computedDigest) {
+          sb.append(String.format(Locale.US, "%02x", b));
+        }
+        return sb.toString();
+    }
+
+    public void testfips180_2_multiblock() {
+
+        digest.update(source2.getBytes(), 0, source2.length());
+
+        byte[] computedDigest = digest.digest();
+
+        assertNotNull("computed digest is null", computedDigest);
+
+        String actual = digestToString(computedDigest);
+        assertEquals("computed and check digest differ", expected2, actual);
+    }
+
+    public void testfips180_2_longMessage() {
+
+        digest.update(source3.getBytes(), 0, source3.length());
+
+        byte[] computedDigest = digest.digest();
+
+        assertNotNull("computed digest is null", computedDigest);
+
+        String actual = digestToString(computedDigest);
+        assertEquals("computed and check digest differ", expected3, actual);
+    }
+}
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestMD5.java b/luni/src/test/java/tests/targets/security/MessageDigestTestMD5.java
index a997b1e..d0b3039 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestMD5.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestMD5.java
@@ -15,8 +15,6 @@
  */
 package tests.targets.security;
 
-import tests.security.MessageDigestTest;
-
 public class MessageDigestTestMD5 extends MessageDigestTest {
 
     public MessageDigestTestMD5() {
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA1.java b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
index a73da37..e4236c8 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
@@ -15,8 +15,6 @@
  */
 package tests.targets.security;
 
-import tests.security.MessageDigestTest;
-
 public class MessageDigestTestSHA1 extends MessageDigestTest {
 
     public MessageDigestTestSHA1() {
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA256.java b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
index 4813396..4009d59 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
@@ -15,8 +15,6 @@
  */
 package tests.targets.security;
 
-import tests.security.MessageDigestTest;
-
 public class MessageDigestTestSHA256 extends MessageDigestTest {
 
     public MessageDigestTestSHA256() {
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA384.java b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
index 29f9477..d873945 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
@@ -15,8 +15,6 @@
  */
 package tests.targets.security;
 
-import tests.security.MessageDigestTest;
-
 public class MessageDigestTestSHA384 extends MessageDigestTest {
 
     public MessageDigestTestSHA384() {
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA512.java b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
index b0f2c6b..e200c25 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
@@ -15,8 +15,6 @@
  */
 package tests.targets.security;
 
-import tests.security.MessageDigestTest;
-
 public class MessageDigestTestSHA512 extends MessageDigestTest {
 
     public MessageDigestTestSHA512() {
diff --git a/luni/src/test/resources/dalvik/system/bootoverride.jar b/luni/src/test/resources/dalvik/system/bootoverride.jar
index 1d6a9bb..2260f63 100644
--- a/luni/src/test/resources/dalvik/system/bootoverride.jar
+++ b/luni/src/test/resources/dalvik/system/bootoverride.jar
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/child.jar b/luni/src/test/resources/dalvik/system/child.jar
index abfbcac..22cb624 100644
--- a/luni/src/test/resources/dalvik/system/child.jar
+++ b/luni/src/test/resources/dalvik/system/child.jar
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/loading-test.dex b/luni/src/test/resources/dalvik/system/loading-test.dex
index 98fe21b..bd26fdc 100644
--- a/luni/src/test/resources/dalvik/system/loading-test.dex
+++ b/luni/src/test/resources/dalvik/system/loading-test.dex
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/loading-test.jar b/luni/src/test/resources/dalvik/system/loading-test.jar
index 3edea4c..55cbc98 100644
--- a/luni/src/test/resources/dalvik/system/loading-test.jar
+++ b/luni/src/test/resources/dalvik/system/loading-test.jar
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/loading-test2.dex b/luni/src/test/resources/dalvik/system/loading-test2.dex
index c50d984..77d83f8 100644
--- a/luni/src/test/resources/dalvik/system/loading-test2.dex
+++ b/luni/src/test/resources/dalvik/system/loading-test2.dex
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/loading-test2.jar b/luni/src/test/resources/dalvik/system/loading-test2.jar
index 4155a37..c5df6bd 100644
--- a/luni/src/test/resources/dalvik/system/loading-test2.jar
+++ b/luni/src/test/resources/dalvik/system/loading-test2.jar
Binary files differ
diff --git a/luni/src/test/resources/dalvik/system/parent.jar b/luni/src/test/resources/dalvik/system/parent.jar
index 9752ac9..e77e259 100644
--- a/luni/src/test/resources/dalvik/system/parent.jar
+++ b/luni/src/test/resources/dalvik/system/parent.jar
Binary files differ
diff --git a/metrictests/Android.mk b/metrictests/Android.mk
deleted file mode 100644
index c362718..0000000
--- a/metrictests/Android.mk
+++ /dev/null
@@ -1,17 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(call all-subdir-makefiles)
diff --git a/metrictests/memory/Android.mk b/metrictests/memory/Android.mk
deleted file mode 100644
index 9e5489c..0000000
--- a/metrictests/memory/Android.mk
+++ /dev/null
@@ -1,17 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(call all-subdir-makefiles)
\ No newline at end of file
diff --git a/metrictests/memory/apps/Android.bp b/metrictests/memory/apps/Android.bp
new file mode 100644
index 0000000..480886e
--- /dev/null
+++ b/metrictests/memory/apps/Android.bp
@@ -0,0 +1,21 @@
+// 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.
+
+android_test_helper_app {
+    name: "LibcoreHeapDumper",
+    sdk_version: "current",
+    resource_dirs: ["res"],
+    srcs: ["src/**/*.java"],
+    test_suites: ["general-tests"],
+}
diff --git a/metrictests/memory/apps/Android.mk b/metrictests/memory/apps/Android.mk
deleted file mode 100644
index 98a8ca8..0000000
--- a/metrictests/memory/apps/Android.mk
+++ /dev/null
@@ -1,30 +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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_PACKAGE_NAME := LibcoreHeapDumper
-LOCAL_SDK_VERSION := current
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_COMPATIBILITY_SUITE := general-tests
-
-include $(BUILD_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/metrictests/memory/apps/src/libcore/heapdumper/PssInstrumentation.java b/metrictests/memory/apps/src/libcore/heapdumper/PssInstrumentation.java
index f6feb35..35167ff 100644
--- a/metrictests/memory/apps/src/libcore/heapdumper/PssInstrumentation.java
+++ b/metrictests/memory/apps/src/libcore/heapdumper/PssInstrumentation.java
@@ -40,13 +40,12 @@
     protected void takeMeasurement(String label) throws IOException {
         ActivityManager activityManager = getContext().getSystemService(ActivityManager.class);
         tryRemoveGarbage();
-        Debug.MemoryInfo memoryInfo =
-                activityManager.getProcessMemoryInfo(new int[] { Process.myPid() })[0];
+        int totalPssKb = Math.toIntExact(Debug.getPss());
         File output = resolveRelativeOutputFilename(label + ".pss.txt");
         Charset cs = StandardCharsets.UTF_8;
         try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(output), cs)) {
-            writer.append(Integer.toString(memoryInfo.getTotalPss()));
+            writer.append(Integer.toString(totalPssKb));
         }
-        Log.i(TAG, "Wrote to total PSS in kB to " + output.getCanonicalPath());
+        Log.i(TAG, "Wrote to total PSS of " + totalPssKb + " kB to " + output.getCanonicalPath());
     }
 }
diff --git a/metrictests/memory/host/Android.bp b/metrictests/memory/host/Android.bp
new file mode 100644
index 0000000..a70afc6
--- /dev/null
+++ b/metrictests/memory/host/Android.bp
@@ -0,0 +1,23 @@
+// 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.
+
+java_test_host {
+    name: "libcore-memory-metrics-tests",
+    srcs: ["src/**/*.java"],
+    libs: [
+        "tradefed",
+        "ahat",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/metrictests/memory/host/Android.mk b/metrictests/memory/host/Android.mk
deleted file mode 100644
index cce0288..0000000
--- a/metrictests/memory/host/Android.mk
+++ /dev/null
@@ -1,32 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := libcore-memory-metrics-tests
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := tradefed ahat
-
-LOCAL_COMPATIBILITY_SUITE := general-tests
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
new file mode 100644
index 0000000..4210597
--- /dev/null
+++ b/mmodules/core_platform_api/Android.bp
@@ -0,0 +1,75 @@
+// 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_standard_libs: true,
+
+    installable: false,
+    args: "--hide-annotation libcore.api.Hide "
+        + "--show-single-annotation libcore.api.CorePlatformApi "
+        + "--skip-annotation-instance-methods=false ",
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
+
+    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.
+//
+// Although this stubs library is primarily used by the Java compiler / build to indicate
+// the core platform API surface area, compile_dex: true is used so that the Core Platform
+// API annotations are available to the dex tools that enable enforcement of runtime
+// accessibility. b/119068555
+java_library {
+    name: "core.platform.api.stubs",
+    srcs: [":core-platform-api-stubs"],
+    hostdex: true,
+    compile_dex: true,
+
+    no_standard_libs: true,
+    system_modules: "none",
+    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",
+        // This one is not on device but it's needed when javac compiles code
+        // containing lambdas.
+        "core-lambda-stubs-for-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..b2b81df
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -0,0 +1,1519 @@
+// Signature format: 2.0
+package android.icu.impl {
+
+  public class CalendarAstronomer {
+    ctor public CalendarAstronomer(double, double);
+    method public long getSunRiseSet(boolean);
+    method public void setTime(long);
+  }
+
+  public class TimeZoneAdapter extends java.util.TimeZone {
+    method public static java.util.TimeZone wrap(android.icu.util.TimeZone);
+  }
+
+}
+
+package android.icu.text {
+
+  public final class StringPrep {
+    method public static android.icu.text.StringPrep getInstance(int);
+    method public String prepare(String, int) throws android.icu.text.StringPrepParseException;
+    field public static final int DEFAULT = 0; // 0x0
+    field public static final int RFC3920_RESOURCEPREP = 8; // 0x8
+  }
+
+  public class StringPrepParseException extends java.text.ParseException {
+    ctor public StringPrepParseException(String, int);
+    ctor public StringPrepParseException(String, int, String, int);
+    ctor public StringPrepParseException(String, int, String, int, int);
+    method public int getError();
+    field public static final int ACE_PREFIX_ERROR = 6; // 0x6
+    field public static final int BUFFER_OVERFLOW_ERROR = 9; // 0x9
+    field public static final int CHECK_BIDI_ERROR = 4; // 0x4
+    field public static final int DOMAIN_NAME_TOO_LONG_ERROR = 11; // 0xb
+    field public static final int ILLEGAL_CHAR_FOUND = 1; // 0x1
+    field public static final int INVALID_CHAR_FOUND = 0; // 0x0
+    field public static final int LABEL_TOO_LONG_ERROR = 8; // 0x8
+    field public static final int PROHIBITED_ERROR = 2; // 0x2
+    field public static final int STD3_ASCII_RULES_ERROR = 5; // 0x5
+    field public static final int UNASSIGNED_ERROR = 3; // 0x3
+    field public static final int VERIFICATION_ERROR = 7; // 0x7
+    field public static final int ZERO_LENGTH_LABEL = 10; // 0xa
+  }
+
+}
+
+package android.icu.util {
+
+  public abstract class BasicTimeZone extends android.icu.util.TimeZone {
+    method public abstract android.icu.util.TimeZoneTransition getNextTransition(long, boolean);
+  }
+
+  public class Region implements java.lang.Comparable<android.icu.util.Region> {
+    method public static java.util.Set<android.icu.util.Region> getAvailable(android.icu.util.Region.RegionType);
+  }
+
+  public enum Region.RegionType {
+    enum_constant public static final android.icu.util.Region.RegionType TERRITORY;
+  }
+
+  public abstract class TimeZoneRule implements java.io.Serializable {
+    method public int getDSTSavings();
+  }
+
+  public class TimeZoneTransition {
+    method public android.icu.util.TimeZoneRule getFrom();
+    method public long getTime();
+    method public android.icu.util.TimeZoneRule getTo();
+  }
+
+}
+
+package android.system {
+
+  public final class ErrnoException extends java.lang.Exception {
+    method public java.io.IOException rethrowAsIOException() throws java.io.IOException;
+    method public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
+  }
+
+  public class Int32Ref {
+    ctor public Int32Ref(int);
+    field @dalvik.annotation.compat.UnsupportedAppUsage public int value;
+  }
+
+  public final class NetlinkSocketAddress extends java.net.SocketAddress {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public NetlinkSocketAddress(int, int);
+    method public int getGroupsMask();
+    method public int getPortId();
+  }
+
+  public final class Os {
+    method public static android.system.StructCapUserData[] capget(android.system.StructCapUserHeader) throws android.system.ErrnoException;
+    method public static void capset(android.system.StructCapUserHeader, android.system.StructCapUserData[]) throws android.system.ErrnoException;
+    method public static int fcntlInt(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int getpgid(int) throws android.system.ErrnoException;
+    method public static android.system.StructRlimit getrlimit(int) throws android.system.ErrnoException;
+    method public static int getsockoptInt(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static android.system.StructLinger getsockoptLinger(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int ioctlInt(java.io.FileDescriptor, int, android.system.Int32Ref) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor[] pipe2(int) throws android.system.ErrnoException;
+    method public static String realpath(String) throws android.system.ErrnoException;
+    method public static void setpgid(int, int) throws android.system.ErrnoException;
+    method public static void setregid(int, int) throws android.system.ErrnoException;
+    method public static void setreuid(int, int) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void setsockoptIfreq(java.io.FileDescriptor, int, int, String) throws android.system.ErrnoException;
+    method public static void setsockoptLinger(java.io.FileDescriptor, int, int, android.system.StructLinger) throws android.system.ErrnoException;
+    method public static long splice(java.io.FileDescriptor, android.system.Int64Ref, java.io.FileDescriptor, android.system.Int64Ref, long, int) throws android.system.ErrnoException;
+    method public static void unlink(String) throws android.system.ErrnoException;
+  }
+
+  public final class OsConstants {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static int CAP_TO_INDEX(int);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static int CAP_TO_MASK(int);
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int ENONET;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int EUSERS;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int MAP_POPULATE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int NETLINK_NETFILTER;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int O_DIRECT;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int PR_CAP_AMBIENT;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int PR_CAP_AMBIENT_RAISE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int RLIMIT_NOFILE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int RTMGRP_IPV4_IFADDR;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int SPLICE_F_MORE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int SPLICE_F_MOVE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int TIOCOUTQ;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int UDP_ENCAP;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int UDP_ENCAP_ESPINUDP;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int XATTR_CREATE;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int _LINUX_CAPABILITY_VERSION_3;
+  }
+
+  public final class PacketSocketAddress extends java.net.SocketAddress {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public PacketSocketAddress(short, int);
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public PacketSocketAddress(int, byte[]);
+  }
+
+  public final class StructCapUserData {
+    ctor public StructCapUserData(int, int, int);
+    field public final int effective;
+    field public final int inheritable;
+    field public final int permitted;
+  }
+
+  public final class StructCapUserHeader {
+    ctor public StructCapUserHeader(int, int);
+  }
+
+  public final class StructLinger {
+    ctor public StructLinger(int, int);
+    method public boolean isOn();
+    field public final int l_linger;
+  }
+
+  public final class StructRlimit {
+    field public final long rlim_cur;
+  }
+
+  public final class UnixSocketAddress extends java.net.SocketAddress {
+    method public static android.system.UnixSocketAddress createFileSystem(String);
+  }
+
+}
+
+package com.android.okhttp.internalandroidapi {
+
+  public final class AndroidResponseCacheAdapter {
+    ctor public AndroidResponseCacheAdapter(com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder);
+    method public void close() throws java.io.IOException;
+    method public void delete() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public java.net.CacheResponse get(java.net.URI, String, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder getCacheHolder();
+    method public int getHitCount();
+    method public long getMaxSize();
+    method public int getNetworkCount();
+    method public int getRequestCount();
+    method public long getSize() throws java.io.IOException;
+    method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
+  }
+
+  public interface Dns {
+    method public java.util.List<java.net.InetAddress> lookup(String) throws java.net.UnknownHostException;
+  }
+
+  public interface HasCacheHolder {
+    method public com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder getCacheHolder();
+  }
+
+  public static final class HasCacheHolder.CacheHolder {
+    method public static com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder create(java.io.File, long);
+    method public boolean isEquivalent(java.io.File, long);
+  }
+
+  public final class HttpURLConnectionFactory {
+    ctor public HttpURLConnectionFactory();
+    method public java.net.URLConnection openConnection(java.net.URL, javax.net.SocketFactory, java.net.Proxy) throws java.io.IOException;
+    method public void setDns(com.android.okhttp.internalandroidapi.Dns);
+    method public void setNewConnectionPool(int, long, java.util.concurrent.TimeUnit);
+  }
+
+}
+
+package com.android.org.bouncycastle.asn1 {
+
+  public abstract class ASN1BitString extends com.android.org.bouncycastle.asn1.ASN1Primitive {
+  }
+
+  public interface ASN1Encodable {
+  }
+
+  public class ASN1EncodableVector {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public ASN1EncodableVector();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void add(com.android.org.bouncycastle.asn1.ASN1Encodable);
+  }
+
+  public class ASN1InputStream extends java.io.FilterInputStream {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public ASN1InputStream(java.io.InputStream);
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public ASN1InputStream(byte[]);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public com.android.org.bouncycastle.asn1.ASN1Primitive readObject() throws java.io.IOException;
+  }
+
+  public class ASN1Integer extends com.android.org.bouncycastle.asn1.ASN1Primitive {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public ASN1Integer(java.math.BigInteger);
+  }
+
+  public abstract class ASN1Null extends com.android.org.bouncycastle.asn1.ASN1Primitive {
+  }
+
+  public abstract class ASN1Object implements com.android.org.bouncycastle.asn1.ASN1Encodable {
+    ctor public ASN1Object();
+    method public byte[] getEncoded() throws java.io.IOException;
+    method public byte[] getEncoded(String) throws java.io.IOException;
+  }
+
+  public class ASN1ObjectIdentifier extends com.android.org.bouncycastle.asn1.ASN1Primitive {
+    ctor public ASN1ObjectIdentifier(String);
+    method public String getId();
+    method public static com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier getInstance(Object);
+  }
+
+  public abstract class ASN1OctetString extends com.android.org.bouncycastle.asn1.ASN1Primitive implements com.android.org.bouncycastle.asn1.ASN1Encodable {
+    method public byte[] getOctets();
+  }
+
+  public abstract class ASN1Primitive extends com.android.org.bouncycastle.asn1.ASN1Object {
+    method public static com.android.org.bouncycastle.asn1.ASN1Primitive fromByteArray(byte[]) throws java.io.IOException;
+    method public com.android.org.bouncycastle.asn1.ASN1Primitive toASN1Primitive();
+  }
+
+  public abstract class ASN1Sequence extends com.android.org.bouncycastle.asn1.ASN1Primitive implements com.android.org.bouncycastle.util.Iterable<com.android.org.bouncycastle.asn1.ASN1Encodable> {
+    method public com.android.org.bouncycastle.asn1.ASN1Encodable getObjectAt(int);
+    method public int size();
+  }
+
+  public abstract class ASN1TaggedObject extends com.android.org.bouncycastle.asn1.ASN1Primitive implements com.android.org.bouncycastle.asn1.ASN1Encodable {
+    method public com.android.org.bouncycastle.asn1.ASN1Primitive getObject();
+  }
+
+  public class DERBitString extends com.android.org.bouncycastle.asn1.ASN1BitString {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public DERBitString(byte[]);
+  }
+
+  @Deprecated public class DERInteger extends com.android.org.bouncycastle.asn1.ASN1Integer {
+    ctor @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public DERInteger(long);
+  }
+
+  public class DERNull extends com.android.org.bouncycastle.asn1.ASN1Null {
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final com.android.org.bouncycastle.asn1.DERNull INSTANCE;
+  }
+
+  public class DEROctetString extends com.android.org.bouncycastle.asn1.ASN1OctetString {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public DEROctetString(byte[]);
+  }
+
+  public class DERSequence extends com.android.org.bouncycastle.asn1.ASN1Sequence {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public DERSequence();
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public DERSequence(com.android.org.bouncycastle.asn1.ASN1EncodableVector);
+  }
+
+  public class DERTaggedObject extends com.android.org.bouncycastle.asn1.ASN1TaggedObject {
+    ctor public DERTaggedObject(int, com.android.org.bouncycastle.asn1.ASN1Encodable);
+  }
+
+  public class DERUTF8String extends com.android.org.bouncycastle.asn1.ASN1Primitive {
+    ctor public DERUTF8String(String);
+    method public String getString();
+  }
+
+}
+
+package com.android.org.bouncycastle.asn1.pkcs {
+
+  public interface PKCSObjectIdentifiers {
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier sha256WithRSAEncryption;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier sha512WithRSAEncryption;
+  }
+
+  public class PrivateKeyInfo extends com.android.org.bouncycastle.asn1.ASN1Object {
+    method public static com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo getInstance(Object);
+    method public com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier getPrivateKeyAlgorithm();
+    method public com.android.org.bouncycastle.asn1.ASN1Encodable parsePrivateKey() throws java.io.IOException;
+  }
+
+}
+
+package com.android.org.bouncycastle.asn1.x500.style {
+
+  public class BCStyle {
+    method public static java.util.Hashtable copyHashTable(java.util.Hashtable);
+    method public com.android.org.bouncycastle.asn1.ASN1Encodable stringToValue(com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier, String);
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier C;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier CN;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier E;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier L;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier O;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier OU;
+    field public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier ST;
+  }
+
+}
+
+package com.android.org.bouncycastle.asn1.x509 {
+
+  public class AlgorithmIdentifier extends com.android.org.bouncycastle.asn1.ASN1Object {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public AlgorithmIdentifier(com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier);
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public AlgorithmIdentifier(com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier, com.android.org.bouncycastle.asn1.ASN1Encodable);
+    method public com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier getAlgorithm();
+  }
+
+  public class BasicConstraints extends com.android.org.bouncycastle.asn1.ASN1Object {
+    method public static com.android.org.bouncycastle.asn1.x509.BasicConstraints getInstance(Object);
+    method public boolean isCA();
+  }
+
+  public class Certificate extends com.android.org.bouncycastle.asn1.ASN1Object {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static com.android.org.bouncycastle.asn1.x509.Certificate getInstance(Object);
+  }
+
+  public class GeneralName extends com.android.org.bouncycastle.asn1.ASN1Object {
+    ctor public GeneralName(int, com.android.org.bouncycastle.asn1.ASN1Encodable);
+    ctor public GeneralName(int, String);
+    method public int getTagNo();
+    field public static final int dNSName = 2; // 0x2
+    field public static final int iPAddress = 7; // 0x7
+    field public static final int otherName = 0; // 0x0
+  }
+
+  public class SubjectPublicKeyInfo extends com.android.org.bouncycastle.asn1.ASN1Object {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo getInstance(Object);
+  }
+
+  public class TBSCertificate extends com.android.org.bouncycastle.asn1.ASN1Object {
+  }
+
+  public class Time extends com.android.org.bouncycastle.asn1.ASN1Object {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public Time(java.util.Date);
+  }
+
+  public class V3TBSCertificateGenerator {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public V3TBSCertificateGenerator();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public com.android.org.bouncycastle.asn1.x509.TBSCertificate generateTBSCertificate();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setEndDate(com.android.org.bouncycastle.asn1.x509.Time);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setIssuer(com.android.org.bouncycastle.asn1.x509.X509Name);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setSerialNumber(com.android.org.bouncycastle.asn1.ASN1Integer);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setSignature(com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setStartDate(com.android.org.bouncycastle.asn1.x509.Time);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setSubject(com.android.org.bouncycastle.asn1.x509.X509Name);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setSubjectPublicKeyInfo(com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo);
+  }
+
+  @Deprecated public class X509Name extends com.android.org.bouncycastle.asn1.ASN1Object {
+    ctor @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public X509Name(String);
+    method @Deprecated public static com.android.org.bouncycastle.asn1.x509.X509Name getInstance(Object);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public java.util.Vector getOIDs();
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public java.util.Vector getValues();
+    method @Deprecated public String toString(boolean, java.util.Hashtable);
+    field @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier CN;
+    field @Deprecated public static final java.util.Hashtable DefaultSymbols;
+    field @Deprecated public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier O;
+    field @Deprecated public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier OU;
+  }
+
+}
+
+package com.android.org.bouncycastle.asn1.x9 {
+
+  public interface X9ObjectIdentifiers {
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier ecdsa_with_SHA256;
+  }
+
+}
+
+package com.android.org.bouncycastle.crypto {
+
+  public interface CipherParameters {
+  }
+
+  public abstract class PBEParametersGenerator {
+    ctor protected PBEParametersGenerator();
+    method public static byte[] PKCS5PasswordToBytes(char[]);
+  }
+
+}
+
+package com.android.org.bouncycastle.crypto.generators {
+
+  public class OpenSSLPBEParametersGenerator extends com.android.org.bouncycastle.crypto.PBEParametersGenerator {
+    ctor public OpenSSLPBEParametersGenerator();
+    method public com.android.org.bouncycastle.crypto.CipherParameters generateDerivedParameters(int);
+    method public void init(byte[], byte[]);
+  }
+
+}
+
+package com.android.org.bouncycastle.crypto.params {
+
+  public class KeyParameter implements com.android.org.bouncycastle.crypto.CipherParameters {
+    method public byte[] getKey();
+  }
+
+}
+
+package com.android.org.bouncycastle.jcajce.util {
+
+  public class DefaultJcaJceHelper {
+    method public javax.crypto.Cipher createCipher(String) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException;
+  }
+
+}
+
+package com.android.org.bouncycastle.jce {
+
+  @Deprecated public class X509Principal extends com.android.org.bouncycastle.asn1.x509.X509Name implements java.security.Principal {
+    ctor @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public X509Principal(byte[]) throws java.io.IOException;
+    ctor @Deprecated public X509Principal(java.util.Vector, java.util.Hashtable);
+    method public byte[] getEncoded();
+  }
+
+}
+
+package com.android.org.bouncycastle.jce.provider {
+
+  public final class BouncyCastleProvider extends java.security.Provider {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public BouncyCastleProvider();
+  }
+
+  @Deprecated public class X509CertificateObject extends java.security.cert.X509Certificate {
+    ctor @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public X509CertificateObject(com.android.org.bouncycastle.asn1.x509.Certificate) throws java.security.cert.CertificateParsingException;
+  }
+
+}
+
+package com.android.org.bouncycastle.util {
+
+  public interface Iterable<T> extends java.lang.Iterable<T> {
+  }
+
+}
+
+package com.android.org.bouncycastle.util.io.pem {
+
+  public class PemHeader {
+    ctor public PemHeader(String, String);
+  }
+
+  public class PemObject implements com.android.org.bouncycastle.util.io.pem.PemObjectGenerator {
+    ctor public PemObject(String, byte[]);
+    ctor public PemObject(String, java.util.List, byte[]);
+    method public byte[] getContent();
+    method public String getType();
+  }
+
+  public interface PemObjectGenerator {
+  }
+
+  public class PemReader extends java.io.BufferedReader {
+    ctor public PemReader(java.io.Reader);
+    method public com.android.org.bouncycastle.util.io.pem.PemObject readPemObject() throws java.io.IOException;
+  }
+
+  public class PemWriter extends java.io.BufferedWriter {
+    ctor public PemWriter(java.io.Writer);
+    method public void writeObject(com.android.org.bouncycastle.util.io.pem.PemObjectGenerator) throws java.io.IOException;
+  }
+
+}
+
+package com.android.org.bouncycastle.x509 {
+
+  @Deprecated public class X509V1CertificateGenerator {
+    ctor @Deprecated public X509V1CertificateGenerator();
+    method @Deprecated public java.security.cert.X509Certificate generate(java.security.PrivateKey, String) throws java.security.cert.CertificateEncodingException, java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method @Deprecated public void setIssuerDN(javax.security.auth.x500.X500Principal);
+    method @Deprecated public void setNotAfter(java.util.Date);
+    method @Deprecated public void setNotBefore(java.util.Date);
+    method @Deprecated public void setPublicKey(java.security.PublicKey);
+    method @Deprecated public void setSerialNumber(java.math.BigInteger);
+    method @Deprecated public void setSignatureAlgorithm(String);
+    method @Deprecated public void setSubjectDN(javax.security.auth.x500.X500Principal);
+  }
+
+  @Deprecated public class X509V3CertificateGenerator {
+    ctor @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public X509V3CertificateGenerator();
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public java.security.cert.X509Certificate generate(java.security.PrivateKey) throws java.security.cert.CertificateEncodingException, java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setIssuerDN(javax.security.auth.x500.X500Principal);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setNotAfter(java.util.Date);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setNotBefore(java.util.Date);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setPublicKey(java.security.PublicKey) throws java.lang.IllegalArgumentException;
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setSerialNumber(java.math.BigInteger);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setSignatureAlgorithm(String);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void setSubjectDN(javax.security.auth.x500.X500Principal);
+  }
+
+}
+
+package com.android.org.conscrypt {
+
+  public interface CertPinManager {
+  }
+
+  public final class ClientSessionContext implements javax.net.ssl.SSLSessionContext {
+    method public final java.util.Enumeration<byte[]> getIds();
+    method public final javax.net.ssl.SSLSession getSession(byte[]);
+    method public final int getSessionCacheSize();
+    method public final int getSessionTimeout();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setPersistentCache(com.android.org.conscrypt.SSLClientSessionCache);
+    method public final void setSessionCacheSize(int) throws java.lang.IllegalArgumentException;
+    method public final void setSessionTimeout(int) throws java.lang.IllegalArgumentException;
+  }
+
+  public final class Conscrypt {
+    method public static javax.net.ssl.X509TrustManager getDefaultX509TrustManager() throws java.security.KeyManagementException;
+  }
+
+  public interface ConscryptCertStore {
+  }
+
+  public final class FileClientSessionCache {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static com.android.org.conscrypt.SSLClientSessionCache usingDirectory(java.io.File) throws java.io.IOException;
+  }
+
+  public final class OpenSSLProvider extends java.security.Provider {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public OpenSSLProvider();
+  }
+
+  public abstract class OpenSSLSocketImpl extends javax.net.ssl.SSLSocket {
+    method public void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
+    method public final void connect(java.net.SocketAddress) throws java.io.IOException;
+    method public final void connect(java.net.SocketAddress, int) throws java.io.IOException;
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public final byte[] getAlpnSelectedProtocol();
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public final byte[] getNpnSelectedProtocol();
+    method public final int getPort();
+    method public final int getSoTimeout() throws java.net.SocketException;
+    method public void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
+    method public final void sendUrgentData(int) throws java.io.IOException;
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public final void setAlpnProtocols(byte[]);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public abstract void setChannelIdPrivateKey(java.security.PrivateKey);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setHandshakeTimeout(int) throws java.net.SocketException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setHostname(String);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public final void setNpnProtocols(byte[]);
+    method public final void setOOBInline(boolean) throws java.net.SocketException;
+    method public final void setSoTimeout(int) throws java.net.SocketException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void setSoWriteTimeout(int) throws java.net.SocketException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public abstract void setUseSessionTickets(boolean);
+  }
+
+  public interface SSLClientSessionCache {
+  }
+
+  public final class TrustManagerImpl extends javax.net.ssl.X509ExtendedTrustManager {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public TrustManagerImpl(java.security.KeyStore);
+    ctor public TrustManagerImpl(java.security.KeyStore, com.android.org.conscrypt.CertPinManager, com.android.org.conscrypt.ConscryptCertStore);
+    method public void checkClientTrusted(java.security.cert.X509Certificate[], String) throws java.security.cert.CertificateException;
+    method public void checkClientTrusted(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
+    method public void checkClientTrusted(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], String, String) throws java.security.cert.CertificateException;
+    method public java.util.List<java.security.cert.X509Certificate> getTrustedChainForServer(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
+    method public java.util.List<java.security.cert.X509Certificate> getTrustedChainForServer(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
+    method public void handleTrustStorageUpdate();
+  }
+
+  public final class TrustedCertificateIndex {
+    ctor public TrustedCertificateIndex();
+    method public java.util.Set<java.security.cert.TrustAnchor> findAllByIssuerAndSignature(java.security.cert.X509Certificate);
+    method public java.security.cert.TrustAnchor findByIssuerAndSignature(java.security.cert.X509Certificate);
+    method public java.security.cert.TrustAnchor findBySubjectAndPublicKey(java.security.cert.X509Certificate);
+    method public java.security.cert.TrustAnchor index(java.security.cert.X509Certificate);
+  }
+
+  public class TrustedCertificateStore implements com.android.org.conscrypt.ConscryptCertStore {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public TrustedCertificateStore();
+    method public java.util.Set<java.lang.String> aliases();
+    method public java.util.Set<java.lang.String> allSystemAliases();
+    method public boolean containsAlias(String);
+    method public void deleteCertificateEntry(String) throws java.security.cert.CertificateException, java.io.IOException;
+    method public java.util.Set<java.security.cert.X509Certificate> findAllIssuers(java.security.cert.X509Certificate);
+    method public java.security.cert.X509Certificate findIssuer(java.security.cert.X509Certificate);
+    method public java.security.cert.Certificate getCertificate(String);
+    method public java.security.cert.Certificate getCertificate(String, boolean);
+    method public String getCertificateAlias(java.security.cert.Certificate);
+    method public String getCertificateAlias(java.security.cert.Certificate, boolean);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public java.util.List<java.security.cert.X509Certificate> getCertificateChain(java.security.cert.X509Certificate) throws java.security.cert.CertificateException;
+    method public java.io.File getCertificateFile(java.io.File, java.security.cert.X509Certificate);
+    method public java.util.Date getCreationDate(String);
+    method public java.security.cert.X509Certificate getTrustAnchor(java.security.cert.X509Certificate);
+    method public void installCertificate(java.security.cert.X509Certificate) throws java.security.cert.CertificateException, java.io.IOException;
+    method public static final boolean isUser(String);
+    method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
+    method public static void setDefaultUserDirectory(java.io.File);
+    method public java.util.Set<java.lang.String> userAliases();
+  }
+
+}
+
+package dalvik.annotation.compat {
+
+  @java.lang.annotation.Repeatable(UnsupportedAppUsage.Container.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.TYPE}) public @interface UnsupportedAppUsage {
+    method public abstract String expectedSignature() default "";
+    method public abstract String implicitMember() default "";
+    method public abstract int maxTargetSdk() default java.lang.Integer.MAX_VALUE;
+    method public abstract long trackingBug() default 0;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public static @interface UnsupportedAppUsage.Container {
+    method public abstract dalvik.annotation.compat.UnsupportedAppUsage[] value();
+  }
+
+}
+
+package dalvik.annotation.optimization {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface CriticalNative {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface FastNative {
+  }
+
+}
+
+package dalvik.system {
+
+  public class AnnotatedStackTraceElement {
+    method public Object getBlockedOn();
+    method public Object[] getHeldLocks();
+    method public StackTraceElement getStackTraceElement();
+  }
+
+  public class BaseDexClassLoader extends java.lang.ClassLoader {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void addDexPath(String);
+    method public void addNativePath(java.util.Collection<java.lang.String>);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public String getLdLibraryPath();
+    method public static void setReporter(dalvik.system.BaseDexClassLoader.Reporter);
+  }
+
+  public static interface BaseDexClassLoader.Reporter {
+    method public void report(java.util.List<java.lang.ClassLoader>, java.util.List<java.lang.String>);
+  }
+
+  public final class BlockGuard {
+    method @NonNull @dalvik.annotation.compat.UnsupportedAppUsage public static dalvik.system.BlockGuard.Policy getThreadPolicy();
+    method @NonNull public static dalvik.system.BlockGuard.VmPolicy getVmPolicy();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void setThreadPolicy(@NonNull dalvik.system.BlockGuard.Policy);
+    method public static void setVmPolicy(@NonNull dalvik.system.BlockGuard.VmPolicy);
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final dalvik.system.BlockGuard.Policy LAX_POLICY;
+    field public static final dalvik.system.BlockGuard.VmPolicy LAX_VM_POLICY;
+  }
+
+  public static interface BlockGuard.Policy {
+    method public int getPolicyMask();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void onReadFromDisk();
+    method public void onUnbufferedIO();
+    method public void onWriteToDisk();
+  }
+
+  public static interface BlockGuard.VmPolicy {
+    method public void onPathAccess(String);
+  }
+
+  public final class CloseGuard {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void close();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static dalvik.system.CloseGuard get();
+    method public static dalvik.system.CloseGuard.Reporter getReporter();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void open(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void setEnabled(boolean);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void setReporter(dalvik.system.CloseGuard.Reporter);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void warnIfOpen();
+  }
+
+  public static interface CloseGuard.Reporter {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void report(String, Throwable);
+  }
+
+  public interface DalvikLogHandler {
+    method public void publish(java.util.logging.Logger, String, java.util.logging.Level, String);
+  }
+
+  public final class DalvikLogging {
+    method public static String loggerNameToTag(String);
+  }
+
+  public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+    ctor public DelegateLastClassLoader(String, String, ClassLoader, ClassLoader[]);
+  }
+
+  @Deprecated public final class DexFile {
+    ctor @Deprecated public DexFile(java.io.File) throws java.io.IOException;
+    ctor @Deprecated public DexFile(String) throws java.io.IOException;
+    method @Deprecated public void close() throws java.io.IOException;
+    method @Deprecated public java.util.Enumeration<java.lang.String> entries();
+    method @Deprecated public static dalvik.system.DexFile.OptimizationInfo getDexFileOptimizationInfo(String, String) throws java.io.FileNotFoundException;
+    method @Deprecated public static String[] getDexFileOutputPaths(String, String) throws java.io.FileNotFoundException;
+    method @Deprecated public static int getDexOptNeeded(String, String, String, String, boolean, boolean) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated public String getName();
+    method @Deprecated public static String getSafeModeCompilerFilter(String);
+    method @Deprecated public static boolean isDexOptNeeded(String) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated public static boolean isProfileGuidedCompilerFilter(String);
+    method @Deprecated public static boolean isValidCompilerFilter(String);
+    method @Deprecated public Class loadClass(String, ClassLoader);
+    method @Deprecated public static dalvik.system.DexFile loadDex(String, String, int) throws java.io.IOException;
+    field @Deprecated public static final int DEX2OAT_FOR_FILTER = 3; // 0x3
+    field @Deprecated public static final int NO_DEXOPT_NEEDED = 0; // 0x0
+  }
+
+  @Deprecated public static final class DexFile.OptimizationInfo {
+    method @Deprecated public String getReason();
+    method @Deprecated public String getStatus();
+  }
+
+  public class PathClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public PathClassLoader(String, String, ClassLoader, ClassLoader[]);
+  }
+
+  public final class RuntimeHooks {
+    method public static void setTimeZoneIdSupplier(java.util.function.Supplier<java.lang.String>);
+    method public static void setUncaughtExceptionPreHandler(java.lang.Thread.UncaughtExceptionHandler);
+  }
+
+  public abstract class SocketTagger {
+    ctor public SocketTagger();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static dalvik.system.SocketTagger get();
+    method public static void set(dalvik.system.SocketTagger);
+    method public abstract void tag(java.io.FileDescriptor) throws java.net.SocketException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public final void tag(java.net.Socket) throws java.net.SocketException;
+    method public final void tag(java.net.DatagramSocket) throws java.net.SocketException;
+    method public abstract void untag(java.io.FileDescriptor) throws java.net.SocketException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public final void untag(java.net.Socket) throws java.net.SocketException;
+    method public final void untag(java.net.DatagramSocket) throws java.net.SocketException;
+  }
+
+  public final class VMDebug {
+    method public static void attachAgent(String, ClassLoader) throws java.io.IOException;
+    method public static boolean cacheRegisterMap(String);
+    method public static long countInstancesOfClass(Class, boolean);
+    method public static long[] countInstancesOfClasses(Class[], boolean);
+    method public static void dumpHprofData(String) throws java.io.IOException;
+    method public static void dumpHprofData(String, java.io.FileDescriptor) throws java.io.IOException;
+    method public static void dumpHprofDataDdms();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void dumpReferenceTables();
+    method public static int getAllocCount(int);
+    method @dalvik.annotation.optimization.FastNative public static int getLoadedClassCount();
+    method public static int getMethodTracingMode();
+    method public static String getRuntimeStat(String);
+    method public static java.util.Map<java.lang.String,java.lang.String> getRuntimeStats();
+    method public static String[] getVmFeatureList();
+    method @dalvik.annotation.compat.UnsupportedAppUsage @dalvik.annotation.optimization.FastNative public static boolean isDebuggerConnected();
+    method @dalvik.annotation.optimization.FastNative public static boolean isDebuggingEnabled();
+    method @dalvik.annotation.optimization.FastNative public static long lastDebuggerActivity();
+    method @dalvik.annotation.optimization.FastNative public static void printLoadedClasses(int);
+    method public static void resetAllocCount(int);
+    method public static void setAllocTrackerStackDepth(int);
+    method public static void startAllocCounting();
+    method public static void startEmulatorTracing();
+    method public static void startMethodTracing(String, int, int, boolean, int);
+    method public static void startMethodTracing(String, java.io.FileDescriptor, int, int, boolean, int, boolean);
+    method public static void startMethodTracingDdms(int, int, boolean, int);
+    method public static void stopAllocCounting();
+    method public static void stopEmulatorTracing();
+    method public static void stopMethodTracing();
+    method @dalvik.annotation.optimization.FastNative public static long threadCpuTimeNanos();
+    field public static final int KIND_ALL_COUNTS = -1; // 0xffffffff
+    field public static final int KIND_GLOBAL_ALLOCATED_BYTES = 2; // 0x2
+    field public static final int KIND_GLOBAL_ALLOCATED_OBJECTS = 1; // 0x1
+    field public static final int KIND_GLOBAL_CLASS_INIT_COUNT = 32; // 0x20
+    field public static final int KIND_GLOBAL_CLASS_INIT_TIME = 64; // 0x40
+    field public static final int KIND_GLOBAL_FREED_BYTES = 8; // 0x8
+    field public static final int KIND_GLOBAL_FREED_OBJECTS = 4; // 0x4
+    field public static final int KIND_GLOBAL_GC_INVOCATIONS = 16; // 0x10
+    field public static final int KIND_THREAD_ALLOCATED_BYTES = 131072; // 0x20000
+    field public static final int KIND_THREAD_ALLOCATED_OBJECTS = 65536; // 0x10000
+    field public static final int KIND_THREAD_GC_INVOCATIONS = 1048576; // 0x100000
+    field public static final int TRACE_COUNT_ALLOCS = 1; // 0x1
+  }
+
+  public final class VMRuntime {
+    method @dalvik.annotation.compat.UnsupportedAppUsage @dalvik.annotation.optimization.FastNative public long addressOf(Object);
+    method public void clampGrowthLimit();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void clearGrowthLimit();
+    method public static boolean didPruneDalvikCache();
+    method public void disableJitCompilation();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String getCurrentInstructionSet();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String getInstructionSet(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static dalvik.system.VMRuntime getRuntime();
+    method public float getTargetHeapUtilization();
+    method public int getTargetSdkVersion();
+    method @dalvik.annotation.optimization.FastNative public static boolean hasBootImageSpaces();
+    method @dalvik.annotation.compat.UnsupportedAppUsage @dalvik.annotation.optimization.FastNative public boolean is64Bit();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static boolean is64BitAbi(String);
+    method public static boolean is64BitInstructionSet(String);
+    method public static boolean isBootClassPathOnDisk(String);
+    method @dalvik.annotation.optimization.FastNative public boolean isCheckJniEnabled();
+    method @dalvik.annotation.optimization.FastNative public boolean isNativeDebuggable();
+    method @dalvik.annotation.compat.UnsupportedAppUsage @dalvik.annotation.optimization.FastNative public Object newNonMovableArray(Class<?>, int);
+    method @dalvik.annotation.optimization.FastNative public Object newUnpaddedArray(Class<?>, int);
+    method public void notifyStartupCompleted();
+    method public void preloadDexCaches();
+    method public static void registerAppInfo(String, String[]);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void registerNativeAllocation(long);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void registerNativeAllocation(int);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void registerNativeFree(long);
+    method @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage public void registerNativeFree(int);
+    method public static void registerSensitiveThread();
+    method public void requestConcurrentGC();
+    method public static void setDedupeHiddenApiWarnings(boolean);
+    method public void setHiddenApiAccessLogSamplingRate(int);
+    method public void setHiddenApiExemptions(String[]);
+    method public static void setHiddenApiUsageLogger(dalvik.system.VMRuntime.HiddenApiUsageLogger);
+    method public static void setNonSdkApiUsageConsumer(java.util.function.Consumer<java.lang.String>);
+    method public static void setProcessDataDirectory(String);
+    method public static void setProcessPackageName(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public float setTargetHeapUtilization(float);
+    method public void setTargetSdkVersion(int);
+    method public void startJitCompilation();
+    method public void updateProcessState(int);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public String vmInstructionSet();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public String vmLibrary();
+    field public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000; // 0x2710
+  }
+
+  public static interface VMRuntime.HiddenApiUsageLogger {
+    method public void hiddenApiUsed(int, String, String, int, boolean);
+    field public static final int ACCESS_METHOD_JNI = 2; // 0x2
+    field public static final int ACCESS_METHOD_LINKING = 3; // 0x3
+    field public static final int ACCESS_METHOD_NONE = 0; // 0x0
+    field public static final int ACCESS_METHOD_REFLECTION = 1; // 0x1
+  }
+
+  public final class VMStack {
+    method @dalvik.annotation.optimization.FastNative public static dalvik.system.AnnotatedStackTraceElement[] getAnnotatedThreadStackTrace(Thread);
+  }
+
+  public class VersionCodes {
+    field public static final int O = 26; // 0x1a
+    field public static final int P = 28; // 0x1c
+  }
+
+  public final class ZygoteHooks {
+    method public static void gcAndFinalize();
+    method public static void onBeginPreload();
+    method public static void onEndPreload();
+    method public static void postForkChild(int, boolean, boolean, String);
+    method public static void postForkCommon();
+    method public static void postForkSystemServer();
+    method public static void preFork();
+    method public static void startZygoteNoThreadCreation();
+    method public static void stopZygoteNoThreadCreation();
+  }
+
+}
+
+package java.io {
+
+  public final class FileDescriptor {
+    method public int getInt$();
+    method public void setInt$(int);
+  }
+
+  public class FileInputStream extends java.io.InputStream {
+    ctor public FileInputStream(java.io.FileDescriptor, boolean);
+  }
+
+}
+
+package java.lang {
+
+  public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+    method public static String toHexString(byte, boolean);
+  }
+
+  public final class Class<T> implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
+    method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean);
+    method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean);
+    method public String getPackageName$();
+  }
+
+  public final class Math {
+    method public static long randomLongInternal();
+  }
+
+  public final class System {
+    method public static void logE(String, Throwable);
+  }
+
+  public class Thread implements java.lang.Runnable {
+    method public static java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionPreHandler();
+    method public static void setUncaughtExceptionPreHandler(java.lang.Thread.UncaughtExceptionHandler);
+  }
+
+}
+
+package java.net {
+
+  public class DatagramSocket implements java.io.Closeable {
+    method public java.io.FileDescriptor getFileDescriptor$();
+  }
+
+  public final class Inet4Address extends java.net.InetAddress {
+    field public static final java.net.InetAddress ALL;
+    field public static final java.net.InetAddress ANY;
+    field public static final java.net.InetAddress LOOPBACK;
+  }
+
+  public final class Inet6Address extends java.net.InetAddress {
+    method public static java.net.Inet6Address getByAddress(String, byte[], java.net.NetworkInterface) throws java.net.UnknownHostException;
+    method public static java.net.Inet6Address getByAddress(String, byte[], int) throws java.net.UnknownHostException;
+    method public int getScopeId();
+    method public java.net.NetworkInterface getScopedInterface();
+    method public boolean isIPv4CompatibleAddress();
+    field public static final java.net.InetAddress ANY;
+    field public static final java.net.InetAddress LOOPBACK;
+  }
+
+  public class InetAddress implements java.io.Serializable {
+    method public static void clearDnsCache();
+    method public static java.net.InetAddress[] getAllByNameOnNet(String, int) throws java.net.UnknownHostException;
+    method public static java.net.InetAddress getByNameOnNet(String, int) throws java.net.UnknownHostException;
+    method @Deprecated public static boolean isNumeric(String);
+    method @Deprecated public static java.net.InetAddress parseNumericAddress(String);
+  }
+
+  public class InetSocketAddress extends java.net.SocketAddress {
+    ctor public InetSocketAddress();
+  }
+
+  public class ServerSocket implements java.io.Closeable {
+    method public java.net.SocketImpl getImpl() throws java.net.SocketException;
+  }
+
+  public class Socket implements java.io.Closeable {
+    method public java.io.FileDescriptor getFileDescriptor$();
+  }
+
+  public abstract class SocketImpl implements java.net.SocketOptions {
+    method public java.io.FileDescriptor getFD$();
+  }
+
+}
+
+package java.nio {
+
+  public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+    method public void setAccessible(boolean);
+  }
+
+  public class DirectByteBuffer extends java.nio.MappedByteBuffer {
+    ctor public DirectByteBuffer(int, long, java.io.FileDescriptor, Runnable, boolean);
+    method public final long address();
+    method public final void setAccessible(boolean);
+  }
+
+  public final class NioUtils {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void freeDirectBuffer(java.nio.ByteBuffer);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static byte[] unsafeArray(java.nio.ByteBuffer);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static int unsafeArrayOffset(java.nio.ByteBuffer);
+  }
+
+}
+
+package java.security {
+
+  public abstract class Provider extends java.util.Properties {
+    method public void warmUpServiceProvision();
+  }
+
+  public abstract class Signature extends java.security.SignatureSpi {
+    method public java.security.SignatureSpi getCurrentSpi();
+  }
+
+}
+
+package java.text {
+
+  public abstract class DateFormat extends java.text.Format {
+    method public static final void set24HourTimePref(Boolean);
+  }
+
+}
+
+package java.util {
+
+  public class LinkedHashMap<K, V> extends java.util.HashMap<K,V> implements java.util.Map<K,V> {
+    method public java.util.Map.Entry<K,V> eldest();
+  }
+
+  public final class Locale implements java.lang.Cloneable java.io.Serializable {
+    method public static String adjustLanguageCode(String);
+  }
+
+}
+
+package java.util.concurrent {
+
+  public class CompletableFuture<T> implements java.util.concurrent.CompletionStage<T> java.util.concurrent.Future<T> {
+    method public java.util.concurrent.CompletableFuture<T> completeOnTimeout(T, long, java.util.concurrent.TimeUnit);
+    method public static <U> java.util.concurrent.CompletableFuture<U> failedFuture(Throwable);
+  }
+
+}
+
+package java.util.zip {
+
+  public class ZipEntry implements java.lang.Cloneable {
+    method public long getDataOffset();
+  }
+
+}
+
+package javax.crypto {
+
+  public class Cipher {
+    method public javax.crypto.CipherSpi getCurrentSpi();
+  }
+
+  public class Mac implements java.lang.Cloneable {
+    method public javax.crypto.MacSpi getCurrentSpi();
+  }
+
+}
+
+package libcore.icu {
+
+  public final class DateIntervalFormat {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String formatDateRange(long, long, int, String);
+  }
+
+  public final class ICU {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static java.util.Locale addLikelySubtags(java.util.Locale);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String getBestDateTimePattern(String, java.util.Locale);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static char[] getDateFormatOrder(String);
+    method public static String getTZDataVersion();
+  }
+
+  public final class LocaleData {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static libcore.icu.LocaleData get(java.util.Locale);
+    method public String getDateFormat(int);
+    field public String[] amPm;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public Integer firstDayOfWeek;
+    field public String[] longMonthNames;
+    field public String[] longStandAloneMonthNames;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String[] longStandAloneWeekdayNames;
+    field public String[] longWeekdayNames;
+    field public String narrowAm;
+    field public String narrowPm;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String[] shortMonthNames;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String[] shortStandAloneMonthNames;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String[] shortStandAloneWeekdayNames;
+    field public String[] shortWeekdayNames;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String timeFormat_Hm;
+    field public String timeFormat_Hms;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String timeFormat_hm;
+    field public String timeFormat_hms;
+    field public String[] tinyMonthNames;
+    field public String[] tinyStandAloneMonthNames;
+    field public String[] tinyStandAloneWeekdayNames;
+    field public String[] tinyWeekdayNames;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public String today;
+    field public String yesterday;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public char zeroDigit;
+  }
+
+  public final class RelativeDateTimeFormatter {
+    method public static String getRelativeDateTimeString(java.util.Locale, java.util.TimeZone, long, long, long, long, int);
+    method public static String getRelativeTimeSpanString(java.util.Locale, java.util.TimeZone, long, long, long, int);
+  }
+
+}
+
+package libcore.internal {
+
+  public final class StringPool {
+    ctor public StringPool();
+    method public String get(char[], int, int);
+  }
+
+}
+
+package libcore.io {
+
+  public class ForwardingOs implements libcore.io.Os {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage protected ForwardingOs(libcore.io.Os);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public boolean access(String, int) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public java.io.FileDescriptor open(String, int, int) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void remove(String) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void rename(String, String) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public android.system.StructStat stat(String) throws android.system.ErrnoException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public void unlink(String) throws android.system.ErrnoException;
+  }
+
+  public final class IoBridge {
+    method public static void closeAndSignalBlockedThreads(java.io.FileDescriptor) throws java.io.IOException;
+    method public static java.net.InetSocketAddress getLocalInetSocketAddress(java.io.FileDescriptor) throws java.net.SocketException;
+    method public static java.io.FileDescriptor open(String, int) throws java.io.FileNotFoundException;
+    method public static int read(java.io.FileDescriptor, byte[], int, int) throws java.io.IOException;
+    method public static int recvfrom(boolean, java.io.FileDescriptor, byte[], int, int, int, java.net.DatagramPacket, boolean) throws java.io.IOException;
+    method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws java.io.IOException;
+    method public static java.io.FileDescriptor socket(int, int, int) throws java.net.SocketException;
+    method public static void write(java.io.FileDescriptor, byte[], int, int) throws java.io.IOException;
+  }
+
+  public final class IoUtils {
+    method public static int acquireRawFd(@NonNull java.io.FileDescriptor);
+    method public static void close(java.io.FileDescriptor) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void closeQuietly(AutoCloseable);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void closeQuietly(java.io.FileDescriptor);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void closeQuietly(java.net.Socket);
+    method @Deprecated public static java.io.File createTemporaryDirectory(String);
+    method @Deprecated public static void deleteContents(java.io.File) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static byte[] readFileAsByteArray(String) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String readFileAsString(String) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void setBlocking(java.io.FileDescriptor, boolean) throws java.io.IOException;
+    method public static void setFdOwner(@NonNull java.io.FileDescriptor, @NonNull Object);
+  }
+
+  public final class Memory {
+    method public static void memmove(Object, int, Object, int, long);
+    method public static int peekInt(byte[], int, java.nio.ByteOrder);
+    method public static short peekShort(byte[], int, java.nio.ByteOrder);
+    method public static void pokeInt(byte[], int, int, java.nio.ByteOrder);
+    method public static void pokeLong(byte[], int, long, java.nio.ByteOrder);
+    method public static void pokeShort(byte[], int, short, java.nio.ByteOrder);
+  }
+
+  public interface Os {
+    method public static boolean compareAndSetDefault(libcore.io.Os, libcore.io.Os);
+    method public static libcore.io.Os getDefault();
+  }
+
+  public final class Streams {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static int copy(java.io.InputStream, java.io.OutputStream) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void readFully(java.io.InputStream, byte[]) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static byte[] readFully(java.io.InputStream) throws java.io.IOException;
+    method public static String readFully(java.io.Reader) throws java.io.IOException;
+    method public static byte[] readFullyNoClose(java.io.InputStream) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static int readSingleByte(java.io.InputStream) throws java.io.IOException;
+    method public static long skipByReading(java.io.InputStream, long) throws java.io.IOException;
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void writeSingleByte(java.io.OutputStream, int) throws java.io.IOException;
+  }
+
+}
+
+package libcore.net {
+
+  public class InetAddressUtils {
+    method public static boolean isNumericAddress(String);
+    method public static java.net.InetAddress parseNumericAddress(String);
+  }
+
+  public final class MimeUtils {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String guessExtensionFromMimeType(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static String guessMimeTypeFromExtension(String);
+    method public static boolean hasExtension(String);
+    method public static boolean hasMimeType(String);
+  }
+
+  public abstract class NetworkSecurityPolicy {
+    ctor public NetworkSecurityPolicy();
+    method public static libcore.net.NetworkSecurityPolicy getInstance();
+    method public abstract boolean isCertificateTransparencyVerificationRequired(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public abstract boolean isCleartextTrafficPermitted();
+    method public abstract boolean isCleartextTrafficPermitted(String);
+    method public static void setInstance(libcore.net.NetworkSecurityPolicy);
+  }
+
+}
+
+package libcore.net.event {
+
+  public class NetworkEventDispatcher {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static libcore.net.event.NetworkEventDispatcher getInstance();
+    method public void onNetworkConfigurationChanged();
+  }
+
+}
+
+package libcore.timezone {
+
+  public final class CountryTimeZones {
+    method public String getCountryIso();
+    method public String getDefaultTimeZoneId();
+    method public java.util.List<libcore.timezone.CountryTimeZones.TimeZoneMapping> getTimeZoneMappings();
+    method public boolean hasUtcZone(long);
+    method public boolean isDefaultOkForCountryTimeZoneDetection(long);
+    method public boolean isForCountryCode(String);
+    method @Deprecated public libcore.timezone.CountryTimeZones.OffsetResult lookupByOffsetWithBias(int, boolean, long, android.icu.util.TimeZone);
+  }
+
+  public static final class CountryTimeZones.OffsetResult {
+    field public final boolean mOneMatch;
+    field public final android.icu.util.TimeZone mTimeZone;
+  }
+
+  public static final class CountryTimeZones.TimeZoneMapping {
+    method public static libcore.timezone.CountryTimeZones.TimeZoneMapping createForTests(String, boolean, Long);
+    field public final Long notUsedAfter;
+    field public final boolean showInPicker;
+    field public final String timeZoneId;
+  }
+
+  public final class CountryZonesFinder {
+    method public java.util.List<java.lang.String> lookupAllCountryIsoCodes();
+    method public libcore.timezone.CountryTimeZones lookupCountryTimeZones(String);
+    method public java.util.List<libcore.timezone.CountryTimeZones> lookupCountryTimeZonesForZoneId(String);
+  }
+
+  public final class TimeZoneDataFiles {
+    method public static String getDataTimeZoneFile(String);
+    method public static String getDataTimeZoneRootDir();
+    method public static String getRuntimeModuleTzVersionFile();
+  }
+
+  public final class TimeZoneFinder {
+    method public static libcore.timezone.TimeZoneFinder createInstance(String) throws java.io.IOException;
+    method public libcore.timezone.CountryZonesFinder getCountryZonesFinder();
+    method public String getIanaVersion();
+    method public static libcore.timezone.TimeZoneFinder getInstance();
+    method public libcore.timezone.CountryTimeZones lookupCountryTimeZones(String);
+    method public String lookupDefaultTimeZoneIdByCountry(String);
+    method public android.icu.util.TimeZone lookupTimeZoneByCountryAndOffset(String, int, boolean, long, android.icu.util.TimeZone);
+    method public java.util.List<java.lang.String> lookupTimeZoneIdsByCountry(String);
+    method public java.util.List<android.icu.util.TimeZone> lookupTimeZonesByCountry(String);
+    method public void validate() throws java.io.IOException;
+  }
+
+  public class TzDataSetVersion {
+    ctor public TzDataSetVersion(int, int, String, int) throws libcore.timezone.TzDataSetVersion.TzDataSetException;
+    method public static int currentFormatMajorVersion();
+    method public static int currentFormatMinorVersion();
+    method public static boolean isCompatibleWithThisDevice(libcore.timezone.TzDataSetVersion);
+    method public static libcore.timezone.TzDataSetVersion readFromFile(java.io.File) throws java.io.IOException, libcore.timezone.TzDataSetVersion.TzDataSetException;
+    method public byte[] toBytes();
+    field public static final String DEFAULT_FILE_NAME = "tz_version";
+    field public final String rulesVersion;
+  }
+
+  public static class TzDataSetVersion.TzDataSetException extends java.lang.Exception {
+    ctor public TzDataSetVersion.TzDataSetException(String);
+    ctor public TzDataSetVersion.TzDataSetException(String, Throwable);
+  }
+
+  public final class ZoneInfoDB {
+    method public static libcore.timezone.ZoneInfoDB.TzData getInstance();
+  }
+
+  public static class ZoneInfoDB.TzData implements java.lang.AutoCloseable {
+    method public String getVersion();
+    method public boolean hasTimeZone(String) throws java.io.IOException;
+    method public static libcore.timezone.ZoneInfoDB.TzData loadTzData(String);
+    method public libcore.util.ZoneInfo makeTimeZone(String) throws java.io.IOException;
+    method public void validate() throws java.io.IOException;
+  }
+
+}
+
+package libcore.util {
+
+  public final class ArrayUtils {
+    method public static void throwsIfOutOfBounds(int, int, int);
+  }
+
+  public class CoreLibraryDebug {
+    method public static libcore.util.DebugInfo getDebugInfo();
+  }
+
+  public class DebugInfo {
+    ctor public DebugInfo();
+    method public libcore.util.DebugInfo addStringEntry(String, String);
+    method public libcore.util.DebugInfo addStringEntry(String, int);
+    method public java.util.List<libcore.util.DebugInfo.DebugEntry> getDebugEntries();
+  }
+
+  public static class DebugInfo.DebugEntry {
+    ctor public DebugInfo.DebugEntry(String, String);
+    method public String getKey();
+    method public String getStringValue();
+  }
+
+  public final class EmptyArray {
+    field public static final boolean[] BOOLEAN;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final byte[] BYTE;
+    field public static final float[] FLOAT;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final int[] INT;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final long[] LONG;
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final Object[] OBJECT;
+    field public static final String[] STRING;
+  }
+
+  public class HexEncoding {
+    method public static byte[] decode(String) throws java.lang.IllegalArgumentException;
+    method public static byte[] decode(char[]) throws java.lang.IllegalArgumentException;
+    method public static byte[] decode(char[], boolean) throws java.lang.IllegalArgumentException;
+    method public static char[] encode(byte[]);
+    method public static char[] encode(byte[], int, int);
+    method public static String encodeToString(byte[]);
+  }
+
+  public class NativeAllocationRegistry {
+    ctor public NativeAllocationRegistry(ClassLoader, long, long);
+    method public static void applyFreeFunction(long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(ClassLoader, long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(ClassLoader, long);
+    method public static libcore.util.NativeAllocationRegistry createNonmalloced(ClassLoader, long, long);
+    method public Runnable registerNativeAllocation(Object, long);
+  }
+
+  public class SneakyThrow {
+    method public static void sneakyThrow(Throwable);
+  }
+
+  public class XmlObjectFactory {
+    method public static org.xml.sax.XMLReader newXMLReader();
+    method public static org.xmlpull.v1.XmlPullParser newXmlPullParser();
+    method public static org.xmlpull.v1.XmlSerializer newXmlSerializer();
+  }
+
+  public final class ZoneInfo extends java.util.TimeZone {
+  }
+
+  public static class ZoneInfo.WallTime {
+    ctor public ZoneInfo.WallTime();
+    method public int getGmtOffset();
+    method public int getHour();
+    method public int getIsDst();
+    method public int getMinute();
+    method public int getMonth();
+    method public int getMonthDay();
+    method public int getSecond();
+    method public int getWeekDay();
+    method public int getYear();
+    method public int getYearDay();
+    method public void localtime(int, libcore.util.ZoneInfo);
+    method public int mktime(libcore.util.ZoneInfo);
+    method public void setGmtOffset(int);
+    method public void setHour(int);
+    method public void setIsDst(int);
+    method public void setMinute(int);
+    method public void setMonth(int);
+    method public void setMonthDay(int);
+    method public void setSecond(int);
+    method public void setWeekDay(int);
+    method public void setYear(int);
+    method public void setYearDay(int);
+  }
+
+}
+
+package org.apache.harmony.dalvik {
+
+  public final class NativeTestTarget {
+    ctor public NativeTestTarget();
+    method public static void emptyInlineMethod();
+    method public static void emptyInternalStaticMethod();
+    method public void emptyJniMethod0();
+    method @dalvik.annotation.optimization.FastNative public void emptyJniMethod0_Fast();
+    method public void emptyJniMethod6(int, int, int, int, int, int);
+    method public void emptyJniMethod6L(String, String[], int[][], Object, Object[], Object[][][][]);
+    method @dalvik.annotation.optimization.FastNative public void emptyJniMethod6L_Fast(String, String[], int[][], Object, Object[], Object[][][][]);
+    method @dalvik.annotation.optimization.FastNative public void emptyJniMethod6_Fast(int, int, int, int, int, int);
+    method public static void emptyJniStaticMethod0();
+    method @dalvik.annotation.optimization.CriticalNative public static void emptyJniStaticMethod0_Critical();
+    method @dalvik.annotation.optimization.FastNative public static void emptyJniStaticMethod0_Fast();
+    method public static void emptyJniStaticMethod6(int, int, int, int, int, int);
+    method public static void emptyJniStaticMethod6L(String, String[], int[][], Object, Object[], Object[][][][]);
+    method @dalvik.annotation.optimization.FastNative public static void emptyJniStaticMethod6L_Fast(String, String[], int[][], Object, Object[], Object[][][][]);
+    method @dalvik.annotation.optimization.CriticalNative public static void emptyJniStaticMethod6_Critical(int, int, int, int, int, int);
+    method @dalvik.annotation.optimization.FastNative public static void emptyJniStaticMethod6_Fast(int, int, int, int, int, int);
+    method public static void emptyJniStaticSynchronizedMethod0();
+    method public void emptyJniSynchronizedMethod0();
+  }
+
+}
+
+package org.apache.harmony.dalvik.ddmc {
+
+  public class Chunk {
+    ctor public Chunk(int, byte[], int, int);
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage public Chunk(int, java.nio.ByteBuffer);
+    field public int type;
+  }
+
+  public abstract class ChunkHandler {
+    ctor public ChunkHandler();
+    method public abstract void connected();
+    method public static org.apache.harmony.dalvik.ddmc.Chunk createFailChunk(int, String);
+    method public abstract void disconnected();
+    method public static String getString(java.nio.ByteBuffer, int);
+    method public abstract org.apache.harmony.dalvik.ddmc.Chunk handleChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    method public static String name(int);
+    method public static void putString(java.nio.ByteBuffer, String);
+    method public static int type(String);
+    method public static java.nio.ByteBuffer wrapChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    field @dalvik.annotation.compat.UnsupportedAppUsage public static final java.nio.ByteOrder CHUNK_ORDER;
+  }
+
+  public class DdmServer {
+    method public static void registerHandler(int, org.apache.harmony.dalvik.ddmc.ChunkHandler);
+    method public static void registrationComplete();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static void sendChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+  }
+
+  public class DdmVmInternal {
+    method public static void enableRecentAllocations(boolean);
+    method @dalvik.annotation.optimization.FastNative public static boolean getRecentAllocationStatus();
+    method @dalvik.annotation.optimization.FastNative public static byte[] getRecentAllocations();
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static StackTraceElement[] getStackTraceById(int);
+    method @dalvik.annotation.compat.UnsupportedAppUsage public static byte[] getThreadStats();
+    method @dalvik.annotation.optimization.FastNative public static boolean heapInfoNotify(int);
+    method public static boolean heapSegmentNotify(int, int, boolean);
+    method public static void threadNotify(boolean);
+  }
+
+}
+
+package org.json {
+
+  public class JSONObject {
+    method @dalvik.annotation.compat.UnsupportedAppUsage public java.util.Set<java.lang.String> keySet();
+  }
+
+}
+
+package sun.misc {
+
+  public class Cleaner extends java.lang.ref.PhantomReference<java.lang.Object> {
+    method public void clean();
+    method public static sun.misc.Cleaner create(Object, Runnable);
+  }
+
+  public final class Unsafe {
+    method public int arrayBaseOffset(Class);
+    method @dalvik.annotation.optimization.FastNative public byte getByte(Object, long);
+    method @dalvik.annotation.optimization.FastNative public byte getByte(long);
+    method @dalvik.annotation.optimization.FastNative public long getLong(Object, long);
+    method @dalvik.annotation.optimization.FastNative public long getLong(long);
+    method public static sun.misc.Unsafe getUnsafe();
+    method public long objectFieldOffset(java.lang.reflect.Field);
+    method @dalvik.annotation.optimization.FastNative public void putByte(Object, long, byte);
+    method @dalvik.annotation.optimization.FastNative public void putByte(long, byte);
+  }
+
+}
+
+package sun.security.jca {
+
+  public class Providers {
+    method public static Object startJarVerification();
+    method public static void stopJarVerification(Object);
+  }
+
+}
+
+package sun.security.pkcs {
+
+  public class ContentInfo {
+    method public byte[] getContentBytes() throws java.io.IOException;
+  }
+
+  public class PKCS7 {
+    ctor public PKCS7(java.io.InputStream) throws java.io.IOException, sun.security.pkcs.ParsingException;
+    ctor public PKCS7(byte[]) throws sun.security.pkcs.ParsingException;
+    method public java.security.cert.X509Certificate[] getCertificates();
+    method public sun.security.pkcs.ContentInfo getContentInfo();
+    method public sun.security.pkcs.SignerInfo[] getSignerInfos();
+    method public sun.security.pkcs.SignerInfo verify(sun.security.pkcs.SignerInfo, java.io.InputStream) throws java.io.IOException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
+    method public sun.security.pkcs.SignerInfo[] verify(byte[]) throws java.security.NoSuchAlgorithmException, java.security.SignatureException;
+  }
+
+  public class ParsingException extends java.io.IOException {
+  }
+
+  public class SignerInfo {
+    ctor public SignerInfo();
+    method public java.util.ArrayList<java.security.cert.X509Certificate> getCertificateChain(sun.security.pkcs.PKCS7) throws java.io.IOException;
+  }
+
+}
+
+package sun.security.util {
+
+  public final class ObjectIdentifier implements java.io.Serializable {
+    ctor public ObjectIdentifier(String) throws java.io.IOException;
+  }
+
+}
+
+package sun.security.x509 {
+
+  public class AlgorithmId implements java.io.Serializable {
+    ctor public AlgorithmId(sun.security.util.ObjectIdentifier);
+    method public String getName();
+  }
+
+}
+
+package sun.util.locale {
+
+  public class LanguageTag {
+    method public static boolean isLanguage(String);
+  }
+
+}
+
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..d802177
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/current-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
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..e69de29
--- /dev/null
+++ b/mmodules/core_platform_api/api/platform/last-api.txt
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/intracoreapi/Android.bp b/mmodules/intracoreapi/Android.bp
new file mode 100644
index 0000000..a07f540
--- /dev/null
+++ b/mmodules/intracoreapi/Android.bp
@@ -0,0 +1,95 @@
+// 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_standard_libs: true,
+    libs: ["core-all"],
+
+    installable: false,
+    args: "--hide-annotation libcore.api.Hide "
+        + "--show-single-annotation libcore.api.IntraCoreApi "
+        + "--skip-annotation-instance-methods=false ",
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
+
+    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 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"],
+}
+
+// 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. This proves we
+// don't actually depend on things from (for example) conscrypt we haven't added
+// to the intra-core API.
+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",
+    java_version: "1.9",
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+}
+
diff --git a/mmodules/intracoreapi/api/intra/current-api.txt b/mmodules/intracoreapi/api/intra/current-api.txt
new file mode 100644
index 0000000..a7a2fdc
--- /dev/null
+++ b/mmodules/intracoreapi/api/intra/current-api.txt
@@ -0,0 +1,505 @@
+// Signature format: 2.0
+package android.system {
+
+  public final class ErrnoException extends java.lang.Exception {
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
+  }
+
+}
+
+package com.android.org.conscrypt {
+
+  @libcore.api.IntraCoreApi public class DESEDESecretKeyFactory extends javax.crypto.SecretKeyFactorySpi {
+    ctor @libcore.api.IntraCoreApi public DESEDESecretKeyFactory();
+  }
+
+  @libcore.api.IntraCoreApi public final class DefaultSSLContextImpl extends com.android.org.conscrypt.OpenSSLContextImpl {
+    ctor @libcore.api.IntraCoreApi public DefaultSSLContextImpl() throws java.security.GeneralSecurityException, java.io.IOException;
+  }
+
+  @libcore.api.IntraCoreApi public class ECParameters extends java.security.AlgorithmParametersSpi {
+    ctor @libcore.api.IntraCoreApi public ECParameters();
+  }
+
+  @libcore.api.IntraCoreApi public final class GCMParameters extends java.security.AlgorithmParametersSpi {
+    ctor @libcore.api.IntraCoreApi public GCMParameters();
+  }
+
+  @libcore.api.IntraCoreApi public class IvParameters extends java.security.AlgorithmParametersSpi {
+    ctor @libcore.api.IntraCoreApi public IvParameters();
+  }
+
+  @libcore.api.IntraCoreApi public static class IvParameters.AES extends com.android.org.conscrypt.IvParameters {
+    ctor @libcore.api.IntraCoreApi public IvParameters.AES();
+  }
+
+  @libcore.api.IntraCoreApi public static class IvParameters.ChaCha20 extends com.android.org.conscrypt.IvParameters {
+    ctor @libcore.api.IntraCoreApi public IvParameters.ChaCha20();
+  }
+
+  @libcore.api.IntraCoreApi public static class IvParameters.DESEDE extends com.android.org.conscrypt.IvParameters {
+    ctor @libcore.api.IntraCoreApi public IvParameters.DESEDE();
+  }
+
+  @libcore.api.IntraCoreApi public abstract class KeyGeneratorImpl extends javax.crypto.KeyGeneratorSpi {
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.AES extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.AES();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.ARC4 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.ARC4();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.ChaCha20 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.ChaCha20();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.DESEDE extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.DESEDE();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacMD5 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacMD5();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacSHA1 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacSHA1();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacSHA224 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacSHA224();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacSHA256 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacSHA256();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacSHA384 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacSHA384();
+  }
+
+  @libcore.api.IntraCoreApi public static final class KeyGeneratorImpl.HmacSHA512 extends com.android.org.conscrypt.KeyGeneratorImpl {
+    ctor @libcore.api.IntraCoreApi public KeyGeneratorImpl.HmacSHA512();
+  }
+
+  @libcore.api.IntraCoreApi public class OAEPParameters extends java.security.AlgorithmParametersSpi {
+    ctor @libcore.api.IntraCoreApi public OAEPParameters();
+  }
+
+  @libcore.api.IntraCoreApi public abstract class OpenSSLCipher extends javax.crypto.CipherSpi {
+  }
+
+  @libcore.api.IntraCoreApi public abstract static class OpenSSLCipher.EVP_AEAD extends com.android.org.conscrypt.OpenSSLCipher {
+  }
+
+  @libcore.api.IntraCoreApi public abstract static class OpenSSLCipher.EVP_AEAD.AES extends com.android.org.conscrypt.OpenSSLCipher.EVP_AEAD {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_AEAD.AES.GCM extends com.android.org.conscrypt.OpenSSLCipher.EVP_AEAD.AES {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_AEAD.AES.GCM();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_AEAD.AES.GCM.AES_128 extends com.android.org.conscrypt.OpenSSLCipher.EVP_AEAD.AES.GCM {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_AEAD.AES.GCM.AES_128();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_AEAD.AES.GCM.AES_256 extends com.android.org.conscrypt.OpenSSLCipher.EVP_AEAD.AES.GCM {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_AEAD.AES.GCM.AES_256();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_AEAD.ChaCha20 extends com.android.org.conscrypt.OpenSSLCipher.EVP_AEAD {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_AEAD.ChaCha20();
+  }
+
+  @libcore.api.IntraCoreApi public abstract static class OpenSSLCipher.EVP_CIPHER extends com.android.org.conscrypt.OpenSSLCipher {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.CBC extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.CBC.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES.CBC.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.CBC.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES.CBC.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.CTR extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES.CTR();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.ECB extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.ECB.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES.ECB.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES.ECB.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES.ECB.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128 extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.CBC extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128 {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.CBC.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_128.CBC.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.CBC.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_128.CBC.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.ECB extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128 {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.ECB.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_128.ECB.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_128.ECB.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_128.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_128.ECB.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256 extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.CBC extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256 {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.CBC.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_256.CBC.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.CBC.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_256.CBC.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.ECB extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256 {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.ECB.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_256.ECB.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.AES_256.ECB.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.AES_256.ECB {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.AES_256.ECB.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.ARC4 extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.ARC4();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.DESEDE extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.DESEDE.CBC extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.DESEDE {
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.DESEDE.CBC.NoPadding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.DESEDE.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.DESEDE.CBC.NoPadding();
+  }
+
+  @libcore.api.IntraCoreApi public static class OpenSSLCipher.EVP_CIPHER.DESEDE.CBC.PKCS5Padding extends com.android.org.conscrypt.OpenSSLCipher.EVP_CIPHER.DESEDE.CBC {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipher.EVP_CIPHER.DESEDE.CBC.PKCS5Padding();
+  }
+
+  @libcore.api.IntraCoreApi public class OpenSSLCipherChaCha20 extends com.android.org.conscrypt.OpenSSLCipher {
+    ctor @libcore.api.IntraCoreApi public OpenSSLCipherChaCha20();
+  }
+
+  @libcore.api.IntraCoreApi public abstract class OpenSSLContextImpl extends javax.net.ssl.SSLContextSpi {
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLContextImpl.TLSv1 extends com.android.org.conscrypt.OpenSSLContextImpl {
+    ctor @libcore.api.IntraCoreApi public OpenSSLContextImpl.TLSv1();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLContextImpl.TLSv11 extends com.android.org.conscrypt.OpenSSLContextImpl {
+    ctor @libcore.api.IntraCoreApi public OpenSSLContextImpl.TLSv11();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLContextImpl.TLSv12 extends com.android.org.conscrypt.OpenSSLContextImpl {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.IntraCoreApi public OpenSSLContextImpl.TLSv12();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLContextImpl.TLSv13 extends com.android.org.conscrypt.OpenSSLContextImpl {
+    ctor @libcore.api.IntraCoreApi public OpenSSLContextImpl.TLSv13();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLECDHKeyAgreement extends javax.crypto.KeyAgreementSpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLECDHKeyAgreement();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLECKeyFactory extends java.security.KeyFactorySpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLECKeyFactory();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLECKeyPairGenerator extends java.security.KeyPairGenerator {
+    ctor @libcore.api.IntraCoreApi public OpenSSLECKeyPairGenerator();
+  }
+
+  @libcore.api.IntraCoreApi public abstract class OpenSSLMac extends javax.crypto.MacSpi {
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacMD5 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacMD5();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacSHA1 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacSHA1();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacSHA224 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacSHA224() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacSHA256 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacSHA256() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacSHA384 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacSHA384() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMac.HmacSHA512 extends com.android.org.conscrypt.OpenSSLMac {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMac.HmacSHA512();
+  }
+
+  @libcore.api.IntraCoreApi public class OpenSSLMessageDigestJDK extends java.security.MessageDigestSpi implements java.lang.Cloneable {
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.MD5 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.MD5() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.SHA1 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.SHA1() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.SHA224 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.SHA224() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.SHA256 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.SHA256() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.SHA384 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.SHA384() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLMessageDigestJDK.SHA512 extends com.android.org.conscrypt.OpenSSLMessageDigestJDK {
+    ctor @libcore.api.IntraCoreApi public OpenSSLMessageDigestJDK.SHA512() throws java.security.NoSuchAlgorithmException;
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLRSAKeyFactory extends java.security.KeyFactorySpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLRSAKeyFactory();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLRSAKeyPairGenerator extends java.security.KeyPairGeneratorSpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLRSAKeyPairGenerator();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLRandom extends java.security.SecureRandomSpi implements java.io.Serializable {
+    ctor @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.IntraCoreApi public OpenSSLRandom();
+  }
+
+  @libcore.api.IntraCoreApi public class OpenSSLSignature extends java.security.SignatureSpi {
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.MD5RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.MD5RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA1ECDSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA1ECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA1RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA1RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA1RSAPSS extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA1RSAPSS();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA224ECDSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA224ECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA224RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA224RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA224RSAPSS extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA224RSAPSS();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA256ECDSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA256ECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA256RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA256RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA256RSAPSS extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA256RSAPSS();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA384ECDSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA384ECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA384RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA384RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA384RSAPSS extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA384RSAPSS();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA512ECDSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA512ECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA512RSA extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA512RSA();
+  }
+
+  @libcore.api.IntraCoreApi public static final class OpenSSLSignature.SHA512RSAPSS extends com.android.org.conscrypt.OpenSSLSignature {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignature.SHA512RSAPSS();
+  }
+
+  @libcore.api.IntraCoreApi public class OpenSSLSignatureRawECDSA extends java.security.SignatureSpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignatureRawECDSA();
+  }
+
+  @libcore.api.IntraCoreApi public final class OpenSSLSignatureRawRSA extends java.security.SignatureSpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLSignatureRawRSA();
+  }
+
+  @libcore.api.IntraCoreApi public class OpenSSLX509CertificateFactory extends java.security.cert.CertificateFactorySpi {
+    ctor @libcore.api.IntraCoreApi public OpenSSLX509CertificateFactory();
+  }
+
+  @libcore.api.IntraCoreApi public class PSSParameters extends java.security.AlgorithmParametersSpi {
+    ctor @libcore.api.IntraCoreApi public PSSParameters();
+  }
+
+}
+
+package dalvik.annotation.compat {
+
+  @java.lang.annotation.Repeatable(UnsupportedAppUsage.Container.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.TYPE}) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public @interface UnsupportedAppUsage {
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract String expectedSignature() default "";
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract String implicitMember() default "";
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract int maxTargetSdk() default java.lang.Integer.MAX_VALUE;
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract long trackingBug() default 0;
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static @interface UnsupportedAppUsage.Container {
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract dalvik.annotation.compat.UnsupportedAppUsage[] value();
+  }
+
+}
+
+package dalvik.system {
+
+  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class BlockGuard {
+    method @NonNull @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static dalvik.system.BlockGuard.Policy getThreadPolicy();
+  }
+
+  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static interface BlockGuard.Policy {
+    method @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.IntraCoreApi public void onNetwork();
+  }
+
+  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class CloseGuard {
+    method @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void close();
+    method @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static dalvik.system.CloseGuard get();
+    method @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void open(String);
+    method @dalvik.annotation.compat.UnsupportedAppUsage @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void warnIfOpen();
+  }
+
+  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public class VersionCodes {
+    field @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static final int O = 26; // 0x1a
+    field @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static final int P = 28; // 0x1c
+  }
+
+}
+
+package java.net {
+
+  public class Socket implements java.io.Closeable {
+    method public java.io.FileDescriptor getFileDescriptor$();
+  }
+
+}
+
+package java.security.spec {
+
+  public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    method public String getCurveName();
+    method public void setCurveName(String);
+  }
+
+}
+
+package libcore.api {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.ANNOTATION_TYPE}) @libcore.api.IntraCoreApi public @interface CorePlatformApi {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.ANNOTATION_TYPE}) @libcore.api.IntraCoreApi public @interface IntraCoreApi {
+  }
+
+}
+
+package libcore.net {
+
+  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract class NetworkSecurityPolicy {
+    ctor @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public NetworkSecurityPolicy();
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static libcore.net.NetworkSecurityPolicy getInstance();
+    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract boolean isCertificateTransparencyVerificationRequired(String);
+  }
+
+}
+
+package libcore.util {
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE_USE}) @libcore.api.IntraCoreApi public @interface NonNull {
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE_USE}) @libcore.api.IntraCoreApi public @interface Nullable {
+  }
+
+}
+
+package sun.security.util {
+
+  public interface DerEncoder {
+    method public void derEncode(java.io.OutputStream) throws java.io.IOException;
+  }
+
+}
+
+package sun.security.x509 {
+
+  public class AlgorithmId implements sun.security.util.DerEncoder java.io.Serializable {
+    method public void derEncode(java.io.OutputStream) throws java.io.IOException;
+    method public static sun.security.x509.AlgorithmId get(String) throws java.security.NoSuchAlgorithmException;
+    method public String getName();
+  }
+
+}
+
diff --git a/mmodules/intracoreapi/api/intra/current-removed.txt b/mmodules/intracoreapi/api/intra/current-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/mmodules/intracoreapi/api/intra/current-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/mmodules/intracoreapi/api/intra/last-api.txt b/mmodules/intracoreapi/api/intra/last-api.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/intracoreapi/api/intra/last-api.txt
diff --git a/mmodules/intracoreapi/api/intra/last-removed.txt b/mmodules/intracoreapi/api/intra/last-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mmodules/intracoreapi/api/intra/last-removed.txt
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 929b411..3e4083f 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -1,6 +1,5 @@
 filegroup {
     name: "non_openjdk_javadoc_files",
-    export_to_make_var: "non_openjdk_javadoc_files",
     srcs: [
         "luni/src/main/java/android/system/ErrnoException.java",
         "luni/src/main/java/android/system/GaiException.java",
@@ -27,6 +26,7 @@
         "luni/src/main/java/android/system/StructTimespec.java",
         "luni/src/main/java/android/system/StructUcred.java",
         "luni/src/main/java/android/system/StructUtsname.java",
+        "luni/src/main/java/android/system/UnixSocketAddress.java",
         "dalvik/src/main/java/dalvik/annotation/AnnotationDefault.java",
         "dalvik/src/main/java/dalvik/annotation/EnclosingClass.java",
         "dalvik/src/main/java/dalvik/annotation/EnclosingMethod.java",
@@ -38,13 +38,16 @@
         "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/compat/UnsupportedAppUsage.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java",
+        "dalvik/src/main/java/dalvik/annotation/optimization/DeadReferenceSafe.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java",
         "dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java",
         "dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java",
         "dalvik/src/main/java/dalvik/bytecode/Opcodes.java",
-        "libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java",
         "dalvik/src/main/java/dalvik/system/AllocationLimitError.java",
+        "libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java",
         "dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java",
         "dalvik/src/main/java/dalvik/system/BlockGuard.java",
         "libart/src/main/java/dalvik/system/ClassExt.java",
@@ -60,9 +63,11 @@
         "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",
+        "dalvik/src/main/java/dalvik/system/VersionCodes.java",
         "dalvik/src/main/java/dalvik/system/VMDebug.java",
         "libart/src/main/java/dalvik/system/VMRuntime.java",
         "libart/src/main/java/dalvik/system/VMStack.java",
@@ -154,6 +159,49 @@
         "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/icu/DateIntervalFormat.java",
+        "luni/src/main/java/libcore/api/Hide.java",
+        "luni/src/main/java/libcore/api/IntraCoreApi.java",
+        "luni/src/main/java/libcore/icu/ICU.java",
+        "luni/src/main/java/libcore/icu/LocaleData.java",
+        "luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java",
+        "luni/src/main/java/libcore/icu/TimeZoneNames.java",
+        "luni/src/main/java/libcore/internal/StringPool.java",
+        "luni/src/main/java/libcore/io/ForwardingOs.java",
+        "luni/src/main/java/libcore/io/IoBridge.java",
+        "luni/src/main/java/libcore/io/IoUtils.java",
+        "luni/src/main/java/libcore/io/Libcore.java",
+        "luni/src/main/java/libcore/io/Memory.java",
+        "luni/src/main/java/libcore/io/Os.java",
+        "luni/src/main/java/libcore/io/Streams.java",
+        "luni/src/main/java/libcore/net/InetAddressUtils.java",
+        "luni/src/main/java/libcore/net/MimeUtils.java",
+        "luni/src/main/java/libcore/net/NetworkSecurityPolicy.java",
+        "luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java",
+        "luni/src/main/java/libcore/timezone/CountryTimeZones.java",
+        "luni/src/main/java/libcore/timezone/CountryZonesFinder.java",
+        "luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java",
+        "luni/src/main/java/libcore/timezone/TimeZoneFinder.java",
+        "luni/src/main/java/libcore/timezone/TzDataSetVersion.java",
+        "luni/src/main/java/libcore/timezone/ZoneInfoDB.java",
+        "luni/src/main/java/libcore/util/ArrayUtils.java",
+        "luni/src/main/java/libcore/util/BasicLruCache.java",
+        "luni/src/main/java/libcore/util/CoreLibraryDebug.java",
+        "luni/src/main/java/libcore/util/DebugInfo.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/SneakyThrow.java",
+        "luni/src/main/java/libcore/util/XmlObjectFactory.java",
+        "luni/src/main/java/libcore/util/ZoneInfo.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",
         "json/src/main/java/org/json/JSON.java",
         "json/src/main/java/org/json/JSONArray.java",
         "json/src/main/java/org/json/JSONException.java",
@@ -245,43 +293,22 @@
 
 filegroup {
     name: "non_openjdk_java_files",
-    export_to_make_var: "non_openjdk_java_files",
     srcs: [
-        "luni/src/main/java/android/system/UnixSocketAddress.java",
         "luni/src/main/java/java/net/AddressCache.java",
         "luni/src/main/java/libcore/icu/CollationKeyICU.java",
-        "luni/src/main/java/libcore/icu/DateIntervalFormat.java",
         "luni/src/main/java/libcore/icu/DateTimeFormat.java",
         "luni/src/main/java/libcore/icu/DateUtilsBridge.java",
-        "luni/src/main/java/libcore/icu/ICU.java",
-        "luni/src/main/java/libcore/icu/LocaleData.java",
         "luni/src/main/java/libcore/icu/NativeConverter.java",
-        "luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java",
-        "luni/src/main/java/libcore/icu/TimeZoneNames.java",
-        "luni/src/main/java/libcore/internal/StringPool.java",
+        "luni/src/main/java/libcore/internal/Java9LanguageFeatures.java",
         "luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java",
         "luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java",
         "luni/src/main/java/libcore/io/BlockGuardOs.java",
         "luni/src/main/java/libcore/io/BufferIterator.java",
-        "luni/src/main/java/libcore/io/DropBox.java",
-        "luni/src/main/java/libcore/io/EventLogger.java",
-        "luni/src/main/java/libcore/io/ForwardingOs.java",
-        "luni/src/main/java/libcore/io/IoBridge.java",
         "luni/src/main/java/libcore/io/IoTracker.java",
-        "luni/src/main/java/libcore/io/IoUtils.java",
-        "luni/src/main/java/libcore/io/Libcore.java",
         "luni/src/main/java/libcore/io/Linux.java",
-        "luni/src/main/java/libcore/io/Memory.java",
         "luni/src/main/java/libcore/io/MemoryMappedFile.java",
         "luni/src/main/java/libcore/io/NioBufferIterator.java",
-        "luni/src/main/java/libcore/io/Os.java",
-        "luni/src/main/java/libcore/io/SizeOf.java",
-        "luni/src/main/java/libcore/io/Streams.java",
         "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",
         "luni/src/main/java/libcore/net/http/ResponseUtils.java",
@@ -298,30 +325,11 @@
         "luni/src/main/java/libcore/reflect/Types.java",
         "luni/src/main/java/libcore/reflect/WildcardTypeImpl.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",
         "luni/src/main/java/libcore/util/CollectionUtils.java",
-        "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/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/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 +360,19 @@
         "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",
     ],
 }
+
+// timezone-related source that is also used in host tests / tools and its
+// dependencies.
+filegroup {
+    name: "timezone_host_files",
+    srcs: [
+        "luni/src/main/java/libcore/api/CorePlatformApi.java",
+        "luni/src/main/java/libcore/api/IntraCoreApi.java",
+        "luni/src/main/java/libcore/timezone/TzDataSetVersion.java",
+    ],
+}
diff --git a/nullability_annotated_classes.txt b/nullability_annotated_classes.txt
new file mode 100644
index 0000000..e241e0b
--- /dev/null
+++ b/nullability_annotated_classes.txt
@@ -0,0 +1,6 @@
+# The following classes have nullability annotations directly in their source
+# which should be validated for correctness and completeness. (N.B. Classes
+# with annotations in stub files under ojluni/annotations/sdk/nullability/
+# should also be validated, but are not listed here.)
+java.math.BigInteger
+org.json.JSONObject
diff --git a/nullability_warnings.txt b/nullability_warnings.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nullability_warnings.txt
diff --git a/ojluni/annotations/README b/ojluni/annotations/README
new file mode 100644
index 0000000..e88e233
--- /dev/null
+++ b/ojluni/annotations/README
@@ -0,0 +1,40 @@
+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.
+ - To add some new files under this directory:
+   1. make openjdk-sdk-stubs-no-javadoc
+   2. for FILE in your/package/and/Class.java another/package/AnotherClass.java; do mkdir -p libcore/ojluni/annotations/sdk/nullability/$(dirname ${FILE}) && cp out/soong/.intermediates/libcore/openjdk-sdk-stubs-no-javadoc/android_common/stubsDir/${FILE} libcore/ojluni/annotations/sdk/nullability/${FILE/%.java/.annotated.java}; done
+   3. Add nullability annotations to the new files.
+ - To see the effect of the files under this directory:
+   1. make api-stubs-docs
+   2. Look for the file under out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/stubsDir/
+
+libcore/ojluni/annotations/mmodule:
+ - Contains annotations which determine what is included in the core-platform
+   and intra-core APIs. See the documentation in libcore/openjdk_java_files.bp.
+ - To add some new files under this directory:
+   1. In libcore/openjdk_java_files.bp, move the files from the
+      openjdk_internal_files filegroup to openjdk_mmodule_extra_files. *DO NOT*
+      check in this change, it will have undesirable consequences until you
+      reach step 4, below.
+   2. make openjdk-mmodule-stubs-no-javadoc
+   3. FILES="your/package/and/Class.java another/package/AnotherClass.java"; for FILE in $FILES; do mkdir -p libcore/ojluni/annotations/mmodule/$(dirname ${FILE}) && cp out/soong/.intermediates/libcore/openjdk-mmodule-stubs-no-javadoc/android_common/stubsDir/${FILE} libcore/ojluni/annotations/mmodule/${FILE/%.java/.annotated.java}; done
+   4. Add @libcore.api.Hide to each top-level class in the new files. This will prevent it from being added to the public API. A JavaDoc @hide tag will not work as metalava will ignore javadoc from the stub files.
+   5. Add @libcore.api.CorePlatformApi and @libcore.api.IntraCoreApi as desired
+      to the classes and members.
+ - To see the effect of the files under this directory:
+   1. make make core-platform-api-stubs core-intra-stubs
+   2. Look for the files under out/soong/.intermediates/libcore/mmodules/core_platform_api/core-platform-api-stubs/android_common/stubsDir/ and out/soong/.intermediates/libcore/mmodules/intracoreapi/core-intra-stubs/android_common/stubsDir
diff --git a/ojluni/annotations/hiddenapi/com/sun/nio/file/ExtendedWatchEventModifier.java b/ojluni/annotations/hiddenapi/com/sun/nio/file/ExtendedWatchEventModifier.java
new file mode 100644
index 0000000..d3d1fd7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/com/sun/nio/file/ExtendedWatchEventModifier.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.nio.file;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public enum ExtendedWatchEventModifier implements java.nio.file.WatchEvent.Modifier {
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    FILE_TREE;
+
+    private ExtendedWatchEventModifier() {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/Console.java b/ojluni/annotations/hiddenapi/java/io/Console.java
new file mode 100644
index 0000000..9a93310
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/Console.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Console implements java.io.Flushable {
+
+    private Console() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private Console(java.io.InputStream inStream, java.io.OutputStream outStream) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.PrintWriter writer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.Reader reader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.Console format(java.lang.String fmt, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.Console printf(java.lang.String format, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String readLine(java.lang.String fmt, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String readLine() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char[] readPassword(java.lang.String fmt, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char[] readPassword() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void flush() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native java.lang.String encoding();
+
+    private static native boolean echo(boolean on) throws java.io.IOException;
+
+    private char[] readline(boolean zeroOut) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private char[] grow() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.Console console() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native boolean istty();
+
+    private static java.io.Console cons;
+
+    private java.nio.charset.Charset cs;
+
+    private static boolean echoOff;
+
+    private java.util.Formatter formatter;
+
+    private java.io.Writer out;
+
+    private java.io.PrintWriter pw;
+
+    private char[] rcb;
+
+    private java.lang.Object readLock;
+
+    private java.io.Reader reader;
+
+    private java.lang.Object writeLock;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    class LineReader extends java.io.Reader {
+
+        LineReader(java.io.Reader in) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean ready() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read(char[] cbuf, int offset, int length) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private char[] cb;
+
+        private java.io.Reader in;
+
+        boolean leftoverLF;
+
+        private int nChars;
+
+        private int nextChar;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/File.java b/ojluni/annotations/hiddenapi/java/io/File.java
new file mode 100644
index 0000000..7b93218
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/File.java
@@ -0,0 +1,377 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class File implements java.io.Serializable, java.lang.Comparable<java.io.File> {
+
+    private File(java.lang.String pathname, int prefixLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private File(java.lang.String child, java.io.File parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public File(java.lang.String pathname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public File(java.lang.String parent, java.lang.String child) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public File(java.io.File parent, java.lang.String child) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public File(java.net.URI uri) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isInvalid() {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getPrefixLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getParent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File getParentFile() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAbsolute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAbsolutePath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File getAbsoluteFile() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCanonicalPath() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File getCanonicalFile() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String slashify(java.lang.String path, boolean isDirectory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public java.net.URL toURL() throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI toURI() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canRead() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canWrite() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean exists() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isDirectory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isFile() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isHidden() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long lastModified() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long length() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean createNewFile() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean delete() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void deleteOnExit() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String[] list() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String[] list(java.io.FilenameFilter filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File[] listFiles() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File[] listFiles(java.io.FilenameFilter filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.File[] listFiles(java.io.FileFilter filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean mkdir() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean mkdirs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean renameTo(java.io.File dest) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setLastModified(long time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setReadOnly() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setWritable(boolean writable, boolean ownerOnly) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setWritable(boolean writable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setReadable(boolean readable, boolean ownerOnly) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setReadable(boolean readable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setExecutable(boolean executable, boolean ownerOnly) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean setExecutable(boolean executable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canExecute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.File[] listRoots() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTotalSpace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getFreeSpace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getUsableSpace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.File createTempFile(
+            java.lang.String prefix, java.lang.String suffix, java.io.File directory)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.File createTempFile(java.lang.String prefix, java.lang.String suffix)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.io.File pathname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.file.Path toPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long PATH_OFFSET;
+
+    static {
+        PATH_OFFSET = 0;
+    }
+
+    private static final long PREFIX_LENGTH_OFFSET;
+
+    static {
+        PREFIX_LENGTH_OFFSET = 0;
+    }
+
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static {
+        UNSAFE = null;
+    }
+
+    @UnsupportedAppUsage
+    private transient volatile java.nio.file.Path filePath;
+
+    @UnsupportedAppUsage
+    private static final java.io.FileSystem fs;
+
+    static {
+        fs = null;
+    }
+
+    @UnsupportedAppUsage
+    private final java.lang.String path;
+
+    {
+        path = null;
+    }
+
+    public static final java.lang.String pathSeparator;
+
+    static {
+        pathSeparator = null;
+    }
+
+    public static final char pathSeparatorChar;
+
+    static {
+        pathSeparatorChar = 0;
+    }
+
+    @UnsupportedAppUsage
+    private final transient int prefixLength;
+
+    {
+        prefixLength = 0;
+    }
+
+    public static final java.lang.String separator;
+
+    static {
+        separator = null;
+    }
+
+    public static final char separatorChar;
+
+    static {
+        separatorChar = 0;
+    }
+
+    private static final long serialVersionUID = 301077366599181567L; // 0x42da4450e0de4ffL
+
+    @UnsupportedAppUsage
+    private transient java.io.File.PathStatus status;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static enum PathStatus {
+        INVALID,
+        CHECKED;
+
+        private PathStatus() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class TempDirectory {
+
+        private TempDirectory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static java.io.File generateFile(
+                java.lang.String prefix, java.lang.String suffix, java.io.File dir)
+                throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java b/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java
new file mode 100644
index 0000000..7872403
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1995, 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class FileDescriptor {
+
+    public FileDescriptor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private FileDescriptor(int descriptor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean valid() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native void sync() throws java.io.SyncFailedException;
+
+    @UnsupportedAppUsage
+    public int getInt$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void setInt$(int fd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getOwnerId$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setOwnerId$(long newOwnerId) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.FileDescriptor release$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public boolean isSocket$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.io.FileDescriptor dupFd(int fd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native boolean isSocket(int descriptor);
+
+    public static final long NO_OWNER = 0L; // 0x0L
+
+    @UnsupportedAppUsage
+    private int descriptor;
+
+    public static final java.io.FileDescriptor err;
+
+    static {
+        err = null;
+    }
+
+    public static final java.io.FileDescriptor in;
+
+    static {
+        in = null;
+    }
+
+    public static final java.io.FileDescriptor out;
+
+    static {
+        out = null;
+    }
+
+    private long ownerId = 0L; // 0x0L
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/FileInputStream.java b/ojluni/annotations/hiddenapi/java/io/FileInputStream.java
new file mode 100644
index 0000000..3de1617
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/FileInputStream.java
@@ -0,0 +1,145 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FileInputStream extends java.io.InputStream {
+
+    public FileInputStream(java.lang.String name) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileInputStream(java.io.File file) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileInputStream(java.io.FileDescriptor fdObj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileInputStream(java.io.FileDescriptor fdObj, boolean isFdOwner) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native void open0(java.lang.String name) throws java.io.FileNotFoundException;
+
+    private void open(java.lang.String name) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long skip(long n) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native long skip0(long n)
+            throws java.io.FileInputStream.UseManualSkipException, java.io.IOException;
+
+    public int available() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native int available0() throws java.io.IOException;
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.io.FileDescriptor getFD() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.channels.FileChannel channel;
+
+    private final java.lang.Object closeLock;
+
+    {
+        closeLock = null;
+    }
+
+    private volatile boolean closed = false;
+
+    @UnsupportedAppUsage
+    private final java.io.FileDescriptor fd;
+
+    {
+        fd = null;
+    }
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    private final boolean isFdOwner;
+
+    {
+        isFdOwner = false;
+    }
+
+    private final java.lang.String path;
+
+    {
+        path = null;
+    }
+
+    private final libcore.io.IoTracker tracker;
+
+    {
+        tracker = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class UseManualSkipException extends java.lang.Exception {
+
+        private UseManualSkipException() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java b/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java
new file mode 100644
index 0000000..b918f6a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/FileOutputStream.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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FileOutputStream extends java.io.OutputStream {
+
+    public FileOutputStream(java.lang.String name) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileOutputStream(java.lang.String name, boolean append)
+            throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileOutputStream(java.io.File file) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileOutputStream(java.io.File file, boolean append)
+            throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileOutputStream(java.io.FileDescriptor fdObj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FileOutputStream(java.io.FileDescriptor fdObj, boolean isFdOwner) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native void open0(java.lang.String name, boolean append)
+            throws java.io.FileNotFoundException;
+
+    private void open(java.lang.String name, boolean append) throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(int b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.io.FileDescriptor getFD() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final boolean append;
+
+    {
+        append = false;
+    }
+
+    @UnsupportedAppUsage
+    private java.nio.channels.FileChannel channel;
+
+    private final java.lang.Object closeLock;
+
+    {
+        closeLock = null;
+    }
+
+    private volatile boolean closed = false;
+
+    @UnsupportedAppUsage
+    private final java.io.FileDescriptor fd;
+
+    {
+        fd = null;
+    }
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    private final boolean isFdOwner;
+
+    {
+        isFdOwner = false;
+    }
+
+    private final java.lang.String path;
+
+    {
+        path = null;
+    }
+
+    private final libcore.io.IoTracker tracker;
+
+    {
+        tracker = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/FileSystem.java b/ojluni/annotations/hiddenapi/java/io/FileSystem.java
new file mode 100644
index 0000000..4999b3c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/FileSystem.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1998, 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+abstract class FileSystem {
+
+    FileSystem() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public abstract char getSeparator();
+
+    @UnsupportedAppUsage
+    public abstract char getPathSeparator();
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String normalize(java.lang.String path);
+
+    @UnsupportedAppUsage
+    public abstract int prefixLength(java.lang.String path);
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String resolve(java.lang.String parent, java.lang.String child);
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String getDefaultParent();
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String fromURIPath(java.lang.String path);
+
+    @UnsupportedAppUsage
+    public abstract boolean isAbsolute(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String resolve(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String canonicalize(java.lang.String path) throws java.io.IOException;
+
+    @UnsupportedAppUsage
+    public abstract int getBooleanAttributes(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract boolean checkAccess(java.io.File f, int access);
+
+    @UnsupportedAppUsage
+    public abstract boolean setPermission(
+            java.io.File f, int access, boolean enable, boolean owneronly);
+
+    @UnsupportedAppUsage
+    public abstract long getLastModifiedTime(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract long getLength(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract boolean createFileExclusively(java.lang.String pathname)
+            throws java.io.IOException;
+
+    @UnsupportedAppUsage
+    public abstract boolean delete(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract java.lang.String[] list(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract boolean createDirectory(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract boolean rename(java.io.File f1, java.io.File f2);
+
+    @UnsupportedAppUsage
+    public abstract boolean setLastModifiedTime(java.io.File f, long time);
+
+    @UnsupportedAppUsage
+    public abstract boolean setReadOnly(java.io.File f);
+
+    @UnsupportedAppUsage
+    public abstract java.io.File[] listRoots();
+
+    @UnsupportedAppUsage
+    public abstract long getSpace(java.io.File f, int t);
+
+    @UnsupportedAppUsage
+    public abstract int compare(java.io.File f1, java.io.File f2);
+
+    @UnsupportedAppUsage
+    public abstract int hashCode(java.io.File f);
+
+    private static boolean getBooleanProperty(java.lang.String prop, boolean defaultVal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int ACCESS_EXECUTE = 1; // 0x1
+
+    public static final int ACCESS_OK = 8; // 0x8
+
+    public static final int ACCESS_READ = 4; // 0x4
+
+    public static final int ACCESS_WRITE = 2; // 0x2
+
+    public static final int BA_DIRECTORY = 4; // 0x4
+
+    public static final int BA_EXISTS = 1; // 0x1
+
+    public static final int BA_HIDDEN = 8; // 0x8
+
+    public static final int BA_REGULAR = 2; // 0x2
+
+    public static final int SPACE_FREE = 1; // 0x1
+
+    public static final int SPACE_TOTAL = 0; // 0x0
+
+    public static final int SPACE_USABLE = 2; // 0x2
+
+    static boolean useCanonCaches = false;
+
+    static boolean useCanonPrefixCache = false;
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/ObjectInputStream.java b/ojluni/annotations/hiddenapi/java/io/ObjectInputStream.java
new file mode 100644
index 0000000..90dcfea
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/ObjectInputStream.java
@@ -0,0 +1,895 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ObjectInputStream extends java.io.InputStream
+        implements java.io.ObjectInput, java.io.ObjectStreamConstants {
+
+    public ObjectInputStream(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected ObjectInputStream() throws java.io.IOException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.Object readObject()
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object readObjectOverride()
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object readUnshared()
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void defaultReadObject() throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.ObjectInputStream.GetField readFields()
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void registerValidation(java.io.ObjectInputValidation obj, int prio)
+            throws java.io.InvalidObjectException, java.io.NotActiveException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Class<?> resolveClass(java.io.ObjectStreamClass desc)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Class<?> resolveProxyClass(java.lang.String[] interfaces)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object resolveObject(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean enableResolveObject(boolean enable) throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void readStreamHeader() throws java.io.IOException, java.io.StreamCorruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.io.ObjectStreamClass readClassDescriptor()
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] buf, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int available() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean readBoolean() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte readByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int readUnsignedByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char readChar() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public short readShort() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int readUnsignedShort() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int readInt() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long readLong() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public float readFloat() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public double readDouble() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void readFully(byte[] buf) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void readFully(byte[] buf, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int skipBytes(int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public java.lang.String readLine() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String readUTF() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void verifySubclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean auditSubclass(java.lang.Class<?> subcl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readObject0(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object checkResolve(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.String readTypeString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readNull() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readHandle(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Class<?> readClass(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.ObjectStreamClass readClassDesc(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isCustomSubclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.ObjectStreamClass readProxyDesc(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.ObjectStreamClass readNonProxyDesc(boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String readString(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readArray(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Enum<?> readEnum(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readOrdinaryObject(boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readExternalData(java.io.Externalizable obj, java.io.ObjectStreamClass desc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readSerialData(java.lang.Object obj, java.io.ObjectStreamClass desc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void skipCustomData() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void defaultReadFields(java.lang.Object obj, java.io.ObjectStreamClass desc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.IOException readFatalException() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void handleReset() throws java.io.StreamCorruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native void bytesToFloats(
+            byte[] src, int srcpos, float[] dst, int dstpos, int nfloats);
+
+    @UnsupportedAppUsage
+    private static native void bytesToDoubles(
+            byte[] src, int srcpos, double[] dst, int dstpos, int ndoubles);
+
+    private static java.lang.ClassLoader latestUserDefinedLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Object cloneArray(java.lang.Object array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int NULL_HANDLE = -1; // 0xffffffff
+
+    @UnsupportedAppUsage
+    private final java.io.ObjectInputStream.BlockDataInputStream bin;
+
+    {
+        bin = null;
+    }
+
+    private boolean closed;
+
+    private java.io.SerialCallbackContext curContext;
+
+    private boolean defaultDataEnd = false;
+
+    private int depth;
+
+    private final boolean enableOverride;
+
+    {
+        enableOverride = false;
+    }
+
+    private boolean enableResolve;
+
+    private final java.io.ObjectInputStream.HandleTable handles;
+
+    {
+        handles = null;
+    }
+
+    private int passHandle = -1; // 0xffffffff
+
+    private static final java.util.HashMap<java.lang.String, java.lang.Class<?>> primClasses;
+
+    static {
+        primClasses = null;
+    }
+
+    private byte[] primVals;
+
+    private static final java.lang.Object unsharedMarker;
+
+    static {
+        unsharedMarker = null;
+    }
+
+    private final java.io.ObjectInputStream.ValidationList vlist;
+
+    {
+        vlist = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class BlockDataInputStream extends java.io.InputStream implements java.io.DataInput {
+
+        BlockDataInputStream(java.io.InputStream in) {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean setBlockDataMode(boolean newmode) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean getBlockDataMode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void skipBlockData() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int readBlockHeader(boolean canBlock) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void refill() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        int currentBlockRemaining() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int peek() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        byte peekByte() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long skip(long len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int available() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        int read(byte[] b, int off, int len, boolean copy) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void readFully(byte[] b) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void readFully(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void readFully(byte[] b, int off, int len, boolean copy) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int skipBytes(int n) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean readBoolean() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte readByte() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int readUnsignedByte() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public char readChar() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public short readShort() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int readUnsignedShort() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int readInt() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public float readFloat() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long readLong() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public double readDouble() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String readUTF() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String readLine() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readBooleans(boolean[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readChars(char[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readShorts(short[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readInts(int[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readFloats(float[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readLongs(long[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readDoubles(double[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.String readLongUTF() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String readUTFBody(long utflen) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private long readUTFSpan(java.lang.StringBuilder sbuf, long utflen)
+                throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int readUTFChar(java.lang.StringBuilder sbuf, long utflen)
+                throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        long getBytesRead() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int CHAR_BUF_SIZE = 256; // 0x100
+
+        private static final int HEADER_BLOCKED = -2; // 0xfffffffe
+
+        private static final int MAX_BLOCK_SIZE = 1024; // 0x400
+
+        private static final int MAX_HEADER_SIZE = 5; // 0x5
+
+        private boolean blkmode = false;
+
+        private final byte[] buf;
+
+        {
+            buf = new byte[0];
+        }
+
+        private final char[] cbuf;
+
+        {
+            cbuf = new char[0];
+        }
+
+        private final java.io.DataInputStream din;
+
+        {
+            din = null;
+        }
+
+        private int end = -1; // 0xffffffff
+
+        private final byte[] hbuf;
+
+        {
+            hbuf = new byte[0];
+        }
+
+        private final java.io.ObjectInputStream.PeekInputStream in;
+
+        {
+            in = null;
+        }
+
+        private int pos = 0; // 0x0
+
+        private int unread = 0; // 0x0
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Caches {
+
+        private Caches() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.concurrent.ConcurrentMap<
+                        java.io.ObjectStreamClass.WeakClassKey, java.lang.Boolean>
+                subclassAudits;
+
+        static {
+            subclassAudits = null;
+        }
+
+        static final java.lang.ref.ReferenceQueue<java.lang.Class<?>> subclassAuditsQueue;
+
+        static {
+            subclassAuditsQueue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public abstract static class GetField {
+
+        public GetField() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public abstract java.io.ObjectStreamClass getObjectStreamClass();
+
+        public abstract boolean defaulted(java.lang.String name) throws java.io.IOException;
+
+        public abstract boolean get(java.lang.String name, boolean val) throws java.io.IOException;
+
+        public abstract byte get(java.lang.String name, byte val) throws java.io.IOException;
+
+        public abstract char get(java.lang.String name, char val) throws java.io.IOException;
+
+        public abstract short get(java.lang.String name, short val) throws java.io.IOException;
+
+        public abstract int get(java.lang.String name, int val) throws java.io.IOException;
+
+        public abstract long get(java.lang.String name, long val) throws java.io.IOException;
+
+        public abstract float get(java.lang.String name, float val) throws java.io.IOException;
+
+        public abstract double get(java.lang.String name, double val) throws java.io.IOException;
+
+        public abstract java.lang.Object get(java.lang.String name, java.lang.Object val)
+                throws java.io.IOException;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class GetFieldImpl extends java.io.ObjectInputStream.GetField {
+
+        GetFieldImpl(java.io.ObjectStreamClass desc) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.io.ObjectStreamClass getObjectStreamClass() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean defaulted(java.lang.String name) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean get(java.lang.String name, boolean val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte get(java.lang.String name, byte val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public char get(java.lang.String name, char val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public short get(java.lang.String name, short val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int get(java.lang.String name, int val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public float get(java.lang.String name, float val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long get(java.lang.String name, long val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public double get(java.lang.String name, double val) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object get(java.lang.String name, java.lang.Object val)
+                throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readFields() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFieldOffset(java.lang.String name, java.lang.Class<?> type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.ObjectStreamClass desc;
+
+        {
+            desc = null;
+        }
+
+        private final int[] objHandles;
+
+        {
+            objHandles = new int[0];
+        }
+
+        private final java.lang.Object[] objVals;
+
+        {
+            objVals = new java.lang.Object[0];
+        }
+
+        private final byte[] primVals;
+
+        {
+            primVals = new byte[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class HandleTable {
+
+        HandleTable(int initialCapacity) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int assign(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void markDependency(int dependent, int target) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void markException(int handle, java.lang.ClassNotFoundException ex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void finish(int handle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setObject(int handle, java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object lookupObject(int handle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.ClassNotFoundException lookupException(int handle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void grow() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final byte STATUS_EXCEPTION = 3; // 0x3
+
+        private static final byte STATUS_OK = 1; // 0x1
+
+        private static final byte STATUS_UNKNOWN = 2; // 0x2
+
+        java.io.ObjectInputStream.HandleTable.HandleList[] deps;
+
+        java.lang.Object[] entries;
+
+        int lowDep = -1; // 0xffffffff
+
+        int size = 0; // 0x0
+
+        byte[] status;
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private static class HandleList {
+
+            public HandleList() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public void add(int handle) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public int get(int index) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public int size() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private int[] list;
+
+            private int size = 0; // 0x0
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class PeekInputStream extends java.io.InputStream {
+
+        PeekInputStream(java.io.InputStream in) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int peek() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void readFully(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long skip(long n) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int available() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long getBytesRead() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.InputStream in;
+
+        {
+            in = null;
+        }
+
+        private int peekb = -1; // 0xffffffff
+
+        private long totalBytesRead = 0; // 0x0
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ValidationList {
+
+        ValidationList() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void register(java.io.ObjectInputValidation obj, int priority)
+                throws java.io.InvalidObjectException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void doCallbacks() throws java.io.InvalidObjectException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.io.ObjectInputStream.ValidationList.Callback list;
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private static class Callback {
+
+            Callback(
+                    java.io.ObjectInputValidation obj,
+                    int priority,
+                    java.io.ObjectInputStream.ValidationList.Callback next,
+                    java.security.AccessControlContext acc) {
+                throw new RuntimeException("Stub!");
+            }
+
+            final java.security.AccessControlContext acc;
+
+            {
+                acc = null;
+            }
+
+            java.io.ObjectInputStream.ValidationList.Callback next;
+
+            final java.io.ObjectInputValidation obj;
+
+            {
+                obj = null;
+            }
+
+            final int priority;
+
+            {
+                priority = 0;
+            }
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java b/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java
new file mode 100644
index 0000000..f3e462d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java
@@ -0,0 +1,745 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ObjectOutputStream extends java.io.OutputStream
+        implements java.io.ObjectOutput, java.io.ObjectStreamConstants {
+
+    public ObjectOutputStream(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected ObjectOutputStream() throws java.io.IOException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void useProtocolVersion(int version) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeObject(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void writeObjectOverride(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeUnshared(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void defaultWriteObject() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.ObjectOutputStream.PutField putFields() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeFields() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void annotateClass(java.lang.Class<?> cl) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void annotateProxyClass(java.lang.Class<?> cl) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object replaceObject(java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean enableReplaceObject(boolean enable) throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void writeStreamHeader() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void writeClassDescriptor(java.io.ObjectStreamClass desc) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(int val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] buf) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] buf, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void flush() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void drain() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeBoolean(boolean val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeByte(int val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeShort(int val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeChar(int val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeInt(int val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeLong(long val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeFloat(float val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeDouble(double val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeBytes(java.lang.String str) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeChars(java.lang.String str) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeUTF(java.lang.String str) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getProtocolVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void writeTypeString(java.lang.String str) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void verifySubclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean auditSubclass(java.lang.Class<?> subcl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject0(java.lang.Object obj, boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeNull() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeHandle(int handle) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeClass(java.lang.Class<?> cl, boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeClassDesc(java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isCustomSubclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeProxyDesc(java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeNonProxyDesc(java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeString(java.lang.String str, boolean unshared) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeArray(
+            java.lang.Object array, java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeEnum(java.lang.Enum<?> en, java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeOrdinaryObject(
+            java.lang.Object obj, java.io.ObjectStreamClass desc, boolean unshared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeExternalData(java.io.Externalizable obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeSerialData(java.lang.Object obj, java.io.ObjectStreamClass desc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void defaultWriteFields(java.lang.Object obj, java.io.ObjectStreamClass desc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeFatalException(java.io.IOException ex) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void floatsToBytes(
+            float[] src, int srcpos, byte[] dst, int dstpos, int nfloats);
+
+    private static native void doublesToBytes(
+            double[] src, int srcpos, byte[] dst, int dstpos, int ndoubles);
+
+    private final java.io.ObjectOutputStream.BlockDataOutputStream bout;
+
+    {
+        bout = null;
+    }
+
+    private java.io.SerialCallbackContext curContext;
+
+    private java.io.ObjectOutputStream.PutFieldImpl curPut;
+
+    private final java.io.ObjectOutputStream.DebugTraceInfoStack debugInfoStack;
+
+    {
+        debugInfoStack = null;
+    }
+
+    private int depth;
+
+    private final boolean enableOverride;
+
+    {
+        enableOverride = false;
+    }
+
+    private boolean enableReplace;
+
+    private static final boolean extendedDebugInfo = false;
+
+    private final java.io.ObjectOutputStream.HandleTable handles;
+
+    {
+        handles = null;
+    }
+
+    private byte[] primVals;
+
+    @UnsupportedAppUsage
+    private int protocol = 2; // 0x2
+
+    private final java.io.ObjectOutputStream.ReplaceTable subs;
+
+    {
+        subs = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class BlockDataOutputStream extends java.io.OutputStream
+            implements java.io.DataOutput {
+
+        BlockDataOutputStream(java.io.OutputStream out) {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean setBlockDataMode(boolean mode) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean getBlockDataMode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void warnIfClosed() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void write(int b) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void write(byte[] b) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void write(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void flush() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void write(byte[] b, int off, int len, boolean copy) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void drain() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void writeBlockHeader(int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeBoolean(boolean v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeByte(int v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeChar(int v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeShort(int v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeInt(int v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeFloat(float v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeLong(long v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeDouble(double v) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeBytes(java.lang.String s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeChars(java.lang.String s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void writeUTF(java.lang.String s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeBooleans(boolean[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeChars(char[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeShorts(short[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeInts(int[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeFloats(float[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeLongs(long[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeDoubles(double[] v, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        long getUTFLength(java.lang.String s) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeUTF(java.lang.String s, long utflen) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeLongUTF(java.lang.String s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeLongUTF(java.lang.String s, long utflen) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void writeUTFBody(java.lang.String s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int CHAR_BUF_SIZE = 256; // 0x100
+
+        private static final int MAX_BLOCK_SIZE = 1024; // 0x400
+
+        private static final int MAX_HEADER_SIZE = 5; // 0x5
+
+        private boolean blkmode = false;
+
+        private final byte[] buf;
+
+        {
+            buf = new byte[0];
+        }
+
+        private final char[] cbuf;
+
+        {
+            cbuf = new char[0];
+        }
+
+        private final java.io.DataOutputStream dout;
+
+        {
+            dout = null;
+        }
+
+        private final byte[] hbuf;
+
+        {
+            hbuf = new byte[0];
+        }
+
+        private final java.io.OutputStream out;
+
+        {
+            out = null;
+        }
+
+        private int pos = 0; // 0x0
+
+        private boolean warnOnceWhenWriting;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Caches {
+
+        private Caches() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.concurrent.ConcurrentMap<
+                        java.io.ObjectStreamClass.WeakClassKey, java.lang.Boolean>
+                subclassAudits;
+
+        static {
+            subclassAudits = null;
+        }
+
+        static final java.lang.ref.ReferenceQueue<java.lang.Class<?>> subclassAuditsQueue;
+
+        static {
+            subclassAuditsQueue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DebugTraceInfoStack {
+
+        DebugTraceInfoStack() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void pop() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void push(java.lang.String entry) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.List<java.lang.String> stack;
+
+        {
+            stack = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class HandleTable {
+
+        HandleTable(int initialCapacity, float loadFactor) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int assign(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int lookup(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void insert(java.lang.Object obj, int handle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void growSpine() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void growEntries() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int hash(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final float loadFactor;
+
+        {
+            loadFactor = 0;
+        }
+
+        private int[] next;
+
+        private java.lang.Object[] objs;
+
+        private int size;
+
+        private int[] spine;
+
+        private int threshold;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public abstract static class PutField {
+
+        public PutField() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public abstract void put(java.lang.String name, boolean val);
+
+        public abstract void put(java.lang.String name, byte val);
+
+        public abstract void put(java.lang.String name, char val);
+
+        public abstract void put(java.lang.String name, short val);
+
+        public abstract void put(java.lang.String name, int val);
+
+        public abstract void put(java.lang.String name, long val);
+
+        public abstract void put(java.lang.String name, float val);
+
+        public abstract void put(java.lang.String name, double val);
+
+        public abstract void put(java.lang.String name, java.lang.Object val);
+
+        @Deprecated
+        public abstract void write(java.io.ObjectOutput out) throws java.io.IOException;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class PutFieldImpl extends java.io.ObjectOutputStream.PutField {
+
+        PutFieldImpl(java.io.ObjectStreamClass desc) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, boolean val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, byte val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, char val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, short val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, int val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, float val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, long val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, double val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void put(java.lang.String name, java.lang.Object val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void write(java.io.ObjectOutput out) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void writeFields() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFieldOffset(java.lang.String name, java.lang.Class<?> type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.ObjectStreamClass desc;
+
+        {
+            desc = null;
+        }
+
+        private final java.lang.Object[] objVals;
+
+        {
+            objVals = new java.lang.Object[0];
+        }
+
+        private final byte[] primVals;
+
+        {
+            primVals = new byte[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ReplaceTable {
+
+        ReplaceTable(int initialCapacity, float loadFactor) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void assign(java.lang.Object obj, java.lang.Object rep) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object lookup(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void grow() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.ObjectOutputStream.HandleTable htab;
+
+        {
+            htab = null;
+        }
+
+        private java.lang.Object[] reps;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/ObjectStreamClass.java b/ojluni/annotations/hiddenapi/java/io/ObjectStreamClass.java
new file mode 100644
index 0000000..d617d32
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/ObjectStreamClass.java
@@ -0,0 +1,733 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ObjectStreamClass implements java.io.Serializable {
+
+    private ObjectStreamClass(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ObjectStreamClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.ObjectStreamClass lookup(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.ObjectStreamClass lookupAny(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getSerialVersionUID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> forClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.ObjectStreamField[] getFields() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.ObjectStreamField getField(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.io.ObjectStreamClass lookup(java.lang.Class<?> cl, boolean all) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void initProxy(
+            java.lang.Class<?> cl,
+            java.lang.ClassNotFoundException resolveEx,
+            java.io.ObjectStreamClass superDesc)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void initNonProxy(
+            java.io.ObjectStreamClass model,
+            java.lang.Class<?> cl,
+            java.lang.ClassNotFoundException resolveEx,
+            java.io.ObjectStreamClass superDesc)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void readNonProxy(java.io.ObjectInputStream in)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void writeNonProxy(java.io.ObjectOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.ClassNotFoundException getResolveException() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final void requireInitialized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkDeserialize() throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkSerialize() throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkDefaultSerialize() throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.io.ObjectStreamClass getSuperDesc() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.io.ObjectStreamClass getLocalDesc() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.io.ObjectStreamField[] getFields(boolean copy) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.io.ObjectStreamField getField(java.lang.String name, java.lang.Class<?> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isProxy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isEnum() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isExternalizable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isSerializable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasBlockExternalData() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    boolean hasWriteObjectData() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isInstantiable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasWriteObjectMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    boolean hasReadObjectMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    boolean hasReadObjectNoDataMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasWriteReplaceMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasReadResolveMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.lang.Object newInstance()
+            throws java.lang.InstantiationException, java.lang.reflect.InvocationTargetException,
+                    java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void invokeWriteObject(java.lang.Object obj, java.io.ObjectOutputStream out)
+            throws java.io.IOException, java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void invokeReadObject(java.lang.Object obj, java.io.ObjectInputStream in)
+            throws java.lang.ClassNotFoundException, java.io.IOException,
+                    java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void invokeReadObjectNoData(java.lang.Object obj)
+            throws java.io.IOException, java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.Object invokeWriteReplace(java.lang.Object obj)
+            throws java.io.IOException, java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.Object invokeReadResolve(java.lang.Object obj)
+            throws java.io.IOException, java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.io.ObjectStreamClass.ClassDataSlot[] getClassDataLayout()
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.ObjectStreamClass.ClassDataSlot[] getClassDataLayout0()
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    int getPrimDataSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    int getNumObjFields() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void getPrimFieldValues(java.lang.Object obj, byte[] buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setPrimFieldValues(java.lang.Object obj, byte[] buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void getObjFieldValues(java.lang.Object obj, java.lang.Object[] vals) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setObjFieldValues(java.lang.Object obj, java.lang.Object[] vals) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private void computeFieldOffsets() throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.ObjectStreamClass getVariantFor(java.lang.Class<?> cl)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.reflect.Constructor<?> getExternalizableConstructor(
+            java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.reflect.Constructor<?> getSerializableConstructor(
+            java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.reflect.Method getInheritableMethod(
+            java.lang.Class<?> cl,
+            java.lang.String name,
+            java.lang.Class<?>[] argTypes,
+            java.lang.Class<?> returnType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.reflect.Method getPrivateMethod(
+            java.lang.Class<?> cl,
+            java.lang.String name,
+            java.lang.Class<?>[] argTypes,
+            java.lang.Class<?> returnType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean packageEquals(java.lang.Class<?> cl1, java.lang.Class<?> cl2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getPackageName(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean classNamesEqual(java.lang.String name1, java.lang.String name2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getClassSignature(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getMethodSignature(
+            java.lang.Class<?>[] paramTypes, java.lang.Class<?> retType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void throwMiscException(java.lang.Throwable th) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.io.ObjectStreamField[] getSerialFields(java.lang.Class<?> cl)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.io.ObjectStreamField[] getDeclaredSerialFields(java.lang.Class<?> cl)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.io.ObjectStreamField[] getDefaultSerialFields(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Long getDeclaredSUID(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static long computeDefaultSUID(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native boolean hasStaticInitializer(
+            java.lang.Class<?> cl, boolean checkSuperclass);
+
+    private static java.io.ObjectStreamClass.FieldReflector getReflector(
+            java.io.ObjectStreamField[] fields, java.io.ObjectStreamClass localDesc)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.io.ObjectStreamField[] matchFields(
+            java.io.ObjectStreamField[] fields, java.io.ObjectStreamClass localDesc)
+            throws java.io.InvalidClassException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static long getConstructorId(java.lang.Class<?> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.lang.Object newInstance(java.lang.Class<?> clazz, long constructorId) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void processQueue(
+            java.lang.ref.ReferenceQueue<java.lang.Class<?>> queue,
+            java.util.concurrent.ConcurrentMap<
+                            ? extends java.lang.ref.WeakReference<java.lang.Class<?>>, ?>
+                    map) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND = 23; // 0x17
+
+    public static final java.io.ObjectStreamField[] NO_FIELDS;
+
+    static {
+        NO_FIELDS = new java.io.ObjectStreamField[0];
+    }
+
+    private java.lang.Class<?> cl;
+
+    private java.lang.reflect.Constructor<?> cons;
+
+    private volatile java.io.ObjectStreamClass.ClassDataSlot[] dataLayout;
+
+    private java.io.ObjectStreamClass.ExceptionInfo defaultSerializeEx;
+
+    private java.io.ObjectStreamClass.ExceptionInfo deserializeEx;
+
+    private boolean externalizable;
+
+    private java.io.ObjectStreamClass.FieldReflector fieldRefl;
+
+    @UnsupportedAppUsage
+    private java.io.ObjectStreamField[] fields;
+
+    private boolean hasBlockExternalData = true;
+
+    private boolean hasWriteObjectData;
+
+    private boolean initialized;
+
+    private boolean isEnum;
+
+    private boolean isProxy;
+
+    private java.io.ObjectStreamClass localDesc;
+
+    private java.lang.String name;
+
+    private int numObjFields;
+
+    private int primDataSize;
+
+    private java.lang.reflect.Method readObjectMethod;
+
+    private java.lang.reflect.Method readObjectNoDataMethod;
+
+    private java.lang.reflect.Method readResolveMethod;
+
+    private java.lang.ClassNotFoundException resolveEx;
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private static final long serialVersionUID = -6120832682080437368L; // 0xab0e6f1aeefe7b88L
+
+    private boolean serializable;
+
+    private java.io.ObjectStreamClass.ExceptionInfo serializeEx;
+
+    private volatile java.lang.Long suid;
+
+    private java.io.ObjectStreamClass superDesc;
+
+    private java.lang.reflect.Method writeObjectMethod;
+
+    private java.lang.reflect.Method writeReplaceMethod;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Caches {
+
+        private Caches() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.concurrent.ConcurrentMap<
+                        java.io.ObjectStreamClass.WeakClassKey, java.lang.ref.Reference<?>>
+                localDescs;
+
+        static {
+            localDescs = null;
+        }
+
+        private static final java.lang.ref.ReferenceQueue<java.lang.Class<?>> localDescsQueue;
+
+        static {
+            localDescsQueue = null;
+        }
+
+        static final java.util.concurrent.ConcurrentMap<
+                        java.io.ObjectStreamClass.FieldReflectorKey, java.lang.ref.Reference<?>>
+                reflectors;
+
+        static {
+            reflectors = null;
+        }
+
+        private static final java.lang.ref.ReferenceQueue<java.lang.Class<?>> reflectorsQueue;
+
+        static {
+            reflectorsQueue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class ClassDataSlot {
+
+        ClassDataSlot(java.io.ObjectStreamClass desc, boolean hasData) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.io.ObjectStreamClass desc;
+
+        {
+            desc = null;
+        }
+
+        final boolean hasData;
+
+        {
+            hasData = false;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EntryFuture {
+
+        private EntryFuture() {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized boolean set(java.lang.Object entry) {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized java.lang.Object get() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Thread getOwner() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object entry;
+
+        private final java.lang.Thread owner;
+
+        {
+            owner = null;
+        }
+
+        private static final java.lang.Object unset;
+
+        static {
+            unset = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ExceptionInfo {
+
+        ExceptionInfo(java.lang.String cn, java.lang.String msg) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.io.InvalidClassException newInvalidClassException() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.String className;
+
+        {
+            className = null;
+        }
+
+        private final java.lang.String message;
+
+        {
+            message = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class FieldReflector {
+
+        FieldReflector(java.io.ObjectStreamField[] fields) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.io.ObjectStreamField[] getFields() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void getPrimFieldValues(java.lang.Object obj, byte[] buf) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setPrimFieldValues(java.lang.Object obj, byte[] buf) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void getObjFieldValues(java.lang.Object obj, java.lang.Object[] vals) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setObjFieldValues(java.lang.Object obj, java.lang.Object[] vals) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.ObjectStreamField[] fields;
+
+        {
+            fields = new java.io.ObjectStreamField[0];
+        }
+
+        private final int numPrimFields;
+
+        {
+            numPrimFields = 0;
+        }
+
+        private final int[] offsets;
+
+        {
+            offsets = new int[0];
+        }
+
+        private final long[] readKeys;
+
+        {
+            readKeys = new long[0];
+        }
+
+        private final char[] typeCodes;
+
+        {
+            typeCodes = new char[0];
+        }
+
+        private final java.lang.Class<?>[] types;
+
+        {
+            types = new java.lang.Class[0];
+        }
+
+        private static final sun.misc.Unsafe unsafe;
+
+        static {
+            unsafe = null;
+        }
+
+        private final long[] writeKeys;
+
+        {
+            writeKeys = new long[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class FieldReflectorKey extends java.lang.ref.WeakReference<java.lang.Class<?>> {
+
+        FieldReflectorKey(
+                java.lang.Class<?> cl,
+                java.io.ObjectStreamField[] fields,
+                java.lang.ref.ReferenceQueue<java.lang.Class<?>> queue) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+
+        private final boolean nullClass;
+
+        {
+            nullClass = false;
+        }
+
+        private final java.lang.String sigs;
+
+        {
+            sigs = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class MemberSignature {
+
+        public MemberSignature(java.lang.reflect.Field field) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public MemberSignature(java.lang.reflect.Constructor<?> cons) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public MemberSignature(java.lang.reflect.Method meth) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final java.lang.reflect.Member member;
+
+        {
+            member = null;
+        }
+
+        public final java.lang.String name;
+
+        {
+            name = null;
+        }
+
+        public final java.lang.String signature;
+
+        {
+            signature = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class WeakClassKey extends java.lang.ref.WeakReference<java.lang.Class<?>> {
+
+        WeakClassKey(
+                java.lang.Class<?> cl, java.lang.ref.ReferenceQueue<java.lang.Class<?>> refQueue) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/ObjectStreamField.java b/ojluni/annotations/hiddenapi/java/io/ObjectStreamField.java
new file mode 100644
index 0000000..b3b7c34
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/ObjectStreamField.java
@@ -0,0 +1,133 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ObjectStreamField implements java.lang.Comparable<java.lang.Object> {
+
+    public ObjectStreamField(java.lang.String name, java.lang.Class<?> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ObjectStreamField(java.lang.String name, java.lang.Class<?> type, boolean unshared) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ObjectStreamField(java.lang.String name, java.lang.String signature, boolean unshared) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ObjectStreamField(java.lang.reflect.Field field, boolean unshared, boolean showType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getTypeCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getTypeString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setOffset(int offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isPrimitive() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isUnshared() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.lang.reflect.Field getField() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.String getSignature() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getClassSignature(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.lang.reflect.Field field;
+
+    {
+        field = null;
+    }
+
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    private int offset = 0; // 0x0
+
+    private final java.lang.String signature;
+
+    {
+        signature = null;
+    }
+
+    private final java.lang.Class<?> type;
+
+    {
+        type = null;
+    }
+
+    private final boolean unshared;
+
+    {
+        unshared = false;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java b/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java
new file mode 100644
index 0000000..32d36ab
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java
@@ -0,0 +1,260 @@
+/*
+ * 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.io;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class RandomAccessFile implements java.io.DataOutput, java.io.DataInput, java.io.Closeable {
+
+    public RandomAccessFile(java.lang.String name, java.lang.String mode)
+            throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public RandomAccessFile(java.io.File file, java.lang.String mode)
+            throws java.io.FileNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void maybeSync() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.io.FileDescriptor getFD() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.channels.FileChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int readBytes(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void readFully(byte[] b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void readFully(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int skipBytes(int n) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(int b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeBytes(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] b) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void write(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getFilePointer() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void seek(long pos) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long length() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLength(long newLength) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean readBoolean() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte readByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int readUnsignedByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final short readShort() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int readUnsignedShort() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final char readChar() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int readInt() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final long readLong() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final float readFloat() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final double readDouble() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String readLine() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String readUTF() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeBoolean(boolean v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeByte(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeShort(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeChar(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeInt(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeLong(long v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeFloat(float v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeDouble(double v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeBytes(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeChars(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void writeUTF(java.lang.String str) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() throws java.lang.Throwable {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int FLUSH_FDATASYNC = 2; // 0x2
+
+    private static final int FLUSH_FSYNC = 1; // 0x1
+
+    private static final int FLUSH_NONE = 0; // 0x0
+
+    private java.nio.channels.FileChannel channel;
+
+    private java.lang.Object closeLock;
+
+    private volatile boolean closed = false;
+
+    @UnsupportedAppUsage
+    private java.io.FileDescriptor fd;
+
+    private int flushAfterWrite = 0; // 0x0
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    private final libcore.io.IoTracker ioTracker;
+
+    {
+        ioTracker = null;
+    }
+
+    private int mode;
+
+    private final java.lang.String path;
+
+    {
+        path = null;
+    }
+
+    private boolean rw;
+
+    private final byte[] scratch;
+
+    {
+        scratch = new byte[0];
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/AbstractStringBuilder.java b/ojluni/annotations/hiddenapi/java/lang/AbstractStringBuilder.java
new file mode 100644
index 0000000..42a5b55
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/AbstractStringBuilder.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+abstract class AbstractStringBuilder implements java.lang.Appendable, java.lang.CharSequence {
+
+    AbstractStringBuilder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    AbstractStringBuilder(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int length() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int capacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void ensureCapacity(int minimumCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureCapacityInternal(int minimumCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int newCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int hugeCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void trimToSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLength(int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char charAt(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    public void setCharAt(int index, char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(java.lang.StringBuffer sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.AbstractStringBuilder append(java.lang.AbstractStringBuilder asb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(java.lang.CharSequence s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.AbstractStringBuilder appendNull() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(java.lang.CharSequence s, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(char[] str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(char[] str, int offset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(long l) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder append(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder delete(int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder appendCodePoint(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder deleteCharAt(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder replace(int start, int end, java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String substring(int start) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.CharSequence subSequence(int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String substring(int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int index, char[] str, int offset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, char[] str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int dstOffset, java.lang.CharSequence s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(
+            int dstOffset, java.lang.CharSequence s, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, long l) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder insert(int offset, double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.String str, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.String str, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.AbstractStringBuilder reverse() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void reverseAllValidSurrogatePairs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.String toString();
+
+    final char[] getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int MAX_ARRAY_SIZE = 2147483639; // 0x7ffffff7
+
+    int count;
+
+    @UnsupportedAppUsage
+    char[] value;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Boolean.java b/ojluni/annotations/hiddenapi/java/lang/Boolean.java
new file mode 100644
index 0000000..14f0255
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Boolean.java
@@ -0,0 +1,132 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean parseBoolean(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean booleanValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Boolean valueOf(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Boolean valueOf(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    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(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean getBoolean(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(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;
+    }
+
+    private static final long serialVersionUID = -3665804199014368530L; // 0xcd207280d59cfaeeL
+
+    /**
+     * @deprecated Use {@link #booleanValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final boolean value;
+
+    {
+        value = false;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Byte.java b/ojluni/annotations/hiddenapi/java/lang/Byte.java
new file mode 100644
index 0000000..6938eb7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Byte.java
@@ -0,0 +1,186 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(byte b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Byte valueOf(byte b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte parseByte(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte parseByte(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Byte valueOf(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Byte valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Byte decode(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!");
+    }
+
+    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(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(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!");
+    }
+
+    @UnsupportedAppUsage
+    public static java.lang.String toHexString(byte b, boolean upperCase) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int BYTES = 1; // 0x1
+
+    private static final char[] DIGITS;
+
+    static {
+        DIGITS = new char[0];
+    }
+
+    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;
+    }
+
+    private static final char[] UPPER_CASE_DIGITS;
+
+    static {
+        UPPER_CASE_DIGITS = new char[0];
+    }
+
+    private static final long serialVersionUID = -7183698231559129828L; // 0x9c4e6084ee50f51cL
+
+    /**
+     * @deprecated Use {@link #byteValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final byte value;
+
+    {
+        value = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ByteCache {
+
+        private ByteCache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.lang.Byte[] cache;
+
+        static {
+            cache = new java.lang.Byte[0];
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Character.java b/ojluni/annotations/hiddenapi/java/lang/Character.java
new file mode 100644
index 0000000..6ac842d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Character.java
@@ -0,0 +1,2150 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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!");
+    }
+
+    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(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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(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!");
+    }
+
+    static int codePointAtImpl(char[] a, int index, int limit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int codePointBefore(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!");
+    }
+
+    static int codePointBeforeImpl(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!");
+    }
+
+    static void toSurrogates(int codePoint, char[] dst, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int codePointCount(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!");
+    }
+
+    static int codePointCountImpl(char[] a, int offset, int count) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int offsetByCodePoints(
+            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!");
+    }
+
+    static int offsetByCodePointsImpl(
+            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!");
+    }
+
+    static native boolean isLowerCaseImpl(int codePoint);
+
+    public static boolean isUpperCase(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isUpperCase(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isUpperCaseImpl(int codePoint);
+
+    public static boolean isTitleCase(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isTitleCase(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isTitleCaseImpl(int codePoint);
+
+    public static boolean isDigit(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isDigit(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isDigitImpl(int codePoint);
+
+    public static boolean isDefined(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isDefined(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isDefinedImpl(int codePoint);
+
+    public static boolean isLetter(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isLetter(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isLetterImpl(int codePoint);
+
+    public static boolean isLetterOrDigit(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isLetterOrDigit(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isLetterOrDigitImpl(int codePoint);
+
+    @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!");
+    }
+
+    static native boolean isAlphabeticImpl(int codePoint);
+
+    public static boolean isIdeographic(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isIdeographicImpl(int codePoint);
+
+    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!");
+    }
+
+    static native boolean isUnicodeIdentifierStartImpl(int codePoint);
+
+    public static boolean isUnicodeIdentifierPart(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isUnicodeIdentifierPart(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isUnicodeIdentifierPartImpl(int codePoint);
+
+    public static boolean isIdentifierIgnorable(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isIdentifierIgnorable(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isIdentifierIgnorableImpl(int codePoint);
+
+    public static char toLowerCase(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int toLowerCase(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native int toLowerCaseImpl(int codePoint);
+
+    public static char toUpperCase(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int toUpperCase(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native int toUpperCaseImpl(int codePoint);
+
+    public static char toTitleCase(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int toTitleCase(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native int toTitleCaseImpl(int codePoint);
+
+    public static int digit(char ch, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int digit(int codePoint, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native int digitImpl(int codePoint, int radix);
+
+    public static int getNumericValue(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int getNumericValue(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native int getNumericValueImpl(int codePoint);
+
+    @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!");
+    }
+
+    static native boolean isSpaceCharImpl(int codePoint);
+
+    public static boolean isWhitespace(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isWhitespace(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isWhitespaceImpl(int codePoint);
+
+    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!");
+    }
+
+    static native int getTypeImpl(int codePoint);
+
+    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!");
+    }
+
+    static native byte getDirectionalityImpl(int codePoint);
+
+    public static boolean isMirrored(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isMirrored(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native boolean isMirroredImpl(int codePoint);
+
+    public int compareTo(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!");
+    }
+
+    public static java.lang.String getName(int codePoint) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native java.lang.String getNameImpl(int codePoint);
+
+    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
+
+    private static final byte[] DIRECTIONALITY;
+
+    static {
+        DIRECTIONALITY = new byte[0];
+    }
+
+    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
+
+    static final int ERROR = -1; // 0xffffffff
+
+    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
+
+    private static final long serialVersionUID = 3786198910865385080L; // 0x348b47d96b1a2678L
+
+    /**
+     * @deprecated Use {@link #charValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final char value;
+
+    {
+        value = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CharacterCache {
+
+        private CharacterCache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.lang.Character[] cache;
+
+        static {
+            cache = new java.lang.Character[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Subset {
+
+        protected Subset(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String name;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class UnicodeBlock extends java.lang.Character.Subset {
+
+        private UnicodeBlock(java.lang.String idName) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        private UnicodeBlock(java.lang.String idName, boolean isMap) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        private UnicodeBlock(java.lang.String idName, java.lang.String alias) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        private UnicodeBlock(java.lang.String idName, java.lang.String... aliases) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.Character.UnicodeBlock of(char c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.Character.UnicodeBlock of(int codePoint) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.Character.UnicodeBlock forName(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;
+        }
+
+        private static final int[] blockStarts;
+
+        static {
+            blockStarts = new int[0];
+        }
+
+        private static final java.lang.Character.UnicodeBlock[] blocks;
+
+        static {
+            blocks = new java.lang.Character.UnicodeBlock[0];
+        }
+
+        private static java.util.Map<java.lang.String, java.lang.Character.UnicodeBlock> map;
+    }
+
+    @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;
+
+        private UnicodeScript() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.Character.UnicodeScript of(int codePoint) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.Character.UnicodeScript forName(java.lang.String scriptName) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.util.HashMap<java.lang.String, java.lang.Character.UnicodeScript>
+                aliases = null;
+
+        private static final int[] scriptStarts = null;
+
+        private static final java.lang.Character.UnicodeScript[] scripts = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Class.java b/ojluni/annotations/hiddenapi/java/lang/Class.java
new file mode 100644
index 0000000..12a69d7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Class.java
@@ -0,0 +1,491 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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 {
+
+    @UnsupportedAppUsage
+    private Class() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toGenericString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> forName(java.lang.String className)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> forName(
+            java.lang.String name, boolean initialize, java.lang.ClassLoader loader)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native java.lang.Class<?> classForName(
+            java.lang.String className, boolean shouldInitialize, java.lang.ClassLoader classLoader)
+            throws java.lang.ClassNotFoundException;
+
+    public native T newInstance()
+            throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+    public boolean isInstance(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAssignableFrom(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 isFinalizable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAnnotation() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSynthetic() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String getNameNative();
+
+    public java.lang.ClassLoader getClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<? super T> getSuperclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Type getGenericSuperclass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Package getPackage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPackageName$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?>[] getInterfaces() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.Class<?>[] getInterfacesInternal();
+
+    public java.lang.reflect.Type[] getGenericInterfaces() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> getComponentType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getModifiers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] getSigners() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Method getEnclosingMethodNative();
+
+    public java.lang.reflect.Method getEnclosingMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Constructor<?> getEnclosingConstructor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Constructor<?> getEnclosingConstructorNative();
+
+    private boolean classNameImpliesTopLevel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native java.lang.Class<?> getDeclaringClass();
+
+    public native java.lang.Class<?> getEnclosingClass();
+
+    public java.lang.String getSimpleName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getTypeName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    private boolean isLocalOrAnonymousClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?>[] getClasses() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void getPublicFieldsRecursive(java.util.List<java.lang.reflect.Field> result) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void getPublicMethodsInternal(java.util.List<java.lang.reflect.Method> result) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Field getField(java.lang.String name)
+            throws java.lang.NoSuchFieldException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Field getPublicFieldRecursive(java.lang.String name);
+
+    public java.lang.reflect.Method getMethod(
+            java.lang.String name, java.lang.Class<?>... parameterTypes)
+            throws java.lang.NoSuchMethodException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Constructor<T> getConstructor(java.lang.Class<?>... parameterTypes)
+            throws java.lang.NoSuchMethodException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native java.lang.Class<?>[] getDeclaredClasses();
+
+    public native java.lang.reflect.Field[] getDeclaredFields();
+
+    public native java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+    public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public native java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+    public java.lang.reflect.Constructor<?>[] getDeclaredConstructors()
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Constructor<?>[] getDeclaredConstructorsInternal(
+            boolean publicOnly);
+
+    public native java.lang.reflect.Field getDeclaredField(java.lang.String name)
+            throws java.lang.NoSuchFieldException;
+
+    private native java.lang.reflect.Field[] getPublicDeclaredFields();
+
+    public java.lang.reflect.Method getDeclaredMethod(
+            java.lang.String name, java.lang.Class<?>... parameterTypes)
+            throws java.lang.NoSuchMethodException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.reflect.Method getMethod(
+            java.lang.String name,
+            java.lang.Class<?>[] parameterTypes,
+            boolean recursivePublicMethods)
+            throws java.lang.NoSuchMethodException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.reflect.Method getPublicMethodRecursive(
+            java.lang.String name, java.lang.Class<?>[] parameterTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Method getInstanceMethod(
+            java.lang.String name, java.lang.Class<?>[] parameterTypes)
+            throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.reflect.Method findInterfaceMethod(
+            java.lang.String name, java.lang.Class<?>[] parameterTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Constructor<T> getDeclaredConstructor(
+            java.lang.Class<?>... parameterTypes)
+            throws java.lang.NoSuchMethodException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getResourceAsStream(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL getResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.ProtectionDomain getProtectionDomain() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static native java.lang.Class<?> getPrimitiveClass(java.lang.String name);
+
+    private java.lang.String resolveName(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.reflect.Constructor<T> getConstructor0(
+            java.lang.Class<?>[] parameterTypes, int which) throws java.lang.NoSuchMethodException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Constructor<T> getDeclaredConstructorInternal(
+            java.lang.Class<?>[] args);
+
+    public boolean desiredAssertionStatus() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String getInnerClassName();
+
+    private native int getInnerClassFlags(int defaultValue);
+
+    public boolean isEnum() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public T[] getEnumConstants() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public T[] getEnumConstantsShared() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public T cast(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String cannotCastMsg(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <U> java.lang.Class<? extends U> asSubclass(java.lang.Class<U> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <A extends java.lang.annotation.Annotation> A getAnnotation(
+            java.lang.Class<A> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAnnotationPresent(
+            java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(
+            java.lang.Class<A> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.annotation.Annotation[] getAnnotations() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(
+            java.lang.Class<A> annotationClass);
+
+    public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+
+    private native boolean isDeclaredAnnotationPresent(
+            java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass);
+
+    private java.lang.String getSignatureAttribute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String[] getSignatureAnnotation();
+
+    public boolean isProxy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getAccessFlags() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Method getDeclaredMethodInternal(
+            java.lang.String name, java.lang.Class<?>[] args);
+
+    private static final int ANNOTATION = 8192; // 0x2000
+
+    private static final int ENUM = 16384; // 0x4000
+
+    private static final int FINALIZABLE = -2147483648; // 0x80000000
+
+    private static final int SYNTHETIC = 4096; // 0x1000
+
+    @UnsupportedAppUsage
+    private transient int accessFlags;
+
+    private transient int classFlags;
+
+    @UnsupportedAppUsage
+    private transient java.lang.ClassLoader classLoader;
+
+    private transient int classSize;
+
+    @UnsupportedAppUsage
+    private transient int clinitThreadId;
+
+    private transient java.lang.Class<?> componentType;
+
+    private transient short copiedMethodsOffset;
+
+    @UnsupportedAppUsage
+    private transient java.lang.Object dexCache;
+
+    @UnsupportedAppUsage
+    private transient int dexClassDefIndex;
+
+    private transient volatile int dexTypeIndex;
+
+    private transient dalvik.system.ClassExt extData;
+
+    private transient long iFields;
+
+    @UnsupportedAppUsage
+    private transient java.lang.Object[] ifTable;
+
+    private transient long methods;
+
+    @UnsupportedAppUsage
+    private transient java.lang.String name;
+
+    private transient int numReferenceInstanceFields;
+
+    private transient int numReferenceStaticFields;
+
+    @UnsupportedAppUsage
+    private transient int objectSize;
+
+    private transient int objectSizeAllocFastPath;
+
+    private transient int primitiveType;
+
+    private transient int referenceInstanceOffsets;
+
+    private transient long sFields;
+
+    private static final long serialVersionUID = 3206093459760846163L; // 0x2c7e5503d9bf9553L
+
+    @UnsupportedAppUsage
+    private transient int status;
+
+    private transient java.lang.Class<? super T> superClass;
+
+    private transient short virtualMethodsOffset;
+
+    private transient java.lang.Object vtable;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Caches {
+
+        private Caches() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final libcore.util.BasicLruCache<java.lang.Class, java.lang.reflect.Type[]>
+                genericInterfaces;
+
+        static {
+            genericInterfaces = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/ClassLoader.java b/ojluni/annotations/hiddenapi/java/lang/ClassLoader.java
new file mode 100644
index 0000000..6af0cb8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/ClassLoader.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ClassLoader {
+
+    private ClassLoader(java.lang.Void unused, java.lang.ClassLoader parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected ClassLoader(java.lang.ClassLoader parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected ClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.ClassLoader createSystemClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Void checkCreateClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> loadClass(java.lang.String name)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Class<?> loadClass(java.lang.String name, boolean resolve)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Class<?> findClass(java.lang.String name)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    protected final java.lang.Class<?> defineClass(byte[] b, int off, int len)
+            throws java.lang.ClassFormatError {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.Class<?> defineClass(
+            java.lang.String name, byte[] b, int off, int len) throws java.lang.ClassFormatError {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.Class<?> defineClass(
+            java.lang.String name,
+            byte[] b,
+            int off,
+            int len,
+            java.security.ProtectionDomain protectionDomain)
+            throws java.lang.ClassFormatError {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.Class<?> defineClass(
+            java.lang.String name,
+            java.nio.ByteBuffer b,
+            java.security.ProtectionDomain protectionDomain)
+            throws java.lang.ClassFormatError {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final void resolveClass(java.lang.Class<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.Class<?> findSystemClass(java.lang.String name)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Class<?> findBootstrapClassOrNull(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.Class<?> findLoadedClass(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final void setSigners(java.lang.Class<?> c, java.lang.Object[] signers) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL getResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.net.URL> getResources(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.URL findResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.util.Enumeration<java.net.URL> findResources(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected static boolean registerAsParallelCapable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URL getSystemResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Enumeration<java.net.URL> getSystemResources(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URL getBootstrapResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Enumeration<java.net.URL> getBootstrapResources(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getResourceAsStream(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.InputStream getSystemResourceAsStream(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.ClassLoader getParent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.ClassLoader getSystemClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.ClassLoader getClassLoader(java.lang.Class<?> caller) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Package definePackage(
+            java.lang.String name,
+            java.lang.String specTitle,
+            java.lang.String specVersion,
+            java.lang.String specVendor,
+            java.lang.String implTitle,
+            java.lang.String implVersion,
+            java.lang.String implVendor,
+            java.net.URL sealBase)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Package getPackage(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Package[] getPackages() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.String findLibrary(java.lang.String libname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDefaultAssertionStatus(boolean enabled) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPackageAssertionStatus(java.lang.String packageName, boolean enabled) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setClassAssertionStatus(java.lang.String className, boolean enabled) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clearAssertionStatus() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private transient long allocator;
+
+    private transient long classTable;
+
+    private final java.util.HashMap<java.lang.String, java.lang.Package> packages;
+
+    {
+        packages = null;
+    }
+
+    @UnsupportedAppUsage
+    private final java.lang.ClassLoader parent;
+
+    {
+        parent = null;
+    }
+
+    public final java.util.Map<java.util.List<java.lang.Class<?>>, java.lang.Class<?>> proxyCache;
+
+    {
+        proxyCache = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SystemClassLoader {
+
+        private SystemClassLoader() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.lang.ClassLoader loader;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Double.java b/ojluni/annotations/hiddenapi/java/lang/Double.java
new file mode 100644
index 0000000..187b7b4
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Double.java
@@ -0,0 +1,189 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toHexString(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Double valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Double valueOf(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double parseDouble(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!");
+    }
+
+    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(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(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;
+    }
+
+    private static final long serialVersionUID = -9172774392245257468L; // 0x80b3c24a296bfb04L
+
+    /**
+     * @deprecated Use {@link #doubleValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final double value;
+
+    {
+        value = 0;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Enum.java b/ojluni/annotations/hiddenapi/java/lang/Enum.java
new file mode 100644
index 0000000..369e58e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Enum.java
@@ -0,0 +1,120 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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!");
+    }
+
+    private static java.lang.Object[] enumValues(java.lang.Class<? extends java.lang.Enum> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static <T extends java.lang.Enum<T>> T[] getSharedConstants(
+            java.lang.Class<T> enumType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final void finalize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream in)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObjectNoData() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    @UnsupportedAppUsage
+    private final int ordinal;
+
+    {
+        ordinal = 0;
+    }
+
+    private static final libcore.util.BasicLruCache<
+                    java.lang.Class<? extends java.lang.Enum>, java.lang.Object[]>
+            sharedConstantsCache;
+
+    static {
+        sharedConstantsCache = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Float.java b/ojluni/annotations/hiddenapi/java/lang/Float.java
new file mode 100644
index 0000000..1081764
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Float.java
@@ -0,0 +1,192 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toHexString(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Float valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Float valueOf(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float parseFloat(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!");
+    }
+
+    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(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(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;
+    }
+
+    private static final long serialVersionUID = -2671257302660747028L; // 0xdaedc9a2db3cf0ecL
+
+    /**
+     * @deprecated Use {@link #floatValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final float value;
+
+    {
+        value = 0;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Integer.java b/ojluni/annotations/hiddenapi/java/lang/Integer.java
new file mode 100644
index 0000000..adb8c9c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Integer.java
@@ -0,0 +1,336 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(int i, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toUnsignedString(int i, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toHexString(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toOctalString(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toBinaryString(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String toUnsignedString0(int val, int shift) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toUnsignedString(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void getChars(int i, int index, char[] buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int stringSize(int x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int parseInt(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int parseInt(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int parseUnsignedInt(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int parseUnsignedInt(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer valueOf(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    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(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer getInteger(java.lang.String nm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer getInteger(java.lang.String nm, int val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer getInteger(java.lang.String nm, java.lang.Integer val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Integer decode(java.lang.String nm)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(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
+
+    static final char[] DigitOnes;
+
+    static {
+        DigitOnes = new char[0];
+    }
+
+    static final char[] DigitTens;
+
+    static {
+        DigitTens = new char[0];
+    }
+
+    public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+
+    public static final int MIN_VALUE = -2147483648; // 0x80000000
+
+    public static final int SIZE = 32; // 0x20
+
+    private static final java.lang.String[] SMALL_NEG_VALUES;
+
+    static {
+        SMALL_NEG_VALUES = new java.lang.String[0];
+    }
+
+    private static final java.lang.String[] SMALL_NONNEG_VALUES;
+
+    static {
+        SMALL_NONNEG_VALUES = new java.lang.String[0];
+    }
+
+    public static final java.lang.Class<java.lang.Integer> TYPE;
+
+    static {
+        TYPE = null;
+    }
+
+    static final char[] digits;
+
+    static {
+        digits = new char[0];
+    }
+
+    private static final long serialVersionUID = 1360826667806852920L; // 0x12e2a0a4f7818738L
+
+    static final int[] sizeTable;
+
+    static {
+        sizeTable = new int[0];
+    }
+
+    /**
+     * @deprecated Use {@link #intValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final int value;
+
+    {
+        value = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class IntegerCache {
+
+        private IntegerCache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.lang.Integer[] cache;
+
+        static {
+            cache = new java.lang.Integer[0];
+        }
+
+        static final int high;
+
+        static {
+            high = 0;
+        }
+
+        static final int low = -128; // 0xffffff80
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Long.java b/ojluni/annotations/hiddenapi/java/lang/Long.java
new file mode 100644
index 0000000..2f32b27
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Long.java
@@ -0,0 +1,292 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@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(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(long i, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toUnsignedString(long i, int radix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.math.BigInteger toUnsignedBigInteger(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toHexString(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toOctalString(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toBinaryString(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String toUnsignedString0(long val, int shift) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toUnsignedString(long i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void getChars(long i, int index, char[] buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int stringSize(long x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long parseLong(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long parseLong(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long parseUnsignedLong(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long parseUnsignedLong(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long valueOf(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long valueOf(long l) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long decode(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!");
+    }
+
+    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(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long getLong(java.lang.String nm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long getLong(java.lang.String nm, long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Long getLong(java.lang.String nm, java.lang.Long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(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;
+    }
+
+    private static final long serialVersionUID = 4290774380558885855L; // 0x3b8be490cc8f23dfL
+
+    /**
+     * @deprecated Use {@link #longValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final long value;
+
+    {
+        value = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class LongCache {
+
+        private LongCache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.lang.Long[] cache;
+
+        static {
+            cache = new java.lang.Long[0];
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Object.java b/ojluni/annotations/hiddenapi/java/lang/Object.java
new file mode 100644
index 0000000..5289874
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Object.java
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Object {
+
+    public Object() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.Class<?> getClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static int identityHashCode(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native int identityHashCodeNative(java.lang.Object obj);
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object clone() throws java.lang.CloneNotSupportedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.Object internalClone();
+
+    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!");
+    }
+
+    private transient java.lang.Class<?> shadow$_klass_;
+
+    private transient int shadow$_monitor_;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Runtime.java b/ojluni/annotations/hiddenapi/java/lang/Runtime.java
new file mode 100644
index 0000000..ca8c56c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Runtime.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Runtime {
+
+    @UnsupportedAppUsage
+    private Runtime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void nativeExit(int code);
+
+    public static java.lang.Runtime getRuntime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void exit(int status) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addShutdownHook(java.lang.Thread hook) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeShutdownHook(java.lang.Thread hook) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void halt(int status) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static void runFinalizersOnExit(boolean value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(java.lang.String command) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(java.lang.String command, java.lang.String[] envp)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(
+            java.lang.String command, java.lang.String[] envp, java.io.File dir)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(java.lang.String[] cmdarray) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(java.lang.String[] cmdarray, java.lang.String[] envp)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Process exec(
+            java.lang.String[] cmdarray, java.lang.String[] envp, java.io.File dir)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int availableProcessors() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native long freeMemory();
+
+    public native long totalMemory();
+
+    public native long maxMemory();
+
+    public void gc() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native void nativeGc();
+
+    private static native void runFinalization0();
+
+    public void runFinalization() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void traceInstructions(boolean on) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void traceMethodCalls(boolean on) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void load(java.lang.String filename) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkTargetSdkVersionForLoad(java.lang.String methodName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    void load(java.lang.String absolutePath, java.lang.ClassLoader loader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    synchronized void load0(java.lang.Class<?> fromClass, java.lang.String filename) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void loadLibrary(java.lang.String libname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void loadLibrary0(java.lang.Class<?> fromClass, java.lang.String libname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void loadLibrary(java.lang.String libname, java.lang.ClassLoader classLoader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    void loadLibrary0(java.lang.ClassLoader loader, java.lang.String libname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String[] getLibPaths() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String[] initLibPaths() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.lang.String nativeLoad(
+            java.lang.String filename, java.lang.ClassLoader loader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public java.io.InputStream getLocalizedInputStream(java.io.InputStream in) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public java.io.OutputStream getLocalizedOutputStream(java.io.OutputStream out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Runtime currentRuntime;
+
+    private static boolean finalizeOnExit;
+
+    @UnsupportedAppUsage
+    private volatile java.lang.String[] mLibPaths;
+
+    private java.util.List<java.lang.Thread> shutdownHooks;
+
+    private boolean shuttingDown;
+
+    private boolean tracingMethods;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Short.java b/ojluni/annotations/hiddenapi/java/lang/Short.java
new file mode 100644
index 0000000..f1f0641
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Short.java
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Short extends java.lang.Number implements java.lang.Comparable<java.lang.Short> {
+
+    public Short(short value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Short(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(short s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short parseShort(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short parseShort(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Short valueOf(java.lang.String s, int radix)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Short valueOf(java.lang.String s)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Short valueOf(short s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Short decode(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!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(short value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.lang.Short anotherShort) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int compare(short x, short y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short reverseBytes(short i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int toUnsignedInt(short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long toUnsignedLong(short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int BYTES = 2; // 0x2
+
+    public static final short MAX_VALUE = 32767; // 0x7fff
+
+    public static final short MIN_VALUE = -32768; // 0xffff8000
+
+    public static final int SIZE = 16; // 0x10
+
+    public static final java.lang.Class<java.lang.Short> TYPE;
+
+    static {
+        TYPE = null;
+    }
+
+    private static final long serialVersionUID = 7515723908773894738L; // 0x684d37133460da52L
+
+    /**
+     * @deprecated Use {@link #shortValue()}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P)
+    private final short value;
+
+    {
+        value = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ShortCache {
+
+        private ShortCache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.lang.Short[] cache;
+
+        static {
+            cache = new java.lang.Short[0];
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/StackTraceElement.java b/ojluni/annotations/hiddenapi/java/lang/StackTraceElement.java
new file mode 100644
index 0000000..a396013
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/StackTraceElement.java
@@ -0,0 +1,86 @@
+/*
+ * 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
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StackTraceElement implements java.io.Serializable {
+
+    public StackTraceElement(
+            java.lang.String declaringClass,
+            java.lang.String methodName,
+            java.lang.String fileName,
+            int lineNumber) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getFileName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getLineNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getClassName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getMethodName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isNativeMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.String declaringClass;
+
+    @UnsupportedAppUsage
+    private java.lang.String fileName;
+
+    @UnsupportedAppUsage
+    private int lineNumber;
+
+    @UnsupportedAppUsage
+    private java.lang.String methodName;
+
+    private static final long serialVersionUID = 6992337162326171013L; // 0x6109c59a2636dd85L
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/String.java b/ojluni/annotations/hiddenapi/java/lang/String.java
new file mode 100644
index 0000000..51fdfb7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/String.java
@@ -0,0 +1,489 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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(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, java.lang.String charsetName)
+            throws java.io.UnsupportedEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public String(byte[] bytes, int offset, int length, java.nio.charset.Charset charset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public String(byte[] bytes, java.lang.String charsetName)
+            throws java.io.UnsupportedEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public String(byte[] bytes, 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(java.lang.StringBuffer buffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public String(java.lang.StringBuilder builder) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage
+    String(int offset, int count, char[] value) {
+        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!");
+    }
+
+    void getChars(char[] dst, int dstBegin) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    native void getCharsNoCheck(int start, int end, char[] buffer, int index);
+
+    @Deprecated
+    public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getBytes(java.lang.String charsetName)
+            throws java.io.UnsupportedEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getBytes(java.nio.charset.Charset charset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getBytes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object anObject) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contentEquals(java.lang.StringBuffer sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean nonSyncContentEquals(java.lang.AbstractStringBuilder sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contentEquals(java.lang.CharSequence cs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equalsIgnoreCase(java.lang.String anotherString) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native int compareTo(java.lang.String anotherString);
+
+    public int compareToIgnoreCase(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean regionMatches(int toffset, java.lang.String other, int ooffset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean regionMatches(
+            boolean ignoreCase, int toffset, java.lang.String other, int ooffset, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean startsWith(java.lang.String prefix, int toffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean startsWith(java.lang.String prefix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean endsWith(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!");
+    }
+
+    private int indexOfSupplementary(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!");
+    }
+
+    private int lastIndexOfSupplementary(int ch, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.String str, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int indexOf(java.lang.String source, java.lang.String target, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int indexOf(
+            char[] source,
+            int sourceOffset,
+            int sourceCount,
+            java.lang.String target,
+            int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static int indexOf(
+            char[] source,
+            int sourceOffset,
+            int sourceCount,
+            char[] target,
+            int targetOffset,
+            int targetCount,
+            int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.String str, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int lastIndexOf(
+            java.lang.String source, java.lang.String target, int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int lastIndexOf(
+            char[] source,
+            int sourceOffset,
+            int sourceCount,
+            java.lang.String target,
+            int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static int lastIndexOf(
+            char[] source,
+            int sourceOffset,
+            int sourceCount,
+            char[] target,
+            int targetOffset,
+            int targetCount,
+            int fromIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String substring(int beginIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String substring(int beginIndex, int endIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String fastSubstring(int start, int length);
+
+    public java.lang.CharSequence subSequence(int beginIndex, int endIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native java.lang.String concat(java.lang.String str);
+
+    public java.lang.String replace(char oldChar, char newChar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String doReplace(char oldChar, char newChar);
+
+    public boolean matches(java.lang.String regex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.CharSequence s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String replaceFirst(java.lang.String regex, java.lang.String replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String replaceAll(java.lang.String regex, java.lang.String replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String replace(
+            java.lang.CharSequence target, java.lang.CharSequence replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String[] split(java.lang.String regex, int limit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String[] split(java.lang.String regex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String join(
+            java.lang.CharSequence delimiter, java.lang.CharSequence... elements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String join(
+            java.lang.CharSequence delimiter,
+            java.lang.Iterable<? extends java.lang.CharSequence> elements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toLowerCase(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toLowerCase() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toUpperCase(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toUpperCase() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String trim() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native char[] toCharArray();
+
+    public static java.lang.String format(java.lang.String format, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String format(
+            java.util.Locale l, java.lang.String format, java.lang.Object... args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(char[] data) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(char[] data, int offset, int count) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String copyValueOf(char[] data, int offset, int count) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String copyValueOf(char[] data) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(long l) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String valueOf(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native java.lang.String intern();
+
+    public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+
+    static {
+        CASE_INSENSITIVE_ORDER = null;
+    }
+
+    @UnsupportedAppUsage
+    private final int count;
+
+    {
+        count = 0;
+    }
+
+    @UnsupportedAppUsage
+    private int hash;
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private static final long serialVersionUID = -6849794470754667710L; // 0xa0f0a4387a3bb342L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CaseInsensitiveComparator
+            implements java.util.Comparator<java.lang.String>, java.io.Serializable {
+
+        private CaseInsensitiveComparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int compare(java.lang.String s1, java.lang.String s2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 8575799808933029326L; // 0x77035c7d5c50e5ceL
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/System.java b/ojluni/annotations/hiddenapi/java/lang/System.java
new file mode 100644
index 0000000..a401efd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/System.java
@@ -0,0 +1,344 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class System {
+
+    @UnsupportedAppUsage
+    private System() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setIn(java.io.InputStream in) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setOut(java.io.PrintStream out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setErr(java.io.PrintStream err) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.io.Console console() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void setIn0(java.io.InputStream in);
+
+    private static native void setOut0(java.io.PrintStream out);
+
+    private static native void setErr0(java.io.PrintStream err);
+
+    public static void setSecurityManager(java.lang.SecurityManager s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    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(
+            java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyCharUnchecked(
+            char[] src, int srcPos, char[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyByteUnchecked(
+            byte[] src, int srcPos, byte[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyShortUnchecked(
+            short[] src, int srcPos, short[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyIntUnchecked(
+            int[] src, int srcPos, int[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyLongUnchecked(
+            long[] src, int srcPos, long[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyFloatUnchecked(
+            float[] src, int srcPos, float[] dst, int dstPos, int length);
+
+    private static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyDoubleUnchecked(
+            double[] src, int srcPos, double[] dst, int dstPos, int length);
+
+    @UnsupportedAppUsage
+    private static void arraycopy(
+            boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void arraycopyBooleanUnchecked(
+            boolean[] src, int srcPos, boolean[] dst, int dstPos, int length);
+
+    public static int identityHashCode(java.lang.Object x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native java.lang.String[] specialProperties();
+
+    private static void parsePropertyAssignments(
+            java.util.Properties p, java.lang.String[] assignments) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Properties initUnchangeableSystemProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Properties initProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Properties setDefaultChangeableProperties(java.util.Properties p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setUnchangeableSystemProperty(java.lang.String key, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void addLegacyLocaleSystemProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Properties getProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String lineSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setProperties(java.util.Properties props) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getProperty(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getProperty(java.lang.String key, java.lang.String def) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String setProperty(java.lang.String key, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String clearProperty(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkKey(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getenv(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(java.lang.String filename) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void loadLibrary(java.lang.String libname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static native java.lang.String mapLibraryName(java.lang.String libname);
+
+    private static java.io.PrintStream newPrintStream(
+            java.io.FileOutputStream fos, java.lang.String enc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static void logE(java.lang.String message) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static void logE(java.lang.String message, java.lang.Throwable th) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void logI(java.lang.String message) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void logI(java.lang.String message, java.lang.Throwable th) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void logW(java.lang.String message) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static void logW(java.lang.String message, java.lang.Throwable th) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native void log(char type, java.lang.String message, java.lang.Throwable th);
+
+    private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32; // 0x20
+
+    private static final java.lang.Object LOCK;
+
+    static {
+        LOCK = null;
+    }
+
+    private static volatile java.io.Console cons;
+
+    public static final java.io.PrintStream err;
+
+    static {
+        err = null;
+    }
+
+    public static final java.io.InputStream in;
+
+    static {
+        in = null;
+    }
+
+    private static boolean justRanFinalization;
+
+    private static java.lang.String lineSeparator;
+
+    public static final java.io.PrintStream out;
+
+    static {
+        out = null;
+    }
+
+    private static java.util.Properties props;
+
+    private static boolean runGC;
+
+    private static java.util.Properties unchangeableProps;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class PropertiesWithNonOverrideableDefaults extends java.util.Properties {
+
+        PropertiesWithNonOverrideableDefaults(java.util.Properties defaults) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object put(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Thread.java b/ojluni/annotations/hiddenapi/java/lang/Thread.java
new file mode 100644
index 0000000..2e8557b
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Thread.java
@@ -0,0 +1,526 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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!");
+    }
+
+    Thread(java.lang.Runnable target, java.security.AccessControlContext acc) {
+        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!");
+    }
+
+    @UnsupportedAppUsage
+    Thread(java.lang.ThreadGroup group, java.lang.String name, int priority, boolean daemon) {
+        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!");
+    }
+
+    private static synchronized int nextThreadNum() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static synchronized long nextThreadID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void blockedOn(sun.nio.ch.Interruptible b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    private static native void sleep(java.lang.Object lock, long millis, int nanos)
+            throws java.lang.InterruptedException;
+
+    public static void sleep(long millis, int nanos) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(
+            java.lang.ThreadGroup g,
+            java.lang.Runnable target,
+            java.lang.String name,
+            long stackSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(
+            java.lang.ThreadGroup g,
+            java.lang.Runnable target,
+            java.lang.String name,
+            long stackSize,
+            java.security.AccessControlContext acc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object clone() throws java.lang.CloneNotSupportedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init2(java.lang.Thread parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void start() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void nativeCreate(java.lang.Thread t, long stackSize, boolean daemon);
+
+    public void run() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void exit() {
+        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!");
+    }
+
+    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!");
+    }
+
+    private static boolean isCCLOverridden(java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean auditSubclass(java.lang.Class<?> subcl) {
+        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 static void setUncaughtExceptionPreHandler(
+            java.lang.Thread.UncaughtExceptionHandler eh) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
+        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!");
+    }
+
+    @UnsupportedAppUsage
+    public final void dispatchUncaughtException(java.lang.Throwable e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void processQueue(
+            java.lang.ref.ReferenceQueue<java.lang.Class<?>> queue,
+            java.util.concurrent.ConcurrentMap<
+                            ? extends java.lang.ref.WeakReference<java.lang.Class<?>>, ?>
+                    map) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native void setPriority0(int newPriority);
+
+    private native void interrupt0();
+
+    private native void setNativeName(java.lang.String name);
+
+    private native int nativeGetStatus(boolean hasBeenStarted);
+
+    public final void unpark$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void parkFor$(long nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void parkUntil$(long time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.StackTraceElement[] EMPTY_STACK_TRACE;
+
+    static {
+        EMPTY_STACK_TRACE = new java.lang.StackTraceElement[0];
+    }
+
+    public static final int MAX_PRIORITY = 10; // 0xa
+
+    public static final int MIN_PRIORITY = 1; // 0x1
+
+    private static final int NANOS_PER_MILLI = 1000000; // 0xf4240
+
+    public static final int NORM_PRIORITY = 5; // 0x5
+
+    private static final java.lang.RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION;
+
+    static {
+        SUBCLASS_IMPLEMENTATION_PERMISSION = null;
+    }
+
+    private volatile sun.nio.ch.Interruptible blocker;
+
+    private final java.lang.Object blockerLock;
+
+    {
+        blockerLock = null;
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.ClassLoader contextClassLoader;
+
+    @UnsupportedAppUsage
+    private boolean daemon = false;
+
+    private static volatile java.lang.Thread.UncaughtExceptionHandler
+            defaultUncaughtExceptionHandler;
+
+    private long eetop;
+
+    @UnsupportedAppUsage
+    private java.lang.ThreadGroup group;
+
+    @UnsupportedAppUsage
+    java.lang.ThreadLocal.ThreadLocalMap inheritableThreadLocals;
+
+    @UnsupportedAppUsage
+    private java.security.AccessControlContext inheritedAccessControlContext;
+
+    @UnsupportedAppUsage
+    private final java.lang.Object lock;
+
+    {
+        lock = null;
+    }
+
+    @UnsupportedAppUsage
+    private volatile java.lang.String name;
+
+    private long nativeParkEventPointer;
+
+    @UnsupportedAppUsage
+    private volatile long nativePeer;
+
+    @UnsupportedAppUsage
+    volatile java.lang.Object parkBlocker;
+
+    private int parkState = 1; // 0x1
+
+    @UnsupportedAppUsage
+    private int priority;
+
+    private boolean single_step;
+
+    private long stackSize;
+
+    boolean started = false;
+
+    private boolean stillborn = false;
+
+    @UnsupportedAppUsage
+    private java.lang.Runnable target;
+
+    private static int threadInitNumber;
+
+    int threadLocalRandomProbe;
+
+    int threadLocalRandomSecondarySeed;
+
+    long threadLocalRandomSeed;
+
+    @UnsupportedAppUsage
+    java.lang.ThreadLocal.ThreadLocalMap threadLocals;
+
+    private java.lang.Thread threadQ;
+
+    @UnsupportedAppUsage
+    private static long threadSeqNumber;
+
+    private long tid;
+
+    private volatile java.lang.Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
+
+    @UnsupportedAppUsage
+    private static volatile java.lang.Thread.UncaughtExceptionHandler uncaughtExceptionPreHandler;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Caches {
+
+        private Caches() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.concurrent.ConcurrentMap<
+                        java.lang.Thread.WeakClassKey, java.lang.Boolean>
+                subclassAudits;
+
+        static {
+            subclassAudits = null;
+        }
+
+        static final java.lang.ref.ReferenceQueue<java.lang.Class<?>> subclassAuditsQueue;
+
+        static {
+            subclassAuditsQueue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ParkState {
+
+        private ParkState() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int PARKED = 3; // 0x3
+
+        private static final int PREEMPTIVELY_UNPARKED = 2; // 0x2
+
+        private static final int UNPARKED = 1; // 0x1
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum State {
+        NEW,
+        RUNNABLE,
+        BLOCKED,
+        WAITING,
+        TIMED_WAITING,
+        TERMINATED;
+
+        private State() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface UncaughtExceptionHandler {
+
+        public void uncaughtException(java.lang.Thread t, java.lang.Throwable e);
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class WeakClassKey extends java.lang.ref.WeakReference<java.lang.Class<?>> {
+
+        WeakClassKey(
+                java.lang.Class<?> cl, java.lang.ref.ReferenceQueue<java.lang.Class<?>> refQueue) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java b/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java
new file mode 100644
index 0000000..ee9feb0
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadGroup implements java.lang.Thread.UncaughtExceptionHandler {
+
+    private ThreadGroup() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ThreadGroup(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ThreadGroup(java.lang.ThreadGroup parent, java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private ThreadGroup(
+            java.lang.Void unused, java.lang.ThreadGroup parent, java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Void checkParentAccess(java.lang.ThreadGroup parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.ThreadGroup getParent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getMaxPriority() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isDaemon() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean isDestroyed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setDaemon(boolean daemon) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setMaxPriority(int pri) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean parentOf(java.lang.ThreadGroup g) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void checkAccess() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int activeCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int enumerate(java.lang.Thread[] list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int enumerate(java.lang.Thread[] list, boolean recurse) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int enumerate(java.lang.Thread[] list, int n, boolean recurse) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int activeGroupCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int enumerate(java.lang.ThreadGroup[] list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int enumerate(java.lang.ThreadGroup[] list, boolean recurse) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int enumerate(java.lang.ThreadGroup[] list, int n, boolean recurse) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public final void stop() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void interrupt() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public final void suspend() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean stopOrSuspend(boolean suspend) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public final void resume() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void destroy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final void add(java.lang.ThreadGroup g) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void remove(java.lang.ThreadGroup g) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void addUnstarted() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    void add(java.lang.Thread t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void threadStartFailed(java.lang.Thread t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    void threadTerminated(java.lang.Thread t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void remove(java.lang.Thread t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void list() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void list(java.io.PrintStream out, int indent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void uncaughtException(java.lang.Thread t, java.lang.Throwable e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public boolean allowThreadSuspension(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean daemon;
+
+    boolean destroyed;
+
+    @UnsupportedAppUsage
+    java.lang.ThreadGroup[] groups;
+
+    @UnsupportedAppUsage
+    static final java.lang.ThreadGroup mainThreadGroup;
+
+    static {
+        mainThreadGroup = null;
+    }
+
+    int maxPriority;
+
+    int nUnstartedThreads = 0; // 0x0
+
+    @UnsupportedAppUsage
+    java.lang.String name;
+
+    @UnsupportedAppUsage
+    int ngroups;
+
+    int nthreads;
+
+    @UnsupportedAppUsage
+    private final java.lang.ThreadGroup parent;
+
+    {
+        parent = null;
+    }
+
+    @UnsupportedAppUsage
+    static final java.lang.ThreadGroup systemThreadGroup;
+
+    static {
+        systemThreadGroup = null;
+    }
+
+    java.lang.Thread[] threads;
+
+    boolean vmAllowSuspension;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java b/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java
new file mode 100644
index 0000000..5772a6d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java
@@ -0,0 +1,196 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocal<T> {
+
+    public ThreadLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int nextHashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected T initialValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <S> java.lang.ThreadLocal<S> withInitial(
+            java.util.function.Supplier<? extends S> supplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public T get() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private T setInitialValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(T value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void remove() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.lang.ThreadLocal.ThreadLocalMap getMap(java.lang.Thread t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void createMap(java.lang.Thread t, T firstValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.ThreadLocal.ThreadLocalMap createInheritedMap(
+            java.lang.ThreadLocal.ThreadLocalMap parentMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    T childValue(T parentValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int HASH_INCREMENT = 1640531527; // 0x61c88647
+
+    private static java.util.concurrent.atomic.AtomicInteger nextHashCode;
+
+    private final int threadLocalHashCode;
+
+    {
+        threadLocalHashCode = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class SuppliedThreadLocal<T> extends java.lang.ThreadLocal<T> {
+
+        SuppliedThreadLocal(java.util.function.Supplier<? extends T> supplier) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected T initialValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.function.Supplier<? extends T> supplier;
+
+        {
+            supplier = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class ThreadLocalMap {
+
+        ThreadLocalMap(java.lang.ThreadLocal<?> firstKey, java.lang.Object firstValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private ThreadLocalMap(java.lang.ThreadLocal.ThreadLocalMap parentMap) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void setThreshold(int len) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static int nextIndex(int i, int len) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static int prevIndex(int i, int len) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.ThreadLocal.ThreadLocalMap.Entry getEntry(java.lang.ThreadLocal<?> key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.ThreadLocal.ThreadLocalMap.Entry getEntryAfterMiss(
+                java.lang.ThreadLocal<?> key, int i, java.lang.ThreadLocal.ThreadLocalMap.Entry e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void set(java.lang.ThreadLocal<?> key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void remove(java.lang.ThreadLocal<?> key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void replaceStaleEntry(
+                java.lang.ThreadLocal<?> key, java.lang.Object value, int staleSlot) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int expungeStaleEntry(int staleSlot) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean cleanSomeSlots(int i, int n) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void rehash() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void resize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void expungeStaleEntries() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int INITIAL_CAPACITY = 16; // 0x10
+
+        private int size = 0; // 0x0
+
+        private java.lang.ThreadLocal.ThreadLocalMap.Entry[] table;
+
+        private int threshold;
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        static class Entry extends java.lang.ref.WeakReference<java.lang.ThreadLocal<?>> {
+
+            Entry(java.lang.ThreadLocal<?> k, java.lang.Object v) {
+                super(null);
+                throw new RuntimeException("Stub!");
+            }
+
+            java.lang.Object value;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Throwable.java b/ojluni/annotations/hiddenapi/java/lang/Throwable.java
new file mode 100644
index 0000000..0bc7d12
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Throwable.java
@@ -0,0 +1,247 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Throwable implements java.io.Serializable {
+
+    public Throwable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Throwable(java.lang.String message) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Throwable(java.lang.String message, java.lang.Throwable cause) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Throwable(java.lang.Throwable cause) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected Throwable(
+            java.lang.String message,
+            java.lang.Throwable cause,
+            boolean enableSuppression,
+            boolean writableStackTrace) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getMessage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getLocalizedMessage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Throwable getCause() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Throwable initCause(java.lang.Throwable cause) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void printStackTrace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void printStackTrace(java.io.PrintStream s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private void printStackTrace(java.lang.Throwable.PrintStreamOrWriter s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void printEnclosedStackTrace(
+            java.lang.Throwable.PrintStreamOrWriter s,
+            java.lang.StackTraceElement[] enclosingTrace,
+            java.lang.String caption,
+            java.lang.String prefix,
+            java.util.Set<java.lang.Throwable> dejaVu) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void printStackTrace(java.io.PrintWriter s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Throwable fillInStackTrace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native java.lang.Object nativeFillInStackTrace();
+
+    public java.lang.StackTraceElement[] getStackTrace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private synchronized java.lang.StackTraceElement[] getOurStackTrace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setStackTrace(java.lang.StackTraceElement[] stackTrace) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native java.lang.StackTraceElement[] nativeGetStackTrace(
+            java.lang.Object stackState);
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final synchronized void addSuppressed(java.lang.Throwable exception) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final synchronized java.lang.Throwable[] getSuppressed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String CAUSE_CAPTION = "Caused by: ";
+
+    private static java.lang.Throwable[] EMPTY_THROWABLE_ARRAY;
+
+    private static final java.lang.String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
+
+    private static final java.lang.String SELF_SUPPRESSION_MESSAGE =
+            "Self-suppression not permitted";
+
+    private static final java.lang.String SUPPRESSED_CAPTION = "Suppressed: ";
+
+    @UnsupportedAppUsage
+    private transient volatile java.lang.Object backtrace;
+
+    @UnsupportedAppUsage
+    private java.lang.Throwable cause;
+
+    @UnsupportedAppUsage
+    private java.lang.String detailMessage;
+
+    private static final long serialVersionUID = -3042686055658047285L; // 0xd5c635273977b8cbL
+
+    @UnsupportedAppUsage
+    private java.lang.StackTraceElement[] stackTrace;
+
+    @UnsupportedAppUsage
+    private java.util.List<java.lang.Throwable> suppressedExceptions;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private abstract static class PrintStreamOrWriter {
+
+        private PrintStreamOrWriter() {
+            throw new RuntimeException("Stub!");
+        }
+
+        abstract java.lang.Object lock();
+
+        abstract void println(java.lang.Object o);
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SentinelHolder {
+
+        private SentinelHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static final java.lang.StackTraceElement STACK_TRACE_ELEMENT_SENTINEL;
+
+        static {
+            STACK_TRACE_ELEMENT_SENTINEL = null;
+        }
+
+        public static final java.lang.StackTraceElement[] STACK_TRACE_SENTINEL;
+
+        static {
+            STACK_TRACE_SENTINEL = new java.lang.StackTraceElement[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class WrappedPrintStream extends java.lang.Throwable.PrintStreamOrWriter {
+
+        WrappedPrintStream(java.io.PrintStream printStream) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object lock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void println(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.PrintStream printStream;
+
+        {
+            printStream = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class WrappedPrintWriter extends java.lang.Throwable.PrintStreamOrWriter {
+
+        WrappedPrintWriter(java.io.PrintWriter printWriter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object lock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void println(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.io.PrintWriter printWriter;
+
+        {
+            printWriter = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/UNIXProcess.java b/ojluni/annotations/hiddenapi/java/lang/UNIXProcess.java
new file mode 100644
index 0000000..75c3aa8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/UNIXProcess.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.
+ */
+
+package java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+final class UNIXProcess extends java.lang.Process {
+
+    UNIXProcess(
+            byte[] prog,
+            byte[] argBlock,
+            int argc,
+            byte[] envBlock,
+            int envc,
+            byte[] dir,
+            int[] fds,
+            boolean redirectErrorStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native int waitForProcessExit(int pid);
+
+    private native int forkAndExec(
+            byte[] prog,
+            byte[] argBlock,
+            int argc,
+            byte[] envBlock,
+            int envc,
+            byte[] dir,
+            int[] fds,
+            boolean redirectErrorStream)
+            throws java.io.IOException;
+
+    static java.io.FileDescriptor newFileDescriptor(int fd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void initStreams(int[] fds) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void processExited(int exitcode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.OutputStream getOutputStream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getInputStream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getErrorStream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int waitFor() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int exitValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void destroyProcess(int pid);
+
+    public void destroy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native void initIDs();
+
+    private int exitcode;
+
+    private boolean hasExited;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private final int pid;
+
+    {
+        pid = 0;
+    }
+
+    private static final java.util.concurrent.Executor processReaperExecutor;
+
+    static {
+        processReaperExecutor = null;
+    }
+
+    private java.io.InputStream stderr;
+
+    private java.io.OutputStream stdin;
+
+    private java.io.InputStream stdout;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class ProcessPipeInputStream extends java.io.BufferedInputStream {
+
+        ProcessPipeInputStream(int fd) {
+            super((java.io.InputStream) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        private static byte[] drainInputStream(java.io.InputStream in) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized void processExited() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class ProcessPipeOutputStream extends java.io.BufferedOutputStream {
+
+        ProcessPipeOutputStream(int fd) {
+            super((java.io.OutputStream) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized void processExited() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ProcessReaperThreadFactory implements java.util.concurrent.ThreadFactory {
+
+        private ProcessReaperThreadFactory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.ThreadGroup getRootThreadGroup() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Thread newThread(java.lang.Runnable grimReaper) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.lang.ThreadGroup group;
+
+        static {
+            group = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/Void.java b/ojluni/annotations/hiddenapi/java/lang/Void.java
new file mode 100644
index 0000000..e082300
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/Void.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1996, 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Void {
+
+    @UnsupportedAppUsage
+    private Void() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.Class<java.lang.Void> TYPE;
+
+    static {
+        TYPE = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/invoke/MethodHandles.java b/ojluni/annotations/hiddenapi/java/lang/invoke/MethodHandles.java
new file mode 100644
index 0000000..dcb5f11
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/invoke/MethodHandles.java
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class MethodHandles {
+
+    private MethodHandles() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandles.Lookup lookup() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandles.Lookup publicLookup() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.reflect.Member> T reflectAs(
+            java.lang.Class<T> expected, java.lang.invoke.MethodHandle target) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.invoke.MethodHandleImpl getMethodHandleImpl(
+            java.lang.invoke.MethodHandle target) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkClassIsArray(java.lang.Class<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkTypeIsViewable(java.lang.Class<?> componentType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?> arrayClass)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte arrayElementGetter(byte[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean arrayElementGetter(boolean[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static char arrayElementGetter(char[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short arrayElementGetter(short[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int arrayElementGetter(int[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long arrayElementGetter(long[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float arrayElementGetter(float[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double arrayElementGetter(double[] array, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?> arrayClass)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(byte[] array, int i, byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(boolean[] array, int i, boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(char[] array, int i, char val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(short[] array, int i, short val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(int[] array, int i, int val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(long[] array, int i, long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(float[] array, int i, float val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void arrayElementSetter(double[] array, int i, double val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.VarHandle arrayElementVarHandle(java.lang.Class<?> arrayClass)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.VarHandle byteArrayViewVarHandle(
+            java.lang.Class<?> viewArrayClass, java.nio.ByteOrder byteOrder)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.VarHandle byteBufferViewVarHandle(
+            java.lang.Class<?> viewArrayClass, java.nio.ByteOrder byteOrder)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle spreadInvoker(
+            java.lang.invoke.MethodType type, int leadingArgCount) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.invoke.MethodHandle methodHandleForVarHandleAccessor(
+            java.lang.invoke.VarHandle.AccessMode accessMode,
+            java.lang.invoke.MethodType type,
+            boolean isExactInvoker) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle varHandleExactInvoker(
+            java.lang.invoke.VarHandle.AccessMode accessMode, java.lang.invoke.MethodType type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle varHandleInvoker(
+            java.lang.invoke.VarHandle.AccessMode accessMode, java.lang.invoke.MethodType type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle explicitCastArguments(
+            java.lang.invoke.MethodHandle target, java.lang.invoke.MethodType newType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void explicitCastArgumentsChecks(
+            java.lang.invoke.MethodHandle target, java.lang.invoke.MethodType newType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle permuteArguments(
+            java.lang.invoke.MethodHandle target,
+            java.lang.invoke.MethodType newType,
+            int... reorder) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean permuteArgumentChecks(
+            int[] reorder,
+            java.lang.invoke.MethodType newType,
+            java.lang.invoke.MethodType oldType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle constant(
+            java.lang.Class<?> type, java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle identity(java.lang.Class<?> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte identity(byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean identity(boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static char identity(char val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short identity(short val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int identity(int val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long identity(long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float identity(float val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double identity(double val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle insertArguments(
+            java.lang.invoke.MethodHandle target, int pos, java.lang.Object... values) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Class<?>[] insertArgumentsChecks(
+            java.lang.invoke.MethodHandle target, int insCount, int pos)
+            throws java.lang.RuntimeException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle dropArguments(
+            java.lang.invoke.MethodHandle target,
+            int pos,
+            java.util.List<java.lang.Class<?>> valueTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.lang.Class<?>> copyTypes(
+            java.util.List<java.lang.Class<?>> types) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int dropArgumentChecks(
+            java.lang.invoke.MethodType oldType,
+            int pos,
+            java.util.List<java.lang.Class<?>> valueTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle dropArguments(
+            java.lang.invoke.MethodHandle target, int pos, java.lang.Class<?>... valueTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle filterArguments(
+            java.lang.invoke.MethodHandle target,
+            int pos,
+            java.lang.invoke.MethodHandle... filters) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void filterArgumentsCheckArity(
+            java.lang.invoke.MethodHandle target,
+            int pos,
+            java.lang.invoke.MethodHandle[] filters) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void filterArgumentChecks(
+            java.lang.invoke.MethodHandle target, int pos, java.lang.invoke.MethodHandle filter)
+            throws java.lang.RuntimeException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle collectArguments(
+            java.lang.invoke.MethodHandle target, int pos, java.lang.invoke.MethodHandle filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.invoke.MethodType collectArgumentsChecks(
+            java.lang.invoke.MethodHandle target, int pos, java.lang.invoke.MethodHandle filter)
+            throws java.lang.RuntimeException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle filterReturnValue(
+            java.lang.invoke.MethodHandle target, java.lang.invoke.MethodHandle filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void filterReturnValueChecks(
+            java.lang.invoke.MethodType targetType, java.lang.invoke.MethodType filterType)
+            throws java.lang.RuntimeException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle foldArguments(
+            java.lang.invoke.MethodHandle target, java.lang.invoke.MethodHandle combiner) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Class<?> foldArgumentChecks(
+            int foldPos,
+            java.lang.invoke.MethodType targetType,
+            java.lang.invoke.MethodType combinerType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle guardWithTest(
+            java.lang.invoke.MethodHandle test,
+            java.lang.invoke.MethodHandle target,
+            java.lang.invoke.MethodHandle fallback) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.RuntimeException misMatchedTypes(
+            java.lang.String what, java.lang.invoke.MethodType t1, java.lang.invoke.MethodType t2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle catchException(
+            java.lang.invoke.MethodHandle target,
+            java.lang.Class<? extends java.lang.Throwable> exType,
+            java.lang.invoke.MethodHandle handler) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.invoke.MethodHandle throwException(
+            java.lang.Class<?> returnType, java.lang.Class<? extends java.lang.Throwable> exType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class Lookup {
+
+        Lookup(java.lang.Class<?> lookupClass) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        private Lookup(java.lang.Class<?> lookupClass, int allowedModes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static int fixmods(int mods) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Class<?> lookupClass() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int lookupModes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?> requestedLookupClass) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static void checkUnprivilegedlookupClass(
+                java.lang.Class<?> lookupClass, int allowedModes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findStatic(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.invoke.MethodType type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle findVirtualForMH(
+                java.lang.String name, java.lang.invoke.MethodType type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle findVirtualForVH(
+                java.lang.String name, java.lang.invoke.MethodType type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.invoke.MethodHandle createMethodHandle(
+                java.lang.reflect.Method method,
+                int handleKind,
+                java.lang.invoke.MethodType methodType) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findVirtual(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.invoke.MethodType type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findConstructor(
+                java.lang.Class<?> refc, java.lang.invoke.MethodType type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle createMethodHandleForConstructor(
+                java.lang.reflect.Constructor constructor) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.invoke.MethodType initMethodType(
+                java.lang.invoke.MethodType constructorType) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findSpecial(
+                java.lang.Class<?> refc,
+                java.lang.String name,
+                java.lang.invoke.MethodType type,
+                java.lang.Class<?> specialCaller)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle findSpecial(
+                java.lang.reflect.Method method,
+                java.lang.invoke.MethodType type,
+                java.lang.Class<?> refc,
+                java.lang.Class<?> specialCaller)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findGetter(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle findAccessor(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type, int kind)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.invoke.MethodHandle findAccessor(
+                java.lang.reflect.Field field,
+                java.lang.Class<?> refc,
+                java.lang.Class<?> type,
+                int kind,
+                boolean performAccessChecks)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findSetter(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.VarHandle findVarHandle(
+                java.lang.Class<?> recv, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.reflect.Field findFieldOfType(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void commonFieldChecks(
+                java.lang.reflect.Field field,
+                java.lang.Class<?> refc,
+                java.lang.Class<?> type,
+                boolean isStatic,
+                boolean performAccessChecks)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findStaticGetter(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle findStaticSetter(
+                java.lang.Class<?> refc, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.VarHandle findStaticVarHandle(
+                java.lang.Class<?> decl, java.lang.String name, java.lang.Class<?> type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle bind(
+                java.lang.Object receiver, java.lang.String name, java.lang.invoke.MethodType type)
+                throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method m)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle unreflectSpecial(
+                java.lang.reflect.Method m, java.lang.Class<?> specialCaller)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle unreflectConstructor(
+                java.lang.reflect.Constructor<?> c) throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field f)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandle unreflectSetter(java.lang.reflect.Field f)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.VarHandle unreflectVarHandle(java.lang.reflect.Field f)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.invoke.MethodHandleInfo revealDirect(
+                java.lang.invoke.MethodHandle target) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean hasPrivateAccess() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void checkAccess(
+                java.lang.Class<?> refc,
+                java.lang.Class<?> defc,
+                int mods,
+                java.lang.String methName)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.String accessFailedMessage(
+                java.lang.Class<?> refc, java.lang.Class<?> defc, int mods) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkSpecialCaller(java.lang.Class<?> specialCaller)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void throwMakeAccessException(java.lang.String message, java.lang.Object from)
+                throws java.lang.IllegalAccessException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkReturnType(
+                java.lang.reflect.Method method, java.lang.invoke.MethodType methodType)
+                throws java.lang.NoSuchMethodException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int ALL_MODES = 15; // 0xf
+
+        static final java.lang.invoke.MethodHandles.Lookup IMPL_LOOKUP;
+
+        static {
+            IMPL_LOOKUP = null;
+        }
+
+        public static final int PACKAGE = 8; // 0x8
+
+        public static final int PRIVATE = 2; // 0x2
+
+        public static final int PROTECTED = 4; // 0x4
+
+        public static final int PUBLIC = 1; // 0x1
+
+        static final java.lang.invoke.MethodHandles.Lookup PUBLIC_LOOKUP;
+
+        static {
+            PUBLIC_LOOKUP = null;
+        }
+
+        private final int allowedModes;
+
+        {
+            allowedModes = 0;
+        }
+
+        private final java.lang.Class<?> lookupClass;
+
+        {
+            lookupClass = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java b/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java
new file mode 100644
index 0000000..b63d0de
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java
@@ -0,0 +1,99 @@
+/*
+ * 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.invoke;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import java.io.Serializable;
+
+public final class SerializedLambda implements Serializable {
+
+    @UnsupportedAppUsage
+    public SerializedLambda(Class<?> capturingClass,
+                            String functionalInterfaceClass,
+                            String functionalInterfaceMethodName,
+                            String functionalInterfaceMethodSignature,
+                            int implMethodKind,
+                            String implClass,
+                            String implMethodName,
+                            String implMethodSignature,
+                            String instantiatedMethodType,
+                            Object[] capturedArgs) { }
+
+    @UnsupportedAppUsage
+    public String getCapturingClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getFunctionalInterfaceClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getFunctionalInterfaceMethodName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getFunctionalInterfaceMethodSignature() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getImplClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getImplMethodName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public String getImplMethodSignature() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int getImplMethodKind() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public final String getInstantiatedMethodType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int getCapturedArgCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public Object getCapturedArg(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java b/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java
new file mode 100644
index 0000000..f2239ea
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.ref;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Reference<T> {
+
+    Reference(T referent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    Reference(T referent, java.lang.ref.ReferenceQueue<? super T> queue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public T get() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final native T getReferent();
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    native void clearReferent();
+
+    public boolean isEnqueued() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean enqueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void reachabilityFence(java.lang.Object ref) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean disableIntrinsic = false;
+
+    java.lang.ref.Reference<?> pendingNext;
+
+    final java.lang.ref.ReferenceQueue<? super T> queue;
+
+    {
+        queue = null;
+    }
+
+    java.lang.ref.Reference queueNext;
+
+    @UnsupportedAppUsage
+    volatile T referent;
+
+    private static boolean slowPathEnabled = false;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SinkHolder {
+
+        private SinkHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static volatile int finalize_count = 0; // 0x0
+
+        static volatile java.lang.Object sink;
+
+        private static java.lang.Object sinkUser;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java b/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java
new file mode 100644
index 0000000..423b830
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2005, 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.ref;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ReferenceQueue<T> {
+
+    public ReferenceQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean enqueueLocked(java.lang.ref.Reference<? extends T> r) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isEnqueued(java.lang.ref.Reference<? extends T> reference) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean enqueue(java.lang.ref.Reference<? extends T> reference) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.ref.Reference<? extends T> reallyPollLocked() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.ref.Reference<? extends T> poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.ref.Reference<? extends T> remove(long timeout)
+            throws java.lang.IllegalArgumentException, java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.ref.Reference<? extends T> remove() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void enqueuePending(java.lang.ref.Reference<?> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static void add(java.lang.ref.Reference<?> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.ref.Reference<? extends T> head;
+
+    private final java.lang.Object lock;
+
+    {
+        lock = null;
+    }
+
+    private static final java.lang.ref.Reference sQueueNextUnenqueued;
+
+    static {
+        sQueueNextUnenqueued = null;
+    }
+
+    private java.lang.ref.Reference<? extends T> tail;
+
+    public static java.lang.ref.Reference<?> unenqueued;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/AccessibleObject.java b/ojluni/annotations/hiddenapi/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 0000000..b105a24
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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!");
+    }
+
+    private static void setAccessible0(java.lang.reflect.AccessibleObject obj, 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.Annotation[] 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.Annotation[] getDeclaredAnnotations() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    boolean override;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java
new file mode 100644
index 0000000..79d24e3
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java
@@ -0,0 +1,164 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Constructor<T> extends java.lang.reflect.Executable {
+
+    private Constructor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private Constructor(
+            java.lang.Class<?> serializationCtor, java.lang.Class<?> serializationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.reflect.Constructor<T> serializationCopy(
+            java.lang.Class<?> ctor, java.lang.Class<?> cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasGenericInformation() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<T> getDeclaringClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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.Class<?>[] 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!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void specificToStringHeader(java.lang.StringBuilder sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toGenericString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void specificToGenericStringHeader(java.lang.StringBuilder sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    private static native java.lang.Object newInstanceFromSerialization(
+            java.lang.Class<?> ctorClass, java.lang.Class<?> allocClass)
+            throws java.lang.IllegalArgumentException, java.lang.InstantiationException,
+                    java.lang.reflect.InvocationTargetException;
+
+    private native T newInstance0(java.lang.Object... args)
+            throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException,
+                    java.lang.InstantiationException, java.lang.reflect.InvocationTargetException;
+
+    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!");
+    }
+
+    private static final java.util.Comparator<java.lang.reflect.Method> ORDER_BY_SIGNATURE;
+
+    static {
+        ORDER_BY_SIGNATURE = null;
+    }
+
+    private final java.lang.Class<?> serializationClass;
+
+    {
+        serializationClass = null;
+    }
+
+    private final java.lang.Class<?> serializationCtor;
+
+    {
+        serializationCtor = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Executable.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Executable.java
new file mode 100644
index 0000000..e40b1b1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Executable.java
@@ -0,0 +1,269 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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!");
+    }
+
+    abstract boolean hasGenericInformation();
+
+    boolean equalParamTypes(java.lang.Class<?>[] params1, java.lang.Class<?>[] params2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void separateWithCommas(java.lang.Class<?>[] types, java.lang.StringBuilder sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void printModifiersIfNonzero(java.lang.StringBuilder sb, int mask, boolean isDefault) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.String sharedToString(
+            int modifierMask,
+            boolean isDefault,
+            java.lang.Class<?>[] parameterTypes,
+            java.lang.Class<?>[] exceptionTypes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void specificToStringHeader(java.lang.StringBuilder sb);
+
+    java.lang.String sharedToGenericString(int modifierMask, boolean isDefault) {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void specificToGenericStringHeader(java.lang.StringBuilder sb);
+
+    public abstract java.lang.Class<?> getDeclaringClass();
+
+    public abstract java.lang.String getName();
+
+    public abstract int getModifiers();
+
+    public abstract java.lang.reflect.TypeVariable<?>[] getTypeParameters();
+
+    public abstract java.lang.Class<?>[] getParameterTypes();
+
+    public int getParameterCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Type[] getGenericParameterTypes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.reflect.Type[] getAllGenericParameterTypes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Parameter[] getParameters() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.reflect.Parameter[] synthesizeAllParams() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void verifyParameters(java.lang.reflect.Parameter[] parameters) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.reflect.Parameter[] privateGetParameters() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean hasRealParameterData() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.reflect.Parameter[] getParameters0();
+
+    public abstract java.lang.Class<?>[] getExceptionTypes();
+
+    public java.lang.reflect.Type[] getGenericExceptionTypes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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.Annotation[][] getParameterAnnotations();
+
+    public <T extends java.lang.annotation.Annotation> T getAnnotation(
+            java.lang.Class<T> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native <T extends java.lang.annotation.Annotation> T getAnnotationNative(
+            java.lang.Class<T> annotationClass);
+
+    public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(
+            java.lang.Class<T> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.annotation.Annotation[] getDeclaredAnnotations() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.annotation.Annotation[] getDeclaredAnnotationsNative();
+
+    private static int fixMethodFlags(int flags) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int getModifiersInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.lang.Class<?> getDeclaringClassInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final native java.lang.Class<?>[] getParameterTypesInternal();
+
+    final native int getParameterCountInternal();
+
+    public final boolean isAnnotationPresent(
+            java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native boolean isAnnotationPresentNative(
+            java.lang.Class<? extends java.lang.annotation.Annotation> annotationType);
+
+    final java.lang.annotation.Annotation[][] getParameterAnnotationsInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.annotation.Annotation[][] getParameterAnnotationsNative();
+
+    public final int getAccessFlags() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final long getArtMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean hasGenericInformationInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.lang.reflect.Executable.GenericInfo getMethodOrConstructorGenericInfoInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String getSignatureAttribute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String[] getSignatureAnnotation();
+
+    final boolean equalNameAndParametersInternal(java.lang.reflect.Method m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    native int compareMethodParametersInternal(java.lang.reflect.Method meth);
+
+    final native java.lang.String getMethodNameInternal();
+
+    final native java.lang.Class<?> getMethodReturnTypeInternal();
+
+    final boolean isDefaultMethodInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isBridgeMethodInternal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int accessFlags;
+
+    @UnsupportedAppUsage
+    private long artMethod;
+
+    private java.lang.Class<?> declaringClass;
+
+    private java.lang.Class<?> declaringClassOfOverriddenMethod;
+
+    private int dexMethodIndex;
+
+    private transient volatile boolean hasRealParameterData;
+
+    private transient volatile java.lang.reflect.Parameter[] parameters;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class GenericInfo {
+
+        GenericInfo(
+                libcore.reflect.ListOfTypes exceptions,
+                libcore.reflect.ListOfTypes parameters,
+                java.lang.reflect.Type ret,
+                java.lang.reflect.TypeVariable<?>[] formal) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.lang.reflect.TypeVariable<?>[] formalTypeParameters;
+
+        {
+            formalTypeParameters = new java.lang.reflect.TypeVariable[0];
+        }
+
+        final libcore.reflect.ListOfTypes genericExceptionTypes;
+
+        {
+            genericExceptionTypes = null;
+        }
+
+        final libcore.reflect.ListOfTypes genericParameterTypes;
+
+        {
+            genericParameterTypes = null;
+        }
+
+        final java.lang.reflect.Type genericReturnType;
+
+        {
+            genericReturnType = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java
new file mode 100644
index 0000000..2048f74
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Field.java
@@ -0,0 +1,189 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Field extends java.lang.reflect.AccessibleObject
+        implements java.lang.reflect.Member {
+
+    private Field() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> getDeclaringClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String getNameInternal();
+
+    public int getModifiers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEnumConstant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSynthetic() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Class<?> getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Type getGenericType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String getSignatureAttribute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String[] getSignatureAnnotation();
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    private native <A extends java.lang.annotation.Annotation> A getAnnotationNative(
+            java.lang.Class<A> annotationType);
+
+    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!");
+    }
+
+    private native boolean isAnnotationPresentNative(
+            java.lang.Class<? extends java.lang.annotation.Annotation> annotationType);
+
+    public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+
+    public int getDexFieldIndex() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int getOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public native long getArtField();
+
+    @UnsupportedAppUsage
+    private int accessFlags;
+
+    private java.lang.Class<?> declaringClass;
+
+    private int dexFieldIndex;
+
+    private int offset;
+
+    private java.lang.Class<?> type;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java
new file mode 100644
index 0000000..40ccf9e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java
@@ -0,0 +1,154 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Parameter implements java.lang.reflect.AnnotatedElement {
+
+    @UnsupportedAppUsage
+    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!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    java.lang.String getRealName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.reflect.Type getParameterizedType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    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!");
+    }
+
+    private static native <A extends java.lang.annotation.Annotation> A getAnnotationNative(
+            java.lang.reflect.Executable executable,
+            int parameterIndex,
+            java.lang.Class<A> annotationType);
+
+    public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(
+            java.lang.Class<T> annotationClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.annotation.Annotation[] 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.Annotation[] getAnnotations() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.lang.reflect.Executable executable;
+
+    {
+        executable = null;
+    }
+
+    private final int index;
+
+    {
+        index = 0;
+    }
+
+    private final int modifiers;
+
+    {
+        modifiers = 0;
+    }
+
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    private transient volatile java.lang.Class<?> parameterClassCache;
+
+    private transient volatile java.lang.reflect.Type parameterTypeCache;
+}
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java
new file mode 100644
index 0000000..e65bf19
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java
@@ -0,0 +1,262 @@
+/*
+ * 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 dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy implements java.io.Serializable {
+
+    private Proxy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected Proxy(java.lang.reflect.InvocationHandler h) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> getProxyClass(
+            java.lang.ClassLoader loader, java.lang.Class<?>... interfaces)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Class<?> getProxyClass0(
+            java.lang.ClassLoader loader, java.lang.Class<?>... interfaces) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.lang.Class<?>[]> deduplicateAndGetExceptions(
+            java.util.List<java.lang.reflect.Method> methods) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Class<?>[] intersectExceptions(
+            java.lang.Class<?>[] aExceptions, java.lang.Class<?>[] bExceptions) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void validateReturnTypes(java.util.List<java.lang.reflect.Method> methods) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.lang.reflect.Method> getMethods(
+            java.lang.Class<?>[] interfaces) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void getMethodsRecursive(
+            java.lang.Class<?>[] interfaces, java.util.List<java.lang.reflect.Method> methods) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native java.lang.Class<?> generateProxy(
+            java.lang.String name,
+            java.lang.Class<?>[] interfaces,
+            java.lang.ClassLoader loader,
+            java.lang.reflect.Method[] methods,
+            java.lang.Class<?>[][] exceptions);
+
+    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!");
+    }
+
+    public static java.lang.reflect.InvocationHandler getInvocationHandler(java.lang.Object proxy)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.lang.Object invoke(
+            java.lang.reflect.Proxy proxy, java.lang.reflect.Method method, java.lang.Object[] args)
+            throws java.lang.Throwable {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.util.Comparator<java.lang.reflect.Method>
+            ORDER_BY_SIGNATURE_AND_SUBTYPE;
+
+    static {
+        ORDER_BY_SIGNATURE_AND_SUBTYPE = null;
+    }
+
+    private static final java.lang.Class<?>[] constructorParams;
+
+    static {
+        constructorParams = new java.lang.Class[0];
+    }
+
+    protected java.lang.reflect.InvocationHandler h;
+
+    private static final java.lang.Object key0;
+
+    static {
+        key0 = null;
+    }
+
+    private static final java.lang.reflect.WeakCache<
+                    java.lang.ClassLoader, java.lang.Class<?>[], java.lang.Class<?>>
+            proxyClassCache;
+
+    static {
+        proxyClassCache = null;
+    }
+
+    private static final long serialVersionUID = -2222568056686623797L; // 0xe127da20cc1043cbL
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class Key1 extends java.lang.ref.WeakReference<java.lang.Class<?>> {
+
+        Key1(java.lang.Class<?> intf) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class Key2 extends java.lang.ref.WeakReference<java.lang.Class<?>> {
+
+        Key2(java.lang.Class<?> intf1, java.lang.Class<?> intf2) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+
+        private final java.lang.ref.WeakReference<java.lang.Class<?>> ref2;
+
+        {
+            ref2 = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class KeyFactory
+            implements java.util.function.BiFunction<
+                    java.lang.ClassLoader, java.lang.Class<?>[], java.lang.Object> {
+
+        private KeyFactory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object apply(
+                java.lang.ClassLoader classLoader, java.lang.Class<?>[] interfaces) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class KeyX {
+
+        KeyX(java.lang.Class<?>[] interfaces) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static boolean equals(
+                java.lang.ref.WeakReference<java.lang.Class<?>>[] refs1,
+                java.lang.ref.WeakReference<java.lang.Class<?>>[] refs2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+
+        private final java.lang.ref.WeakReference<java.lang.Class<?>>[] refs;
+
+        {
+            refs = new java.lang.ref.WeakReference[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class ProxyClassFactory
+            implements java.util.function.BiFunction<
+                    java.lang.ClassLoader, java.lang.Class<?>[], java.lang.Class<?>> {
+
+        private ProxyClassFactory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Class<?> apply(
+                java.lang.ClassLoader loader, java.lang.Class<?>[] interfaces) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.util.concurrent.atomic.AtomicLong nextUniqueNumber;
+
+        static {
+            nextUniqueNumber = null;
+        }
+
+        private static final java.lang.String proxyClassNamePrefix = "$Proxy";
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Authenticator.java b/ojluni/annotations/hiddenapi/java/net/Authenticator.java
new file mode 100644
index 0000000..2765044
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Authenticator.java
@@ -0,0 +1,140 @@
+/*
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Authenticator {
+
+    public Authenticator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setDefault(java.net.Authenticator a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.PasswordAuthentication requestPasswordAuthentication(
+            java.net.InetAddress addr,
+            int port,
+            java.lang.String protocol,
+            java.lang.String prompt,
+            java.lang.String scheme) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.PasswordAuthentication requestPasswordAuthentication(
+            java.lang.String host,
+            java.net.InetAddress addr,
+            int port,
+            java.lang.String protocol,
+            java.lang.String prompt,
+            java.lang.String scheme) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.PasswordAuthentication requestPasswordAuthentication(
+            java.lang.String host,
+            java.net.InetAddress addr,
+            int port,
+            java.lang.String protocol,
+            java.lang.String prompt,
+            java.lang.String scheme,
+            java.net.URL url,
+            java.net.Authenticator.RequestorType reqType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.String getRequestingHost() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.net.InetAddress getRequestingSite() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final int getRequestingPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.String getRequestingProtocol() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.String getRequestingPrompt() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.lang.String getRequestingScheme() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.PasswordAuthentication getPasswordAuthentication() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.URL getRequestingURL() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.Authenticator.RequestorType getRequestorType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.net.Authenticator.RequestorType requestingAuthType;
+
+    private java.lang.String requestingHost;
+
+    private int requestingPort;
+
+    private java.lang.String requestingPrompt;
+
+    private java.lang.String requestingProtocol;
+
+    private java.lang.String requestingScheme;
+
+    private java.net.InetAddress requestingSite;
+
+    private java.net.URL requestingURL;
+
+    @UnsupportedAppUsage
+    private static java.net.Authenticator theAuthenticator;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum RequestorType {
+        PROXY,
+        SERVER;
+
+        private RequestorType() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/DatagramSocket.java b/ojluni/annotations/hiddenapi/java/net/DatagramSocket.java
new file mode 100644
index 0000000..fd804c7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/DatagramSocket.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DatagramSocket implements java.io.Closeable {
+
+    public DatagramSocket() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected DatagramSocket(java.net.DatagramSocketImpl impl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DatagramSocket(java.net.SocketAddress bindaddr) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DatagramSocket(int port) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DatagramSocket(int port, java.net.InetAddress laddr) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void connectInternal(java.net.InetAddress address, int port)
+            throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkOldImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void createImpl() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.net.DatagramSocketImpl getImpl() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void bind(java.net.SocketAddress addr) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkAddress(java.net.InetAddress addr, java.lang.String op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void connect(java.net.InetAddress address, int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void connect(java.net.SocketAddress addr) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void disconnect() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isBound() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isConnected() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getInetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress getRemoteSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress getLocalSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void send(java.net.DatagramPacket p) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void receive(java.net.DatagramPacket p) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean checkFiltering(java.net.DatagramPacket p) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getLocalPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSoTimeout(int timeout) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getSoTimeout() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSendBufferSize(int size) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getSendBufferSize() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getReceiveBufferSize() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setReuseAddress(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean getReuseAddress() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setBroadcast(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean getBroadcast() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setTrafficClass(int tc) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getTrafficClass() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isClosed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.DatagramChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setDatagramSocketImplFactory(
+            java.net.DatagramSocketImplFactory fac) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.io.FileDescriptor getFileDescriptor$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int ST_CONNECTED = 1; // 0x1
+
+    static final int ST_CONNECTED_NO_IMPL = 2; // 0x2
+
+    static final int ST_NOT_CONNECTED = 0; // 0x0
+
+    private boolean bound = false;
+
+    private int bytesLeftToFilter;
+
+    private java.lang.Object closeLock;
+
+    private boolean closed = false;
+
+    int connectState = 0; // 0x0
+
+    java.net.InetAddress connectedAddress;
+
+    int connectedPort = -1; // 0xffffffff
+
+    private boolean created = false;
+
+    private boolean explicitFilter = false;
+
+    static java.net.DatagramSocketImplFactory factory;
+
+    @UnsupportedAppUsage
+    java.net.DatagramSocketImpl impl;
+
+    static java.lang.Class<?> implClass;
+
+    boolean oldImpl = false;
+
+    private java.net.SocketException pendingConnectException;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/HttpCookie.java b/ojluni/annotations/hiddenapi/java/net/HttpCookie.java
new file mode 100644
index 0000000..113e804
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/HttpCookie.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class HttpCookie implements java.lang.Cloneable {
+
+    public HttpCookie(java.lang.String name, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private HttpCookie(java.lang.String name, java.lang.String value, java.lang.String header) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.net.HttpCookie> parse(java.lang.String header) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.net.HttpCookie> parse(
+            java.lang.String header, boolean retainHeader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasExpired() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setComment(java.lang.String purpose) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getComment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCommentURL(java.lang.String purpose) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCommentURL() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDiscard(boolean discard) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getDiscard() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPortlist(java.lang.String ports) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPortlist() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDomain(java.lang.String pattern) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDomain() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMaxAge(long expiry) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getMaxAge() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPath(java.lang.String uri) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setSecure(boolean flag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getSecure() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setValue(java.lang.String newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setVersion(int v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isHttpOnly() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setHttpOnly(boolean httpOnly) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean domainMatches(java.lang.String domain, java.lang.String host) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isFullyQualifiedDomainName(java.lang.String s, int firstCharacter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isToken(java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.HttpCookie parseInternal(
+            java.lang.String header, boolean retainHeader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void assignAttribute(
+            java.net.HttpCookie cookie, java.lang.String attrName, java.lang.String attrValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String header() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toNetscapeHeaderString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toRFC2965HeaderString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int guessCookieVersion(java.lang.String header) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String stripOffSurroundingQuote(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean equalsIgnoreCase(java.lang.String s, java.lang.String t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean startsWithIgnoreCase(java.lang.String s, java.lang.String start) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.lang.String> splitMultiCookies(java.lang.String header) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final java.util.TimeZone GMT;
+
+    static {
+        GMT = null;
+    }
+
+    private static final long MAX_AGE_UNSPECIFIED = -1L; // 0xffffffffffffffffL
+
+    private static final java.util.Set<java.lang.String> RESERVED_NAMES;
+
+    static {
+        RESERVED_NAMES = null;
+    }
+
+    private static final java.lang.String SET_COOKIE = "set-cookie:";
+
+    private static final java.lang.String SET_COOKIE2 = "set-cookie2:";
+
+    @UnsupportedAppUsage
+    static final java.util.Map<java.lang.String, java.net.HttpCookie.CookieAttributeAssignor>
+            assignors;
+
+    static {
+        assignors = null;
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.String comment;
+
+    @UnsupportedAppUsage
+    private java.lang.String commentURL;
+
+    @UnsupportedAppUsage
+    private java.lang.String domain;
+
+    @UnsupportedAppUsage
+    private final java.lang.String header;
+
+    {
+        header = null;
+    }
+
+    @UnsupportedAppUsage
+    private boolean httpOnly;
+
+    @UnsupportedAppUsage
+    private long maxAge = -1L; // 0xffffffffffffffffL
+
+    @UnsupportedAppUsage
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.String path;
+
+    @UnsupportedAppUsage
+    private java.lang.String portlist;
+
+    @UnsupportedAppUsage
+    private boolean secure;
+
+    @UnsupportedAppUsage
+    private boolean toDiscard;
+
+    @UnsupportedAppUsage
+    private static final java.lang.String tspecials = ",;= \t";
+
+    @UnsupportedAppUsage
+    private java.lang.String value;
+
+    @UnsupportedAppUsage
+    private int version = 1; // 0x1
+
+    @UnsupportedAppUsage
+    private final long whenCreated;
+
+    {
+        whenCreated = 0;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static interface CookieAttributeAssignor {
+
+        public void assign(
+                java.net.HttpCookie cookie, java.lang.String attrName, java.lang.String attrValue);
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Inet4Address.java b/ojluni/annotations/hiddenapi/java/net/Inet4Address.java
new file mode 100644
index 0000000..16395ea
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Inet4Address.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet4Address extends java.net.InetAddress {
+
+    @UnsupportedAppUsage
+    Inet4Address() {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet4Address(java.lang.String hostName, byte[] addr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet4Address(java.lang.String hostName, int address) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object writeReplace() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMulticastAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAnyLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLoopbackAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLinkLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSiteLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCGlobal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCNodeLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCLinkLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCSiteLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCOrgLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHostAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String numericToTextFormat(byte[] src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static final java.net.InetAddress ALL;
+
+    static {
+        ALL = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final java.net.InetAddress ANY;
+
+    static {
+        ANY = null;
+    }
+
+    static final int INADDRSZ = 4; // 0x4
+
+    public static final java.net.InetAddress LOOPBACK;
+
+    static {
+        LOOPBACK = null;
+    }
+
+    private static final long serialVersionUID = 3286316764910316507L; // 0x2d9b57af9fe3ebdbL
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Inet6Address.java b/ojluni/annotations/hiddenapi/java/net/Inet6Address.java
new file mode 100644
index 0000000..f46fa58
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Inet6Address.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet6Address extends java.net.InetAddress {
+
+    @UnsupportedAppUsage
+    Inet6Address() {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet6Address(java.lang.String hostName, byte[] addr, int scope_id) {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet6Address(java.lang.String hostName, byte[] addr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet6Address(java.lang.String hostName, byte[] addr, java.net.NetworkInterface nif)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    Inet6Address(java.lang.String hostName, byte[] addr, java.lang.String ifname)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.Inet6Address getByAddress(
+            java.lang.String host, byte[] addr, java.net.NetworkInterface nif)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.Inet6Address getByAddress(
+            java.lang.String host, byte[] addr, int scope_id) throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initstr(java.lang.String hostName, byte[] addr, java.lang.String ifname)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initif(java.lang.String hostName, byte[] addr, java.net.NetworkInterface nif)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isDifferentLocalAddressType(byte[] thisAddr, byte[] otherAddr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int deriveNumericScope(byte[] thisAddr, java.net.NetworkInterface ifc)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int deriveNumericScope(java.lang.String ifname) throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMulticastAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAnyLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLoopbackAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLinkLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isLinkLocalAddress(byte[] ipaddress) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSiteLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isSiteLocalAddress(byte[] ipaddress) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCGlobal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCNodeLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCLinkLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCSiteLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCOrgLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getScopeId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.NetworkInterface getScopedInterface() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHostAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isIPv4CompatibleAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String numericToTextFormat(byte[] src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static final java.net.InetAddress ANY;
+
+    static {
+        ANY = null;
+    }
+
+    private static final long FIELDS_OFFSET;
+
+    static {
+        FIELDS_OFFSET = 0;
+    }
+
+    static final int INADDRSZ = 16; // 0x10
+
+    private static final int INT16SZ = 2; // 0x2
+
+    public static final java.net.InetAddress LOOPBACK;
+
+    static {
+        LOOPBACK = null;
+    }
+
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static {
+        UNSAFE = null;
+    }
+
+    @UnsupportedAppUsage
+    private final transient java.net.Inet6Address.Inet6AddressHolder holder6;
+
+    {
+        holder6 = null;
+    }
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private static final long serialVersionUID = 6880410070516793377L; // 0x5f7c2081522c8021L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Inet6AddressHolder {
+
+        private Inet6AddressHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private Inet6AddressHolder(
+                byte[] ipaddress,
+                int scope_id,
+                boolean scope_id_set,
+                java.net.NetworkInterface ifname,
+                boolean scope_ifname_set) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setAddr(byte[] addr) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void init(byte[] addr, int scope_id) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void init(byte[] addr, java.net.NetworkInterface nif) throws java.net.UnknownHostException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isIPv4CompatibleAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMulticastAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isAnyLocalAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isLoopbackAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isLinkLocalAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isSiteLocalAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMCGlobal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMCNodeLocal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMCLinkLocal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMCSiteLocal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isMCOrgLocal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        byte[] ipaddress;
+
+        @UnsupportedAppUsage
+        int scope_id;
+
+        @UnsupportedAppUsage
+        boolean scope_id_set;
+
+        @UnsupportedAppUsage
+        java.net.NetworkInterface scope_ifname;
+
+        boolean scope_ifname_set;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Inet6AddressImpl.java b/ojluni/annotations/hiddenapi/java/net/Inet6AddressImpl.java
new file mode 100644
index 0000000..964bdda
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Inet6AddressImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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.net;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class Inet6AddressImpl implements java.net.InetAddressImpl {
+
+    Inet6AddressImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress[] lookupAllHostAddr(java.lang.String host, int netId)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.InetAddress[] lookupHostByName(java.lang.String host, int netId)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHostByAddr(byte[] addr) throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clearAddressCache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isReachable(
+            java.net.InetAddress addr, int timeout, java.net.NetworkInterface netif, int ttl)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean tcpEcho(
+            java.net.InetAddress addr, int timeout, java.net.InetAddress sourceAddr, int ttl)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean icmpEcho(
+            java.net.InetAddress addr, int timeout, java.net.InetAddress sourceAddr, int ttl)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress anyLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress[] loopbackAddresses() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String getHostByAddr0(byte[] addr) throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static final java.net.AddressCache addressCache;
+
+    static {
+        addressCache = null;
+    }
+
+    private static java.net.InetAddress anyLocalAddress;
+
+    private static java.net.InetAddress[] loopbackAddresses;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/InetAddress.java b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
new file mode 100644
index 0000000..0f128dd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetAddress implements java.io.Serializable {
+
+    InetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.net.InetAddress.InetAddressHolder holder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readResolve() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMulticastAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAnyLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLoopbackAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLinkLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSiteLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCGlobal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCNodeLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCLinkLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCSiteLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isMCOrgLocal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isReachable(int timeout) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isReachable(java.net.NetworkInterface netif, int ttl, int timeout)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isReachableByICMP(int timeout) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHostName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCanonicalHostName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getHostFromNameService(java.net.InetAddress addr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHostAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getByAddress(java.lang.String host, byte[] addr)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.InetAddress getByAddress(
+            java.lang.String host, byte[] addr, int scopeId) throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getByName(java.lang.String host)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress[] getAllByName(java.lang.String host)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getLoopbackAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getByAddress(byte[] addr)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.net.InetAddress anyLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObjectNoData(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891)
+    public static boolean isNumeric(java.lang.String address) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.net.InetAddress parseNumericAddressNoThrow(java.lang.String address) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.net.InetAddress disallowDeprecatedFormats(
+            java.lang.String address, java.net.InetAddress inetAddress) {
+        throw new RuntimeException("Stub!");
+    }
+
+    /**
+     * @deprecated Use {@code android.net.InetAddresses.parseNumericAddress(String)} instead.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891)
+    public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static void clearDnsCache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetAddress getByNameOnNet(java.lang.String host, int netId)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static java.net.InetAddress[] getAllByNameOnNet(java.lang.String host, int netId)
+            throws java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.ClassLoader BOOT_CLASSLOADER;
+
+    static {
+        BOOT_CLASSLOADER = null;
+    }
+
+    static final int NETID_UNSET = 0; // 0x0
+
+    private transient java.lang.String canonicalHostName;
+
+    @UnsupportedAppUsage
+    transient java.net.InetAddress.InetAddressHolder holder;
+
+    static final java.net.InetAddressImpl impl;
+
+    static {
+        impl = null;
+    }
+
+    private static final sun.net.spi.nameservice.NameService nameService;
+
+    static {
+        nameService = null;
+    }
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private static final long serialVersionUID = 3286316764910316507L; // 0x2d9b57af9fe3ebdbL
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class InetAddressHolder {
+
+        InetAddressHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        InetAddressHolder(java.lang.String hostName, int address, int family) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void init(java.lang.String hostName, int family) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.String getHostName() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.String getOriginalHostName() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int getAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int getFamily() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        int address;
+
+        @UnsupportedAppUsage
+        int family;
+
+        @UnsupportedAppUsage
+        java.lang.String hostName;
+
+        @UnsupportedAppUsage
+        java.lang.String originalHostName;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/InetSocketAddress.java b/ojluni/annotations/hiddenapi/java/net/InetSocketAddress.java
new file mode 100644
index 0000000..0a54f95
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/InetSocketAddress.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetSocketAddress extends java.net.SocketAddress {
+
+    public InetSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public InetSocketAddress(int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public InetSocketAddress(java.net.InetAddress addr, int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public InetSocketAddress(java.lang.String hostname, int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private InetSocketAddress(int port, java.lang.String hostname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int checkPort(int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String checkHost(java.lang.String hostname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.InetSocketAddress createUnresolved(java.lang.String host, int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream in)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObjectNoData() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.net.InetAddress getAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getHostName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getHostString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isUnresolved() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long FIELDS_OFFSET;
+
+    static {
+        FIELDS_OFFSET = 0;
+    }
+
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static {
+        UNSAFE = null;
+    }
+
+    @UnsupportedAppUsage
+    private final transient java.net.InetSocketAddress.InetSocketAddressHolder holder;
+
+    {
+        holder = null;
+    }
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private static final long serialVersionUID = 5076001401234631237L; // 0x467194616ff9aa45L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class InetSocketAddressHolder {
+
+        private InetSocketAddressHolder(
+                java.lang.String hostname, java.net.InetAddress addr, int port) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getPort() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.net.InetAddress getAddress() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String getHostName() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String getHostString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean isUnresolved() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.net.InetAddress addr;
+
+        private java.lang.String hostname;
+
+        private int port;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java b/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java
new file mode 100644
index 0000000..7287847
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InterfaceAddress {
+
+    @UnsupportedAppUsage
+    InterfaceAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    InterfaceAddress(
+            java.net.InetAddress address,
+            java.net.Inet4Address broadcast,
+            java.net.InetAddress netmask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private short countPrefixLength(java.net.InetAddress netmask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getBroadcast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public short getNetworkPrefixLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.net.InetAddress address;
+
+    private java.net.Inet4Address broadcast;
+
+    private short maskLength = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/PlainSocketImpl.java b/ojluni/annotations/hiddenapi/java/net/PlainSocketImpl.java
new file mode 100644
index 0000000..806a428
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/PlainSocketImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2007, 2008, 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.net;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class PlainSocketImpl extends java.net.AbstractPlainSocketImpl {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    PlainSocketImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    PlainSocketImpl(java.io.FileDescriptor fd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected <T> void setOption(java.net.SocketOption<T> name, T value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected <T> T getOption(java.net.SocketOption<T> name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void socketSetOption(int opt, java.lang.Object val) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketCreate(boolean isStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketConnect(java.net.InetAddress address, int port, int timeout)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketBind(java.net.InetAddress address, int port) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketListen(int count) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketAccept(java.net.SocketImpl s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    int socketAvailable() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketClose0(boolean useDeferredClose) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.io.FileDescriptor getMarkerFD() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketShutdown(int howto) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketSetOption0(int cmd, java.lang.Object value) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.Object socketGetOption(int opt) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void socketSendUrgentData(int data) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Proxy.java b/ojluni/annotations/hiddenapi/java/net/Proxy.java
new file mode 100644
index 0000000..4df3fa4
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Proxy.java
@@ -0,0 +1,82 @@
+/*
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy {
+
+    @UnsupportedAppUsage
+    private Proxy() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Proxy(java.net.Proxy.Type type, java.net.SocketAddress sa) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.Proxy.Type type() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress address() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.net.Proxy NO_PROXY;
+
+    static {
+        NO_PROXY = null;
+    }
+
+    private java.net.SocketAddress sa;
+
+    private java.net.Proxy.Type type;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum Type {
+        DIRECT,
+        HTTP,
+        SOCKS;
+
+        private Type() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/ServerSocket.java b/ojluni/annotations/hiddenapi/java/net/ServerSocket.java
new file mode 100644
index 0000000..eabb247
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/ServerSocket.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ServerSocket implements java.io.Closeable {
+
+    ServerSocket(java.net.SocketImpl impl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ServerSocket() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ServerSocket(int port) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ServerSocket(int port, int backlog) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ServerSocket(int port, int backlog, java.net.InetAddress bindAddr)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketImpl getImpl() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkOldImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void createImpl() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void bind(java.net.SocketAddress endpoint) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void bind(java.net.SocketAddress endpoint, int backlog) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getInetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getLocalPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress getLocalSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.Socket accept() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final void implAccept(java.net.Socket s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.ServerSocketChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isBound() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isClosed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSoTimeout(int timeout) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getSoTimeout() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setReuseAddress(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getReuseAddress() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setBound() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setCreated() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setSocketFactory(java.net.SocketImplFactory fac)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getReceiveBufferSize() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.FileDescriptor getFileDescriptor$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean bound = false;
+
+    private java.lang.Object closeLock;
+
+    private boolean closed = false;
+
+    private boolean created = false;
+
+    @UnsupportedAppUsage
+    private static java.net.SocketImplFactory factory;
+
+    private java.net.SocketImpl impl;
+
+    private boolean oldImpl = false;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/Socket.java b/ojluni/annotations/hiddenapi/java/net/Socket.java
new file mode 100644
index 0000000..2ad18ff
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/Socket.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Socket implements java.io.Closeable {
+
+    public Socket() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Socket(java.net.Proxy proxy) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected Socket(java.net.SocketImpl impl) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Socket(java.lang.String host, int port)
+            throws java.io.IOException, java.net.UnknownHostException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Socket(java.net.InetAddress address, int port) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Socket(java.lang.String host, int port, java.net.InetAddress localAddr, int localPort)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Socket(
+            java.net.InetAddress address, int port, java.net.InetAddress localAddr, int localPort)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public Socket(java.lang.String host, int port, boolean stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public Socket(java.net.InetAddress host, int port, boolean stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private Socket(
+            java.net.InetAddress[] addresses,
+            int port,
+            java.net.SocketAddress localAddr,
+            boolean stream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.InetAddress[] nonNullAddress(java.net.InetAddress address) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void createImpl(boolean stream) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkOldImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.net.SocketImpl getImpl() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void connect(java.net.SocketAddress endpoint) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void connect(java.net.SocketAddress endpoint, int timeout) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void bind(java.net.SocketAddress bindpoint) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkAddress(java.net.InetAddress addr, java.lang.String op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void postAccept() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setCreated() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setBound() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setConnected() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getInetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.InetAddress getLocalAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getLocalPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress getRemoteSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.SocketAddress getLocalSocketAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.SocketChannel getChannel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getInputStream() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.OutputStream getOutputStream() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTcpNoDelay(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getTcpNoDelay() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setSoLinger(boolean on, int linger) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getSoLinger() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sendUrgentData(int data) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setOOBInline(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getOOBInline() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSoTimeout(int timeout) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getSoTimeout() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSendBufferSize(int size) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getSendBufferSize() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getReceiveBufferSize() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setKeepAlive(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getKeepAlive() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTrafficClass(int tc) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getTrafficClass() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setReuseAddress(boolean on) throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getReuseAddress() throws java.net.SocketException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void shutdownInput() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void shutdownOutput() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isConnected() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isBound() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isClosed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isInputShutdown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isOutputShutdown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setSocketImplFactory(java.net.SocketImplFactory fac)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.io.FileDescriptor getFileDescriptor$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean bound = false;
+
+    private java.lang.Object closeLock;
+
+    private boolean closed = false;
+
+    private boolean connected = false;
+
+    private boolean created = false;
+
+    @UnsupportedAppUsage
+    private static java.net.SocketImplFactory factory;
+
+    @UnsupportedAppUsage
+    java.net.SocketImpl impl;
+
+    private boolean oldImpl = false;
+
+    private boolean shutIn = false;
+
+    private boolean shutOut = false;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/SocketException.java b/ojluni/annotations/hiddenapi/java/net/SocketException.java
new file mode 100644
index 0000000..03e48e9
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/SocketException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SocketException extends java.io.IOException {
+
+    public SocketException(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SocketException() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SocketException(java.lang.Throwable cause) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public SocketException(java.lang.String msg, java.lang.Throwable cause) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long serialVersionUID = -5935874303556886934L; // 0xad9f89c5411f5e6aL
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/SocketImpl.java b/ojluni/annotations/hiddenapi/java/net/SocketImpl.java
new file mode 100644
index 0000000..be5c4f8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/SocketImpl.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SocketImpl implements java.net.SocketOptions {
+
+    public SocketImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void create(boolean stream) throws java.io.IOException;
+
+    protected abstract void connect(java.lang.String host, int port) throws java.io.IOException;
+
+    protected abstract void connect(java.net.InetAddress address, int port)
+            throws java.io.IOException;
+
+    protected abstract void connect(java.net.SocketAddress address, int timeout)
+            throws java.io.IOException;
+
+    protected abstract void bind(java.net.InetAddress host, int port) throws java.io.IOException;
+
+    protected abstract void listen(int backlog) throws java.io.IOException;
+
+    protected abstract void accept(java.net.SocketImpl s) throws java.io.IOException;
+
+    protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
+
+    protected abstract java.io.OutputStream getOutputStream() throws java.io.IOException;
+
+    protected abstract int available() throws java.io.IOException;
+
+    protected abstract void close() throws java.io.IOException;
+
+    protected void shutdownInput() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void shutdownOutput() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.io.FileDescriptor getFileDescriptor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.FileDescriptor getFD$() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.InetAddress getInetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean supportsUrgentData() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void sendUrgentData(int data) throws java.io.IOException;
+
+    protected int getLocalPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setSocket(java.net.Socket soc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.net.Socket getSocket() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setServerSocket(java.net.ServerSocket soc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.net.ServerSocket getServerSocket() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void reset() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    <T> void setOption(java.net.SocketOption<T> name, T value) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    <T> T getOption(java.net.SocketOption<T> name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.InetAddress address;
+
+    protected java.io.FileDescriptor fd;
+
+    protected int localport;
+
+    protected int port;
+
+    @UnsupportedAppUsage
+    java.net.ServerSocket serverSocket;
+
+    @UnsupportedAppUsage
+    java.net.Socket socket;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/SocksSocketImpl.java b/ojluni/annotations/hiddenapi/java/net/SocksSocketImpl.java
new file mode 100644
index 0000000..6e0f66c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/SocksSocketImpl.java
@@ -0,0 +1,137 @@
+/*
+ * 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
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class SocksSocketImpl extends java.net.PlainSocketImpl implements java.net.SocksConsts {
+
+    @UnsupportedAppUsage
+    SocksSocketImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    SocksSocketImpl(java.lang.String server, int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    SocksSocketImpl(java.net.Proxy proxy) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setV4() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void privilegedConnect(java.lang.String host, int port, int timeout)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void superConnectServer(java.lang.String host, int port, int timeout)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int remainingMillis(long deadlineMillis) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int readSocksReply(java.io.InputStream in, byte[] data) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int readSocksReply(java.io.InputStream in, byte[] data, long deadlineMillis)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean authenticate(
+            byte method, java.io.InputStream in, java.io.BufferedOutputStream out)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean authenticate(
+            byte method,
+            java.io.InputStream in,
+            java.io.BufferedOutputStream out,
+            long deadlineMillis)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void connectV4(
+            java.io.InputStream in,
+            java.io.OutputStream out,
+            java.net.InetSocketAddress endpoint,
+            long deadlineMillis)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void connect(java.net.SocketAddress endpoint, int timeout)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.net.InetAddress getInetAddress() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int getLocalPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String getUserName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean applicationSetProxy;
+
+    private java.io.InputStream cmdIn;
+
+    private java.io.OutputStream cmdOut;
+
+    private java.net.Socket cmdsock;
+
+    private java.net.InetSocketAddress external_address;
+
+    private java.lang.String server;
+
+    private int serverPort = 1080; // 0x438
+
+    private boolean useV4 = false;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/URI.java b/ojluni/annotations/hiddenapi/java/net/URI.java
new file mode 100644
index 0000000..2287ab8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/URI.java
@@ -0,0 +1,808 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class URI implements java.lang.Comparable<java.net.URI>, java.io.Serializable {
+
+    private URI() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URI(java.lang.String str) throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URI(
+            java.lang.String scheme,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String fragment)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URI(
+            java.lang.String scheme,
+            java.lang.String authority,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String fragment)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URI(
+            java.lang.String scheme,
+            java.lang.String host,
+            java.lang.String path,
+            java.lang.String fragment)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URI(java.lang.String scheme, java.lang.String ssp, java.lang.String fragment)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URI create(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI parseServerAuthority() throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI normalize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI resolve(java.net.URI uri) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI resolve(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI relativize(java.net.URI uri) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL toURL() throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getScheme() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAbsolute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isOpaque() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawSchemeSpecificPart() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSchemeSpecificPart() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawAuthority() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAuthority() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawUserInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getUserInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHost() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawQuery() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getQuery() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRawFragment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getFragment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object ob) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.net.URI that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toASCIIString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream os) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream is)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int toLower(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int toUpper(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean equal(java.lang.String s, java.lang.String t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean equalIgnoringCase(java.lang.String s, java.lang.String t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int hash(int hash, java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int normalizedHash(int hash, java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int hashIgnoringCase(int hash, java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compare(java.lang.String s, java.lang.String t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compareIgnoringCase(java.lang.String s, java.lang.String t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkPath(
+            java.lang.String s, java.lang.String scheme, java.lang.String path)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void appendAuthority(
+            java.lang.StringBuffer sb,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void appendSchemeSpecificPart(
+            java.lang.StringBuffer sb,
+            java.lang.String opaquePart,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port,
+            java.lang.String path,
+            java.lang.String query) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void appendFragment(java.lang.StringBuffer sb, java.lang.String fragment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toString(
+            java.lang.String scheme,
+            java.lang.String opaquePart,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String fragment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void defineSchemeSpecificPart() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void defineString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String resolvePath(
+            java.lang.String base, java.lang.String child, boolean absolute) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URI resolve(java.net.URI base, java.net.URI child) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URI normalize(java.net.URI u) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URI relativize(java.net.URI base, java.net.URI child) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int needsNormalization(java.lang.String path) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void split(char[] path, int[] segs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int join(char[] path, int[] segs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void removeDots(char[] path, int[] segs, boolean removeLeading) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void maybeAddLeadingDot(char[] path, int[] segs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String normalize(java.lang.String ps) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String normalize(java.lang.String ps, boolean removeLeading) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long lowMask(java.lang.String chars) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long highMask(java.lang.String chars) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long lowMask(char first, char last) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long highMask(char first, char last) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean match(char c, long lowMask, long highMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendEscape(java.lang.StringBuffer sb, byte b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendEncoded(java.lang.StringBuffer sb, char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String quote(java.lang.String s, long lowMask, long highMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String encode(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int decode(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static byte decode(char c1, char c2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String decode(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long H_ALPHA;
+
+    static {
+        H_ALPHA = 0;
+    }
+
+    private static final long H_ALPHANUM;
+
+    static {
+        H_ALPHANUM = 0;
+    }
+
+    private static final long H_DASH;
+
+    static {
+        H_DASH = 0;
+    }
+
+    private static final long H_DIGIT = 0L; // 0x0L
+
+    private static final long H_DOT;
+
+    static {
+        H_DOT = 0;
+    }
+
+    private static final long H_ESCAPED = 0L; // 0x0L
+
+    private static final long H_HEX;
+
+    static {
+        H_HEX = 0;
+    }
+
+    private static final long H_LEFT_BRACKET;
+
+    static {
+        H_LEFT_BRACKET = 0;
+    }
+
+    private static final long H_LOWALPHA;
+
+    static {
+        H_LOWALPHA = 0;
+    }
+
+    private static final long H_MARK;
+
+    static {
+        H_MARK = 0;
+    }
+
+    private static final long H_PATH;
+
+    static {
+        H_PATH = 0;
+    }
+
+    private static final long H_PCHAR;
+
+    static {
+        H_PCHAR = 0;
+    }
+
+    private static final long H_REG_NAME;
+
+    static {
+        H_REG_NAME = 0;
+    }
+
+    private static final long H_RESERVED;
+
+    static {
+        H_RESERVED = 0;
+    }
+
+    private static final long H_SCHEME;
+
+    static {
+        H_SCHEME = 0;
+    }
+
+    private static final long H_SERVER;
+
+    static {
+        H_SERVER = 0;
+    }
+
+    private static final long H_SERVER_PERCENT;
+
+    static {
+        H_SERVER_PERCENT = 0;
+    }
+
+    private static final long H_UNDERSCORE;
+
+    static {
+        H_UNDERSCORE = 0;
+    }
+
+    private static final long H_UNRESERVED;
+
+    static {
+        H_UNRESERVED = 0;
+    }
+
+    private static final long H_UPALPHA;
+
+    static {
+        H_UPALPHA = 0;
+    }
+
+    private static final long H_URIC;
+
+    static {
+        H_URIC = 0;
+    }
+
+    private static final long H_URIC_NO_SLASH;
+
+    static {
+        H_URIC_NO_SLASH = 0;
+    }
+
+    private static final long H_USERINFO;
+
+    static {
+        H_USERINFO = 0;
+    }
+
+    private static final long L_ALPHA = 0L; // 0x0L
+
+    private static final long L_ALPHANUM;
+
+    static {
+        L_ALPHANUM = 0;
+    }
+
+    private static final long L_DASH;
+
+    static {
+        L_DASH = 0;
+    }
+
+    private static final long L_DIGIT;
+
+    static {
+        L_DIGIT = 0;
+    }
+
+    private static final long L_DOT;
+
+    static {
+        L_DOT = 0;
+    }
+
+    private static final long L_ESCAPED = 1L; // 0x1L
+
+    private static final long L_HEX;
+
+    static {
+        L_HEX = 0;
+    }
+
+    private static final long L_LEFT_BRACKET;
+
+    static {
+        L_LEFT_BRACKET = 0;
+    }
+
+    private static final long L_LOWALPHA = 0L; // 0x0L
+
+    private static final long L_MARK;
+
+    static {
+        L_MARK = 0;
+    }
+
+    private static final long L_PATH;
+
+    static {
+        L_PATH = 0;
+    }
+
+    private static final long L_PCHAR;
+
+    static {
+        L_PCHAR = 0;
+    }
+
+    private static final long L_REG_NAME;
+
+    static {
+        L_REG_NAME = 0;
+    }
+
+    private static final long L_RESERVED;
+
+    static {
+        L_RESERVED = 0;
+    }
+
+    private static final long L_SCHEME;
+
+    static {
+        L_SCHEME = 0;
+    }
+
+    private static final long L_SERVER;
+
+    static {
+        L_SERVER = 0;
+    }
+
+    private static final long L_SERVER_PERCENT;
+
+    static {
+        L_SERVER_PERCENT = 0;
+    }
+
+    private static final long L_UNDERSCORE;
+
+    static {
+        L_UNDERSCORE = 0;
+    }
+
+    private static final long L_UNRESERVED;
+
+    static {
+        L_UNRESERVED = 0;
+    }
+
+    private static final long L_UPALPHA = 0L; // 0x0L
+
+    private static final long L_URIC;
+
+    static {
+        L_URIC = 0;
+    }
+
+    private static final long L_URIC_NO_SLASH;
+
+    static {
+        L_URIC_NO_SLASH = 0;
+    }
+
+    private static final long L_USERINFO;
+
+    static {
+        L_USERINFO = 0;
+    }
+
+    private transient java.lang.String authority;
+
+    private transient volatile java.lang.String decodedAuthority;
+
+    private transient volatile java.lang.String decodedFragment;
+
+    private transient volatile java.lang.String decodedPath;
+
+    private transient volatile java.lang.String decodedQuery;
+
+    private transient volatile java.lang.String decodedSchemeSpecificPart;
+
+    private transient volatile java.lang.String decodedUserInfo;
+
+    @UnsupportedAppUsage
+    private transient java.lang.String fragment;
+
+    private transient volatile int hash;
+
+    private static final char[] hexDigits;
+
+    static {
+        hexDigits = new char[0];
+    }
+
+    @UnsupportedAppUsage
+    private transient java.lang.String host;
+
+    private transient java.lang.String path;
+
+    @UnsupportedAppUsage
+    private transient int port = -1; // 0xffffffff
+
+    @UnsupportedAppUsage
+    private transient java.lang.String query;
+
+    private transient java.lang.String scheme;
+
+    private transient volatile java.lang.String schemeSpecificPart;
+
+    static final long serialVersionUID = -6052424284110960213L; // 0xac01782e439e49abL
+
+    @UnsupportedAppUsage
+    private volatile java.lang.String string;
+
+    private transient java.lang.String userInfo;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Parser {
+
+        Parser(java.lang.String s) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void fail(java.lang.String reason) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void fail(java.lang.String reason, int p) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void failExpecting(java.lang.String expected, int p)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void failExpecting(java.lang.String expected, java.lang.String prior, int p)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String substring(int start, int end) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private char charAt(int p) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean at(int start, int end, char c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean at(int start, int end, java.lang.String s) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scan(int start, int end, char c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scan(int start, int end, java.lang.String err, java.lang.String stop) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scanEscape(int start, int n, char first) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scan(int start, int n, long lowMask, long highMask)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkChars(
+                int start, int end, long lowMask, long highMask, java.lang.String what)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkChar(int p, long lowMask, long highMask, java.lang.String what)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void parse(boolean rsa) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseHierarchical(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseAuthority(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseServer(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scanByte(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scanIPv4Address(int start, int n, boolean strict)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int takeIPv4Address(int start, int n, java.lang.String expected)
+                throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseIPv4Address(int start, int n) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseHostname(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int parseIPv6Reference(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scanHexPost(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int scanHexSeq(int start, int n) throws java.net.URISyntaxException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String input;
+
+        private int ipv6byteCount = 0; // 0x0
+
+        private boolean requireServerAuthority = false;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/URL.java b/ojluni/annotations/hiddenapi/java/net/URL.java
new file mode 100644
index 0000000..905413c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/URL.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class URL implements java.io.Serializable {
+
+    public URL(java.lang.String protocol, java.lang.String host, int port, java.lang.String file)
+            throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URL(java.lang.String protocol, java.lang.String host, java.lang.String file)
+            throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URL(
+            java.lang.String protocol,
+            java.lang.String host,
+            int port,
+            java.lang.String file,
+            java.net.URLStreamHandler handler)
+            throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URL(java.lang.String spec) throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URL(java.net.URL context, java.lang.String spec) throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URL(java.net.URL context, java.lang.String spec, java.net.URLStreamHandler handler)
+            throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isValidProtocol(java.lang.String protocol) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkSpecifyHandler(java.lang.SecurityManager sm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void set(
+            java.lang.String protocol,
+            java.lang.String host,
+            int port,
+            java.lang.String file,
+            java.lang.String ref) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void set(
+            java.lang.String protocol,
+            java.lang.String host,
+            int port,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String ref) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getQuery() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPath() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getUserInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAuthority() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDefaultPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getProtocol() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHost() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getFile() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRef() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean sameFile(java.net.URL other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toExternalForm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI toURI() throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URLConnection openConnection() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URLConnection openConnection(java.net.Proxy proxy) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream openStream() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object getContent() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object getContent(java.lang.Class[] classes) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory fac) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.net.URLStreamHandler getURLStreamHandler(java.lang.String protocol) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URLStreamHandler createBuiltinHandler(java.lang.String protocol)
+            throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException,
+                    java.lang.InstantiationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Set<java.lang.String> createBuiltinHandlerClassNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readResolve() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.net.URL setDeserializedFields(java.net.URLStreamHandler handler) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.net.URL fabricateNewURL() throws java.io.InvalidObjectException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isBuiltinStreamHandler(java.lang.String handlerClassName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void resetState() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setSerializedHashCode(int hc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.util.Set<java.lang.String> BUILTIN_HANDLER_CLASS_NAMES;
+
+    static {
+        BUILTIN_HANDLER_CLASS_NAMES = null;
+    }
+
+    private java.lang.String authority;
+
+    @UnsupportedAppUsage
+    static java.net.URLStreamHandlerFactory factory;
+
+    private java.lang.String file;
+
+    @UnsupportedAppUsage
+    transient java.net.URLStreamHandler handler;
+
+    @UnsupportedAppUsage
+    static java.util.Hashtable<java.lang.String, java.net.URLStreamHandler> handlers;
+
+    private int hashCode = -1; // 0xffffffff
+
+    private java.lang.String host;
+
+    transient java.net.InetAddress hostAddress;
+
+    private transient java.lang.String path;
+
+    private int port = -1; // 0xffffffff
+
+    @UnsupportedAppUsage
+    private java.lang.String protocol;
+
+    private static final java.lang.String protocolPathProp = "java.protocol.handler.pkgs";
+
+    private transient java.lang.String query;
+
+    private java.lang.String ref;
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    static final long serialVersionUID = -7627629688361524110L; // 0x962537361afce472L
+
+    private static java.lang.Object streamHandlerLock;
+
+    private transient java.lang.String userInfo;
+}
diff --git a/ojluni/annotations/hiddenapi/java/net/URLClassLoader.java b/ojluni/annotations/hiddenapi/java/net/URLClassLoader.java
new file mode 100644
index 0000000..105b0c7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/net/URLClassLoader.java
@@ -0,0 +1,143 @@
+/*
+ * 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.net;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class URLClassLoader extends java.security.SecureClassLoader implements java.io.Closeable {
+
+    public URLClassLoader(java.net.URL[] urls, java.lang.ClassLoader parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    URLClassLoader(
+            java.net.URL[] urls,
+            java.lang.ClassLoader parent,
+            java.security.AccessControlContext acc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URLClassLoader(java.net.URL[] urls) {
+        throw new RuntimeException("Stub!");
+    }
+
+    URLClassLoader(java.net.URL[] urls, java.security.AccessControlContext acc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URLClassLoader(
+            java.net.URL[] urls,
+            java.lang.ClassLoader parent,
+            java.net.URLStreamHandlerFactory factory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.io.InputStream getResourceAsStream(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void addURL(java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL[] getURLs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Class<?> findClass(java.lang.String name)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Package getAndVerifyPackage(
+            java.lang.String pkgname, java.util.jar.Manifest man, java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void definePackageInternal(
+            java.lang.String pkgname, java.util.jar.Manifest man, java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Class<?> defineClass(java.lang.String name, sun.misc.Resource res)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Package definePackage(
+            java.lang.String name, java.util.jar.Manifest man, java.net.URL url)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isSealed(java.lang.String name, java.util.jar.Manifest man) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL findResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.net.URL> findResources(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.security.PermissionCollection getPermissions(
+            java.security.CodeSource codesource) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URLClassLoader newInstance(
+            java.net.URL[] urls, java.lang.ClassLoader parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URLClassLoader newInstance(java.net.URL[] urls) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final java.security.AccessControlContext acc;
+
+    {
+        acc = null;
+    }
+
+    private java.util.WeakHashMap<java.io.Closeable, java.lang.Void> closeables;
+
+    @UnsupportedAppUsage
+    private final sun.misc.URLClassPath ucp;
+
+    {
+        ucp = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/Buffer.java b/ojluni/annotations/hiddenapi/java/nio/Buffer.java
new file mode 100644
index 0000000..cbcd8c1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/Buffer.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.nio;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Buffer {
+
+    Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int capacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int position() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer position(int newPosition) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int limit() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer limit(int newLimit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer mark() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer flip() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.Buffer rewind() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int remaining() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean hasRemaining() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract boolean isReadOnly();
+
+    public abstract boolean hasArray();
+
+    public abstract java.lang.Object array();
+
+    public abstract int arrayOffset();
+
+    public abstract boolean isDirect();
+
+    final int nextGetIndex() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int nextGetIndex(int nb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int nextPutIndex() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int nextPutIndex(int nb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int checkIndex(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int checkIndex(int i, int nb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int markValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void truncate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void discardMark() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void checkBounds(int off, int len, int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getElementSizeShift() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int SPLITERATOR_CHARACTERISTICS = 16464; // 0x4050
+
+    @UnsupportedAppUsage
+    final int _elementSizeShift;
+
+    {
+        _elementSizeShift = 0;
+    }
+
+    @UnsupportedAppUsage
+    long address;
+
+    @UnsupportedAppUsage
+    private int capacity;
+
+    @UnsupportedAppUsage
+    private int limit;
+
+    private int mark = -1; // 0xffffffff
+
+    @UnsupportedAppUsage
+    int position = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java b/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java
new file mode 100644
index 0000000..65b6d58
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ByteBuffer extends java.nio.Buffer
+        implements java.lang.Comparable<java.nio.ByteBuffer> {
+
+    ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
+        super(0, 0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    ByteBuffer(int mark, int pos, int lim, int cap) {
+        super(0, 0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.ByteBuffer allocateDirect(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.ByteBuffer allocate(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.ByteBuffer wrap(byte[] array, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.ByteBuffer wrap(byte[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.ByteBuffer slice();
+
+    public abstract java.nio.ByteBuffer duplicate();
+
+    public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+
+    public abstract byte get();
+
+    public abstract java.nio.ByteBuffer put(byte b);
+
+    public abstract byte get(int index);
+
+    public abstract java.nio.ByteBuffer put(int index, byte b);
+
+    public java.nio.ByteBuffer get(byte[] dst, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer get(byte[] dst) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer put(java.nio.ByteBuffer src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer put(byte[] src, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer put(byte[] src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean hasArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte[] array() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int arrayOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.ByteBuffer compact();
+
+    public abstract boolean isDirect();
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object ob) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean equals(byte x, byte y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.nio.ByteBuffer that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compare(byte x, byte y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteOrder order() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer order(java.nio.ByteOrder bo) {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract byte _get(int i);
+
+    abstract void _put(int i, byte b);
+
+    public abstract char getChar();
+
+    public abstract java.nio.ByteBuffer putChar(char value);
+
+    public abstract char getChar(int index);
+
+    abstract char getCharUnchecked(int index);
+
+    abstract void getUnchecked(int pos, char[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putChar(int index, char value);
+
+    abstract void putCharUnchecked(int index, char value);
+
+    abstract void putUnchecked(int pos, char[] dst, int srcOffset, int length);
+
+    public abstract java.nio.CharBuffer asCharBuffer();
+
+    public abstract short getShort();
+
+    public abstract java.nio.ByteBuffer putShort(short value);
+
+    public abstract short getShort(int index);
+
+    abstract short getShortUnchecked(int index);
+
+    abstract void getUnchecked(int pos, short[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putShort(int index, short value);
+
+    abstract void putShortUnchecked(int index, short value);
+
+    abstract void putUnchecked(int pos, short[] dst, int srcOffset, int length);
+
+    public abstract java.nio.ShortBuffer asShortBuffer();
+
+    public abstract int getInt();
+
+    public abstract java.nio.ByteBuffer putInt(int value);
+
+    public abstract int getInt(int index);
+
+    abstract int getIntUnchecked(int index);
+
+    abstract void getUnchecked(int pos, int[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putInt(int index, int value);
+
+    abstract void putIntUnchecked(int index, int value);
+
+    abstract void putUnchecked(int pos, int[] dst, int srcOffset, int length);
+
+    public abstract java.nio.IntBuffer asIntBuffer();
+
+    public abstract long getLong();
+
+    public abstract java.nio.ByteBuffer putLong(long value);
+
+    public abstract long getLong(int index);
+
+    abstract long getLongUnchecked(int index);
+
+    abstract void getUnchecked(int pos, long[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putLong(int index, long value);
+
+    abstract void putLongUnchecked(int index, long value);
+
+    abstract void putUnchecked(int pos, long[] dst, int srcOffset, int length);
+
+    public abstract java.nio.LongBuffer asLongBuffer();
+
+    public abstract float getFloat();
+
+    public abstract java.nio.ByteBuffer putFloat(float value);
+
+    public abstract float getFloat(int index);
+
+    abstract float getFloatUnchecked(int index);
+
+    abstract void getUnchecked(int pos, float[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putFloat(int index, float value);
+
+    abstract void putFloatUnchecked(int index, float value);
+
+    abstract void putUnchecked(int pos, float[] dst, int srcOffset, int length);
+
+    public abstract java.nio.FloatBuffer asFloatBuffer();
+
+    public abstract double getDouble();
+
+    public abstract java.nio.ByteBuffer putDouble(double value);
+
+    public abstract double getDouble(int index);
+
+    abstract double getDoubleUnchecked(int index);
+
+    abstract void getUnchecked(int pos, double[] dst, int dstOffset, int length);
+
+    public abstract java.nio.ByteBuffer putDouble(int index, double value);
+
+    abstract void putDoubleUnchecked(int index, double value);
+
+    abstract void putUnchecked(int pos, double[] dst, int srcOffset, int length);
+
+    public abstract java.nio.DoubleBuffer asDoubleBuffer();
+
+    public boolean isAccessible() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setAccessible(boolean value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean bigEndian = true;
+
+    @UnsupportedAppUsage
+    final byte[] hb;
+
+    {
+        hb = new byte[0];
+    }
+
+    @UnsupportedAppUsage
+    boolean isReadOnly;
+
+    boolean nativeByteOrder;
+
+    @UnsupportedAppUsage
+    final int offset;
+
+    {
+        offset = 0;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java b/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java
new file mode 100644
index 0000000..891e8c3
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharBuffer extends java.nio.Buffer
+        implements java.lang.Comparable<java.nio.CharBuffer>,
+                java.lang.Appendable,
+                java.lang.CharSequence,
+                java.lang.Readable {
+
+    CharBuffer(int mark, int pos, int lim, int cap, char[] hb, int offset) {
+        super(0, 0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    CharBuffer(int mark, int pos, int lim, int cap) {
+        super(0, 0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.CharBuffer allocate(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.CharBuffer wrap(char[] array, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.CharBuffer wrap(char[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(java.nio.CharBuffer target) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.CharBuffer wrap(java.lang.CharSequence csq, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.CharBuffer wrap(java.lang.CharSequence csq) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.CharBuffer slice();
+
+    public abstract java.nio.CharBuffer duplicate();
+
+    public abstract java.nio.CharBuffer asReadOnlyBuffer();
+
+    public abstract char get();
+
+    public abstract java.nio.CharBuffer put(char c);
+
+    public abstract char get(int index);
+
+    abstract char getUnchecked(int index);
+
+    public abstract java.nio.CharBuffer put(int index, char c);
+
+    public java.nio.CharBuffer get(char[] dst, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer get(char[] dst) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer put(java.nio.CharBuffer src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer put(char[] src, int offset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.CharBuffer put(char[] src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer put(java.lang.String src, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.CharBuffer put(java.lang.String src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean hasArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final char[] array() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int arrayOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.CharBuffer compact();
+
+    public abstract boolean isDirect();
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object ob) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean equals(char x, char y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.nio.CharBuffer that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compare(char x, char y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    abstract java.lang.String toString(int start, int end);
+
+    public final int length() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final char charAt(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.CharBuffer subSequence(int start, int end);
+
+    public java.nio.CharBuffer append(java.lang.CharSequence csq) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer append(java.lang.CharSequence csq, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.CharBuffer append(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.nio.ByteOrder order();
+
+    public java.util.stream.IntStream chars() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final char[] hb;
+
+    {
+        hb = new char[0];
+    }
+
+    boolean isReadOnly;
+
+    final int offset;
+
+    {
+        offset = 0;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java b/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java
new file mode 100644
index 0000000..1d5e04f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 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.nio;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DirectByteBuffer extends java.nio.MappedByteBuffer implements sun.nio.ch.DirectBuffer {
+
+    DirectByteBuffer(int capacity, java.nio.DirectByteBuffer.MemoryRef memoryRef) {
+        super(0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private DirectByteBuffer(long addr, int cap) {
+        super(0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    public DirectByteBuffer(
+            int cap,
+            long addr,
+            java.io.FileDescriptor fd,
+            java.lang.Runnable unmapper,
+            boolean isReadOnly) {
+        super(0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    DirectByteBuffer(
+            java.nio.DirectByteBuffer.MemoryRef memoryRef,
+            int mark,
+            int pos,
+            int lim,
+            int cap,
+            int off) {
+        super(0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    DirectByteBuffer(
+            java.nio.DirectByteBuffer.MemoryRef memoryRef,
+            int mark,
+            int pos,
+            int lim,
+            int cap,
+            int off,
+            boolean isReadOnly) {
+        super(0, 0, 0, 0);
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.Object attachment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public final sun.misc.Cleaner cleaner() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer slice() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer duplicate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer asReadOnlyBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final long address() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long ix(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte get(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte get() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte get(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer get(byte[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer put(long a, byte x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer put(java.nio.ByteBuffer src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer put(byte x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer put(int i, byte x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer put(byte[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer compact() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isDirect() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isReadOnly() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final byte _get(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void _put(int i, byte b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final char getChar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final char getChar(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    char getCharUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putChar(long a, char x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putChar(char x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putChar(int i, char x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void putCharUnchecked(int i, char x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void putUnchecked(int pos, char[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.CharBuffer asCharBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private short getShort(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final short getShort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final short getShort(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    short getShortUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putShort(long a, short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putShort(short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putShort(int i, short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void putShortUnchecked(int i, short x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void putUnchecked(int pos, short[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ShortBuffer asShortBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getInt(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getInt() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getInt(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int getIntUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putInt(long a, int x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putInt(int x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putInt(int i, int x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putIntUnchecked(int i, int x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.IntBuffer asIntBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long getLong(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final long getLong() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final long getLong(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final long getLongUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putLong(long a, long x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putLong(long x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putLong(int i, long x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putLongUnchecked(int i, long x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.LongBuffer asLongBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private float getFloat(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final float getFloat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final float getFloat(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final float getFloatUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putFloat(long a, float x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putFloat(float x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putFloat(int i, float x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putFloatUnchecked(int i, float x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.FloatBuffer asFloatBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private double getDouble(long a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final double getDouble() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final double getDouble(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final double getDoubleUnchecked(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.ByteBuffer putDouble(long a, double x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putDouble(double x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer putDouble(int i, double x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putDoubleUnchecked(int i, double x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.DoubleBuffer asDoubleBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isAccessible() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setAccessible(boolean value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final sun.misc.Cleaner cleaner;
+
+    {
+        cleaner = null;
+    }
+
+    final java.nio.DirectByteBuffer.MemoryRef memoryRef;
+
+    {
+        memoryRef = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class MemoryRef {
+
+        MemoryRef(int capacity) {
+            throw new RuntimeException("Stub!");
+        }
+
+        MemoryRef(long allocatedAddress, java.lang.Object originalBufferObject) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void free() {
+            throw new RuntimeException("Stub!");
+        }
+
+        long allocatedAddress;
+
+        byte[] buffer;
+
+        boolean isAccessible;
+
+        boolean isFreed;
+
+        final int offset;
+
+        {
+            offset = 0;
+        }
+
+        final java.lang.Object originalBufferObject;
+
+        {
+            originalBufferObject = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java b/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java
new file mode 100644
index 0000000..daaa265
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.nio.charset;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Charset implements java.lang.Comparable<java.nio.charset.Charset> {
+
+    protected Charset(java.lang.String canonicalName, java.lang.String[] aliases) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean atBugLevel(java.lang.String bl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkName(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void cache(java.lang.String charsetName, java.nio.charset.Charset cs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Iterator<java.nio.charset.spi.CharsetProvider> providers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.nio.charset.Charset lookupViaProviders(java.lang.String charsetName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.nio.charset.Charset lookup(java.lang.String charsetName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.nio.charset.Charset lookup2(java.lang.String charsetName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isSupported(java.lang.String charsetName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.charset.Charset forName(java.lang.String charsetName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.charset.Charset forNameUEE(java.lang.String charsetName)
+            throws java.io.UnsupportedEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void put(
+            java.util.Iterator<java.nio.charset.Charset> i,
+            java.util.Map<java.lang.String, java.nio.charset.Charset> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.SortedMap<java.lang.String, java.nio.charset.Charset>
+            availableCharsets() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.charset.Charset defaultCharset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String name() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.util.Set<java.lang.String> aliases() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String displayName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isRegistered() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String displayName(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract boolean contains(java.nio.charset.Charset cs);
+
+    public abstract java.nio.charset.CharsetDecoder newDecoder();
+
+    public abstract java.nio.charset.CharsetEncoder newEncoder();
+
+    public boolean canEncode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.CharBuffer decode(java.nio.ByteBuffer bb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer encode(java.nio.CharBuffer cb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.ByteBuffer encode(java.lang.String str) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int compareTo(java.nio.charset.Charset that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean equals(java.lang.Object ob) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Set<java.lang.String> aliasSet;
+
+    private final java.lang.String[] aliases;
+
+    {
+        aliases = new java.lang.String[0];
+    }
+
+    private static volatile java.lang.String bugLevel;
+
+    private static volatile java.util.Map.Entry<java.lang.String, java.nio.charset.Charset> cache1;
+
+    private static final java.util.HashMap<java.lang.String, java.nio.charset.Charset> cache2;
+
+    static {
+        cache2 = null;
+    }
+
+    @UnsupportedAppUsage
+    private static java.nio.charset.Charset defaultCharset;
+
+    private static java.lang.ThreadLocal<java.lang.ThreadLocal<?>> gate;
+
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java b/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java
new file mode 100644
index 0000000..f053cae
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharsetEncoder {
+
+    protected CharsetEncoder(
+            java.nio.charset.Charset cs,
+            float averageBytesPerChar,
+            float maxBytesPerChar,
+            byte[] replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    CharsetEncoder(
+            java.nio.charset.Charset cs,
+            float averageBytesPerChar,
+            float maxBytesPerChar,
+            byte[] replacement,
+            boolean trusted) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CharsetEncoder(
+            java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.Charset charset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte[] replacement() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CharsetEncoder replaceWith(byte[] newReplacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void implReplaceWith(byte[] newReplacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLegalReplacement(byte[] repl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.charset.CodingErrorAction malformedInputAction() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CharsetEncoder onMalformedInput(
+            java.nio.charset.CodingErrorAction newAction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void implOnMalformedInput(java.nio.charset.CodingErrorAction newAction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.charset.CodingErrorAction unmappableCharacterAction() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CharsetEncoder onUnmappableCharacter(
+            java.nio.charset.CodingErrorAction newAction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final float averageBytesPerChar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final float maxBytesPerChar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CoderResult encode(
+            java.nio.CharBuffer in, java.nio.ByteBuffer out, boolean endOfInput) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CoderResult flush(java.nio.ByteBuffer out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.nio.charset.CoderResult implFlush(java.nio.ByteBuffer out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.nio.charset.CharsetEncoder reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void implReset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract java.nio.charset.CoderResult encodeLoop(
+            java.nio.CharBuffer in, java.nio.ByteBuffer out);
+
+    public final java.nio.ByteBuffer encode(java.nio.CharBuffer in)
+            throws java.nio.charset.CharacterCodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private boolean canEncode(java.nio.CharBuffer cb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canEncode(char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canEncode(java.lang.CharSequence cs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void throwIllegalStateException(int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int ST_CODING = 1; // 0x1
+
+    private static final int ST_END = 2; // 0x2
+
+    private static final int ST_FLUSHED = 3; // 0x3
+
+    private static final int ST_RESET = 0; // 0x0
+
+    private final float averageBytesPerChar;
+
+    {
+        averageBytesPerChar = 0;
+    }
+
+    private java.lang.ref.WeakReference<java.nio.charset.CharsetDecoder> cachedDecoder;
+
+    private final java.nio.charset.Charset charset;
+
+    {
+        charset = null;
+    }
+
+    private java.nio.charset.CodingErrorAction malformedInputAction;
+
+    private final float maxBytesPerChar;
+
+    {
+        maxBytesPerChar = 0;
+    }
+
+    private byte[] replacement;
+
+    private int state = 0; // 0x0
+
+    private static java.lang.String[] stateNames;
+
+    private java.nio.charset.CodingErrorAction unmappableCharacterAction;
+}
diff --git a/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java b/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java
new file mode 100644
index 0000000..d3e6a42
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class FileTreeWalker implements java.io.Closeable {
+
+    FileTreeWalker(java.util.Collection<java.nio.file.FileVisitOption> options, int maxDepth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.file.attribute.BasicFileAttributes getAttributes(
+            java.nio.file.Path file, boolean canUseCached) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean wouldLoop(java.nio.file.Path dir, java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.nio.file.FileTreeWalker.Event visit(
+            java.nio.file.Path entry, boolean ignoreSecurityException, boolean canUseCached) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.nio.file.FileTreeWalker.Event walk(java.nio.file.Path file) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.nio.file.FileTreeWalker.Event next() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void pop() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void skipRemainingSiblings() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isOpen() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean closed;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private final boolean followLinks;
+
+    {
+        followLinks = false;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private final java.nio.file.LinkOption[] linkOptions;
+
+    {
+        linkOptions = new java.nio.file.LinkOption[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private final int maxDepth;
+
+    {
+        maxDepth = 0;
+    }
+
+    private final java.util.ArrayDeque<java.nio.file.FileTreeWalker.DirectoryNode> stack;
+
+    {
+        stack = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DirectoryNode {
+
+        DirectoryNode(
+                java.nio.file.Path dir,
+                java.lang.Object key,
+                java.nio.file.DirectoryStream<java.nio.file.Path> stream) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.nio.file.Path directory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object key() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.nio.file.DirectoryStream<java.nio.file.Path> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.Iterator<java.nio.file.Path> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void skip() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean skipped() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.nio.file.Path dir;
+
+        {
+            dir = null;
+        }
+
+        private final java.util.Iterator<java.nio.file.Path> iterator;
+
+        {
+            iterator = null;
+        }
+
+        private final java.lang.Object key;
+
+        {
+            key = null;
+        }
+
+        private boolean skipped;
+
+        private final java.nio.file.DirectoryStream<java.nio.file.Path> stream;
+
+        {
+            stream = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class Event {
+
+        private Event(
+                java.nio.file.FileTreeWalker.EventType type,
+                java.nio.file.Path file,
+                java.nio.file.attribute.BasicFileAttributes attrs,
+                java.io.IOException ioe) {
+            throw new RuntimeException("Stub!");
+        }
+
+        Event(
+                java.nio.file.FileTreeWalker.EventType type,
+                java.nio.file.Path file,
+                java.nio.file.attribute.BasicFileAttributes attrs) {
+            throw new RuntimeException("Stub!");
+        }
+
+        Event(
+                java.nio.file.FileTreeWalker.EventType type,
+                java.nio.file.Path file,
+                java.io.IOException ioe) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.nio.file.FileTreeWalker.EventType type() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.nio.file.Path file() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.nio.file.attribute.BasicFileAttributes attributes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.io.IOException ioeException() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.nio.file.attribute.BasicFileAttributes attrs;
+
+        {
+            attrs = null;
+        }
+
+        private final java.nio.file.Path file;
+
+        {
+            file = null;
+        }
+
+        private final java.io.IOException ioe;
+
+        {
+            ioe = null;
+        }
+
+        private final java.nio.file.FileTreeWalker.EventType type;
+
+        {
+            type = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static enum EventType {
+        START_DIRECTORY,
+        END_DIRECTORY,
+        ENTRY;
+
+        private EventType() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java b/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java
new file mode 100644
index 0000000..2dba7cd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java
@@ -0,0 +1,170 @@
+/*
+ * 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.security;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class KeyPairGenerator extends java.security.KeyPairGeneratorSpi {
+
+    protected KeyPairGenerator(java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAlgorithm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.security.KeyPairGenerator getInstance(
+            sun.security.jca.GetInstance.Instance instance, java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyPairGenerator getInstance(java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyPairGenerator getInstance(
+            java.lang.String algorithm, java.lang.String provider)
+            throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyPairGenerator getInstance(
+            java.lang.String algorithm, java.security.Provider provider)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.Provider getProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void disableFailover() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void initialize(int keysize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void initialize(int keysize, java.security.SecureRandom random) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void initialize(java.security.spec.AlgorithmParameterSpec params)
+            throws java.security.InvalidAlgorithmParameterException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void initialize(
+            java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random)
+            throws java.security.InvalidAlgorithmParameterException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.KeyPair genKeyPair() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.KeyPair generateKeyPair() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.lang.String algorithm;
+
+    {
+        algorithm = null;
+    }
+
+    java.security.Provider provider;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class Delegate extends java.security.KeyPairGenerator {
+
+        Delegate(java.security.KeyPairGeneratorSpi spi, java.lang.String algorithm) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        Delegate(
+                sun.security.jca.GetInstance.Instance instance,
+                java.util.Iterator<java.security.Provider.Service> serviceIterator,
+                java.lang.String algorithm) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.security.KeyPairGeneratorSpi nextSpi(
+                java.security.KeyPairGeneratorSpi oldSpi, boolean reinit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void disableFailover() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void initialize(int keysize, java.security.SecureRandom random) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void initialize(
+                java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random)
+                throws java.security.InvalidAlgorithmParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.KeyPair generateKeyPair() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int I_NONE = 1; // 0x1
+
+        private static final int I_PARAMS = 3; // 0x3
+
+        private static final int I_SIZE = 2; // 0x2
+
+        private int initKeySize;
+
+        private java.security.spec.AlgorithmParameterSpec initParams;
+
+        private java.security.SecureRandom initRandom;
+
+        private int initType;
+
+        private final java.lang.Object lock;
+
+        {
+            lock = null;
+        }
+
+        private java.util.Iterator<java.security.Provider.Service> serviceIterator;
+
+        private volatile java.security.KeyPairGeneratorSpi spi;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/security/KeyStore.java b/ojluni/annotations/hiddenapi/java/security/KeyStore.java
new file mode 100644
index 0000000..ae64169
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/security/KeyStore.java
@@ -0,0 +1,538 @@
+/*
+ * 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.security;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class KeyStore {
+
+    protected KeyStore(
+            java.security.KeyStoreSpi keyStoreSpi,
+            java.security.Provider provider,
+            java.lang.String type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyStore getInstance(java.lang.String type)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyStore getInstance(
+            java.lang.String type, java.lang.String provider)
+            throws java.security.KeyStoreException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.KeyStore getInstance(
+            java.lang.String type, java.security.Provider provider)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String getDefaultType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.Provider getProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.Key getKey(java.lang.String alias, char[] password)
+            throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException,
+                    java.security.UnrecoverableKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.cert.Certificate[] getCertificateChain(java.lang.String alias)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.cert.Certificate getCertificate(java.lang.String alias)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.util.Date getCreationDate(java.lang.String alias)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setKeyEntry(
+            java.lang.String alias,
+            java.security.Key key,
+            char[] password,
+            java.security.cert.Certificate[] chain)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setKeyEntry(
+            java.lang.String alias, byte[] key, java.security.cert.Certificate[] chain)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setCertificateEntry(
+            java.lang.String alias, java.security.cert.Certificate cert)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void deleteEntry(java.lang.String alias) throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.util.Enumeration<java.lang.String> aliases()
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean containsAlias(java.lang.String alias)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int size() throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isKeyEntry(java.lang.String alias) throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isCertificateEntry(java.lang.String alias)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getCertificateAlias(java.security.cert.Certificate cert)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void store(java.io.OutputStream stream, char[] password)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.KeyStoreException, java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void store(java.security.KeyStore.LoadStoreParameter param)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.KeyStoreException, java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void load(java.io.InputStream stream, char[] password)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void load(java.security.KeyStore.LoadStoreParameter param)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.KeyStore.Entry getEntry(
+            java.lang.String alias, java.security.KeyStore.ProtectionParameter protParam)
+            throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException,
+                    java.security.UnrecoverableEntryException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setEntry(
+            java.lang.String alias,
+            java.security.KeyStore.Entry entry,
+            java.security.KeyStore.ProtectionParameter protParam)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean entryInstanceOf(
+            java.lang.String alias,
+            java.lang.Class<? extends java.security.KeyStore.Entry> entryClass)
+            throws java.security.KeyStoreException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String KEYSTORE_TYPE = "keystore.type";
+
+    private boolean initialized = false;
+
+    @UnsupportedAppUsage
+    private java.security.KeyStoreSpi keyStoreSpi;
+
+    private java.security.Provider provider;
+
+    private java.lang.String type;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public abstract static class Builder {
+
+        protected Builder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public abstract java.security.KeyStore getKeyStore() throws java.security.KeyStoreException;
+
+        public abstract java.security.KeyStore.ProtectionParameter getProtectionParameter(
+                java.lang.String alias) throws java.security.KeyStoreException;
+
+        public static java.security.KeyStore.Builder newInstance(
+                java.security.KeyStore keyStore,
+                java.security.KeyStore.ProtectionParameter protectionParameter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.security.KeyStore.Builder newInstance(
+                java.lang.String type,
+                java.security.Provider provider,
+                java.io.File file,
+                java.security.KeyStore.ProtectionParameter protection) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.security.KeyStore.Builder newInstance(
+                java.lang.String type,
+                java.security.Provider provider,
+                java.security.KeyStore.ProtectionParameter protection) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final int MAX_CALLBACK_TRIES = 3; // 0x3
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private static final class FileBuilder extends java.security.KeyStore.Builder {
+
+            FileBuilder(
+                    java.lang.String type,
+                    java.security.Provider provider,
+                    java.io.File file,
+                    java.security.KeyStore.ProtectionParameter protection,
+                    java.security.AccessControlContext context) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public synchronized java.security.KeyStore getKeyStore()
+                    throws java.security.KeyStoreException {
+                throw new RuntimeException("Stub!");
+            }
+
+            public synchronized java.security.KeyStore.ProtectionParameter getProtectionParameter(
+                    java.lang.String alias) {
+                throw new RuntimeException("Stub!");
+            }
+
+            private final java.security.AccessControlContext context;
+
+            {
+                context = null;
+            }
+
+            private final java.io.File file;
+
+            {
+                file = null;
+            }
+
+            private java.security.KeyStore.ProtectionParameter keyProtection;
+
+            private java.security.KeyStore keyStore;
+
+            private java.lang.Throwable oldException;
+
+            private java.security.KeyStore.ProtectionParameter protection;
+
+            private final java.security.Provider provider;
+
+            {
+                provider = null;
+            }
+
+            private final java.lang.String type;
+
+            {
+                type = null;
+            }
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class CallbackHandlerProtection
+            implements java.security.KeyStore.ProtectionParameter {
+
+        public CallbackHandlerProtection(javax.security.auth.callback.CallbackHandler handler) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public javax.security.auth.callback.CallbackHandler getCallbackHandler() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final javax.security.auth.callback.CallbackHandler handler;
+
+        {
+            handler = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface Entry {
+
+        public default java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        public static interface Attribute {
+
+            public java.lang.String getName();
+
+            public java.lang.String getValue();
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface LoadStoreParameter {
+
+        public java.security.KeyStore.ProtectionParameter getProtectionParameter();
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class PasswordProtection
+            implements java.security.KeyStore.ProtectionParameter, javax.security.auth.Destroyable {
+
+        public PasswordProtection(char[] password) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public PasswordProtection(
+                char[] password,
+                java.lang.String protectionAlgorithm,
+                java.security.spec.AlgorithmParameterSpec protectionParameters) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String getProtectionAlgorithm() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.spec.AlgorithmParameterSpec getProtectionParameters() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public synchronized char[] getPassword() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public synchronized void destroy() throws javax.security.auth.DestroyFailedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public synchronized boolean isDestroyed() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private volatile boolean destroyed = false;
+
+        private final char[] password;
+
+        {
+            password = new char[0];
+        }
+
+        private final java.lang.String protectionAlgorithm;
+
+        {
+            protectionAlgorithm = null;
+        }
+
+        private final java.security.spec.AlgorithmParameterSpec protectionParameters;
+
+        {
+            protectionParameters = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class PrivateKeyEntry implements java.security.KeyStore.Entry {
+
+        public PrivateKeyEntry(
+                java.security.PrivateKey privateKey, java.security.cert.Certificate[] chain) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public PrivateKeyEntry(
+                java.security.PrivateKey privateKey,
+                java.security.cert.Certificate[] chain,
+                java.util.Set<java.security.KeyStore.Entry.Attribute> attributes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.PrivateKey getPrivateKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.cert.Certificate[] getCertificateChain() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.cert.Certificate getCertificate() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Set<java.security.KeyStore.Entry.Attribute> attributes;
+
+        {
+            attributes = null;
+        }
+
+        private final java.security.cert.Certificate[] chain;
+
+        {
+            chain = new java.security.cert.Certificate[0];
+        }
+
+        private final java.security.PrivateKey privKey;
+
+        {
+            privKey = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface ProtectionParameter {}
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class SecretKeyEntry implements java.security.KeyStore.Entry {
+
+        public SecretKeyEntry(javax.crypto.SecretKey secretKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public SecretKeyEntry(
+                javax.crypto.SecretKey secretKey,
+                java.util.Set<java.security.KeyStore.Entry.Attribute> attributes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public javax.crypto.SecretKey getSecretKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Set<java.security.KeyStore.Entry.Attribute> attributes;
+
+        {
+            attributes = null;
+        }
+
+        private final javax.crypto.SecretKey sKey;
+
+        {
+            sKey = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SimpleLoadStoreParameter implements java.security.KeyStore.LoadStoreParameter {
+
+        SimpleLoadStoreParameter(java.security.KeyStore.ProtectionParameter protection) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.KeyStore.ProtectionParameter getProtectionParameter() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.security.KeyStore.ProtectionParameter protection;
+
+        {
+            protection = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class TrustedCertificateEntry implements java.security.KeyStore.Entry {
+
+        public TrustedCertificateEntry(java.security.cert.Certificate trustedCert) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public TrustedCertificateEntry(
+                java.security.cert.Certificate trustedCert,
+                java.util.Set<java.security.KeyStore.Entry.Attribute> attributes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.cert.Certificate getTrustedCertificate() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Set<java.security.KeyStore.Entry.Attribute> attributes;
+
+        {
+            attributes = null;
+        }
+
+        private final java.security.cert.Certificate cert;
+
+        {
+            cert = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/security/Signature.java b/ojluni/annotations/hiddenapi/java/security/Signature.java
new file mode 100644
index 0000000..a249f65
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/security/Signature.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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.security;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Signature extends java.security.SignatureSpi {
+
+    protected Signature(java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Signature getInstance(java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.security.Signature getInstance(
+            sun.security.jca.GetInstance.Instance instance, java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isSpi(java.security.Provider.Service s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Signature getInstance(
+            java.lang.String algorithm, java.lang.String provider)
+            throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Signature getInstance(
+            java.lang.String algorithm, java.security.Provider provider)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.security.Signature getInstanceRSA(java.security.Provider p)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.Provider getProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void chooseFirstProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void initVerify(java.security.PublicKey publicKey)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void initVerify(java.security.cert.Certificate certificate)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void initSign(java.security.PrivateKey privateKey)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void initSign(
+            java.security.PrivateKey privateKey, java.security.SecureRandom random)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte[] sign() throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int sign(byte[] outbuf, int offset, int len)
+            throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean verify(byte[] signature) throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean verify(byte[] signature, int offset, int length)
+            throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void update(byte b) throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void update(byte[] data) throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void update(byte[] data, int off, int len)
+            throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void update(java.nio.ByteBuffer data) throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String getAlgorithm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public final void setParameter(java.lang.String param, java.lang.Object value)
+            throws java.security.InvalidParameterException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setParameter(java.security.spec.AlgorithmParameterSpec params)
+            throws java.security.InvalidAlgorithmParameterException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.security.AlgorithmParameters getParameters() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public final java.lang.Object getParameter(java.lang.String param)
+            throws java.security.InvalidParameterException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() throws java.lang.CloneNotSupportedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.SignatureSpi getCurrentSpi() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
+
+    private static final java.lang.String RSA_SIGNATURE = "NONEwithRSA";
+
+    protected static final int SIGN = 2; // 0x2
+
+    protected static final int UNINITIALIZED = 0; // 0x0
+
+    protected static final int VERIFY = 3; // 0x3
+
+    private java.lang.String algorithm;
+
+    java.security.Provider provider;
+
+    private static final java.util.List<sun.security.jca.ServiceId> rsaIds;
+
+    static {
+        rsaIds = null;
+    }
+
+    private static final java.util.Map<java.lang.String, java.lang.Boolean> signatureInfo;
+
+    static {
+        signatureInfo = null;
+    }
+
+    protected int state = 0; // 0x0
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CipherAdapter extends java.security.SignatureSpi {
+
+        CipherAdapter(javax.crypto.Cipher cipher) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitVerify(java.security.PublicKey publicKey)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitSign(java.security.PrivateKey privateKey)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitSign(
+                java.security.PrivateKey privateKey, java.security.SecureRandom random)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineUpdate(byte b) throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineUpdate(byte[] b, int off, int len)
+                throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected byte[] engineSign() throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean engineVerify(byte[] sigBytes) throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineSetParameter(java.lang.String param, java.lang.Object value)
+                throws java.security.InvalidParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.lang.Object engineGetParameter(java.lang.String param)
+                throws java.security.InvalidParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final javax.crypto.Cipher cipher;
+
+        {
+            cipher = null;
+        }
+
+        private java.io.ByteArrayOutputStream data;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Delegate extends java.security.Signature {
+
+        Delegate(java.security.SignatureSpi sigSpi, java.lang.String algorithm) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        Delegate(java.lang.String algorithm) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object clone() throws java.lang.CloneNotSupportedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.security.SignatureSpi newInstance(java.security.Provider.Service s)
+                throws java.security.NoSuchAlgorithmException {
+            throw new RuntimeException("Stub!");
+        }
+
+        void chooseFirstProvider() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void chooseProvider(
+                int type, java.security.Key key, java.security.SecureRandom random)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void init(
+                java.security.SignatureSpi spi,
+                int type,
+                java.security.Key key,
+                java.security.SecureRandom random)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitVerify(java.security.PublicKey publicKey)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitSign(java.security.PrivateKey privateKey)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineInitSign(
+                java.security.PrivateKey privateKey, java.security.SecureRandom sr)
+                throws java.security.InvalidKeyException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineUpdate(byte b) throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineUpdate(byte[] b, int off, int len)
+                throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineUpdate(java.nio.ByteBuffer data) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected byte[] engineSign() throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected int engineSign(byte[] outbuf, int offset, int len)
+                throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean engineVerify(byte[] sigBytes) throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+                throws java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineSetParameter(java.lang.String param, java.lang.Object value)
+                throws java.security.InvalidParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void engineSetParameter(java.security.spec.AlgorithmParameterSpec params)
+                throws java.security.InvalidAlgorithmParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.lang.Object engineGetParameter(java.lang.String param)
+                throws java.security.InvalidParameterException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.security.AlgorithmParameters engineGetParameters() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.SignatureSpi getCurrentSpi() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int I_PRIV = 2; // 0x2
+
+        private static final int I_PRIV_SR = 3; // 0x3
+
+        private static final int I_PUB = 1; // 0x1
+
+        private final java.lang.Object lock;
+
+        {
+            lock = null;
+        }
+
+        private java.security.SignatureSpi sigSpi;
+
+        private static int warnCount = 10; // 0xa
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/security/spec/ECParameterSpec.java b/ojluni/annotations/hiddenapi/java/security/spec/ECParameterSpec.java
new file mode 100644
index 0000000..db13a4b
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/security/spec/ECParameterSpec.java
@@ -0,0 +1,93 @@
+/*
+ * 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.security.spec;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+
+    public ECParameterSpec(
+            java.security.spec.EllipticCurve curve,
+            java.security.spec.ECPoint g,
+            java.math.BigInteger n,
+            int h) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.spec.EllipticCurve getCurve() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.spec.ECPoint getGenerator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getOrder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getCofactor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void setCurveName(java.lang.String curveName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.String getCurveName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.security.spec.EllipticCurve curve;
+
+    {
+        curve = null;
+    }
+
+    private java.lang.String curveName;
+
+    private final java.security.spec.ECPoint g;
+
+    {
+        g = null;
+    }
+
+    private final int h;
+
+    {
+        h = 0;
+    }
+
+    private final java.math.BigInteger n;
+
+    {
+        n = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/text/Collator.java b/ojluni/annotations/hiddenapi/java/text/Collator.java
new file mode 100644
index 0000000..82aa868
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/text/Collator.java
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996-1998 -  All Rights Reserved
+ * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.text;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Collator
+        implements java.util.Comparator<java.lang.Object>, java.lang.Cloneable {
+
+    protected Collator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    Collator(android.icu.text.Collator icuColl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized java.text.Collator getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized java.text.Collator getInstance(java.util.Locale desiredLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract int compare(java.lang.String source, java.lang.String target);
+
+    public int compare(java.lang.Object o1, java.lang.Object o2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.text.CollationKey getCollationKey(java.lang.String source);
+
+    public boolean equals(java.lang.String source, java.lang.String target) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getStrength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setStrength(int newStrength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getDecomposition() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setDecomposition(int decompositionMode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int decompositionMode_Java_ICU(int mode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int decompositionMode_ICU_Java(int mode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract int hashCode();
+
+    public static final int CANONICAL_DECOMPOSITION = 1; // 0x1
+
+    public static final int FULL_DECOMPOSITION = 2; // 0x2
+
+    public static final int IDENTICAL = 3; // 0x3
+
+    public static final int NO_DECOMPOSITION = 0; // 0x0
+
+    public static final int PRIMARY = 0; // 0x0
+
+    public static final int SECONDARY = 1; // 0x1
+
+    public static final int TERTIARY = 2; // 0x2
+
+    @UnsupportedAppUsage
+    android.icu.text.Collator icuColl;
+}
diff --git a/ojluni/annotations/hiddenapi/java/text/DateFormat.java b/ojluni/annotations/hiddenapi/java/text/DateFormat.java
new file mode 100644
index 0000000..7a1973f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/text/DateFormat.java
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.text;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class DateFormat extends java.text.Format {
+
+    protected DateFormat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.StringBuffer format(
+            java.lang.Object obj,
+            java.lang.StringBuffer toAppendTo,
+            java.text.FieldPosition fieldPosition) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.StringBuffer format(
+            java.util.Date date,
+            java.lang.StringBuffer toAppendTo,
+            java.text.FieldPosition fieldPosition);
+
+    public final java.lang.String format(java.util.Date date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date parse(java.lang.String source) throws java.text.ParseException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.util.Date parse(java.lang.String source, java.text.ParsePosition pos);
+
+    public java.lang.Object parseObject(java.lang.String source, java.text.ParsePosition pos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getTimeInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getTimeInstance(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getTimeInstance(int style, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateInstance(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateInstance(int style, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateTimeInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getDateTimeInstance(
+            int dateStyle, int timeStyle, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DateFormat getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final void set24HourTimePref(java.lang.Boolean is24Hour) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCalendar(java.util.Calendar newCalendar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Calendar getCalendar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setNumberFormat(java.text.NumberFormat newNumberFormat) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.text.NumberFormat getNumberFormat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTimeZone(java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.TimeZone getTimeZone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLenient(boolean lenient) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLenient() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.text.DateFormat get(
+            int timeStyle, int dateStyle, int flags, java.util.Locale loc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int AM_PM_FIELD = 14; // 0xe
+
+    public static final int DATE_FIELD = 3; // 0x3
+
+    public static final int DAY_OF_WEEK_FIELD = 9; // 0x9
+
+    public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; // 0xb
+
+    public static final int DAY_OF_YEAR_FIELD = 10; // 0xa
+
+    public static final int DEFAULT = 2; // 0x2
+
+    public static final int ERA_FIELD = 0; // 0x0
+
+    public static final int FULL = 0; // 0x0
+
+    public static final int HOUR0_FIELD = 16; // 0x10
+
+    public static final int HOUR1_FIELD = 15; // 0xf
+
+    public static final int HOUR_OF_DAY0_FIELD = 5; // 0x5
+
+    public static final int HOUR_OF_DAY1_FIELD = 4; // 0x4
+
+    public static final int LONG = 1; // 0x1
+
+    public static final int MEDIUM = 2; // 0x2
+
+    public static final int MILLISECOND_FIELD = 8; // 0x8
+
+    public static final int MINUTE_FIELD = 6; // 0x6
+
+    public static final int MONTH_FIELD = 2; // 0x2
+
+    public static final int SECOND_FIELD = 7; // 0x7
+
+    public static final int SHORT = 3; // 0x3
+
+    public static final int TIMEZONE_FIELD = 17; // 0x11
+
+    public static final int WEEK_OF_MONTH_FIELD = 13; // 0xd
+
+    public static final int WEEK_OF_YEAR_FIELD = 12; // 0xc
+
+    public static final int YEAR_FIELD = 1; // 0x1
+
+    protected java.util.Calendar calendar;
+
+    @UnsupportedAppUsage
+    public static java.lang.Boolean is24Hour;
+
+    protected java.text.NumberFormat numberFormat;
+
+    private static final long serialVersionUID = 7218322306649953788L; // 0x642ca1e4c22615fcL
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Field extends java.text.Format.Field {
+
+        protected Field(java.lang.String name, int calendarField) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.text.DateFormat.Field ofCalendarField(int calendarField) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getCalendarField() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.lang.Object readResolve() throws java.io.InvalidObjectException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static final java.text.DateFormat.Field AM_PM;
+
+        static {
+            AM_PM = null;
+        }
+
+        public static final java.text.DateFormat.Field DAY_OF_MONTH;
+
+        static {
+            DAY_OF_MONTH = null;
+        }
+
+        public static final java.text.DateFormat.Field DAY_OF_WEEK;
+
+        static {
+            DAY_OF_WEEK = null;
+        }
+
+        public static final java.text.DateFormat.Field DAY_OF_WEEK_IN_MONTH;
+
+        static {
+            DAY_OF_WEEK_IN_MONTH = null;
+        }
+
+        public static final java.text.DateFormat.Field DAY_OF_YEAR;
+
+        static {
+            DAY_OF_YEAR = null;
+        }
+
+        public static final java.text.DateFormat.Field ERA;
+
+        static {
+            ERA = null;
+        }
+
+        public static final java.text.DateFormat.Field HOUR0;
+
+        static {
+            HOUR0 = null;
+        }
+
+        public static final java.text.DateFormat.Field HOUR1;
+
+        static {
+            HOUR1 = null;
+        }
+
+        public static final java.text.DateFormat.Field HOUR_OF_DAY0;
+
+        static {
+            HOUR_OF_DAY0 = null;
+        }
+
+        public static final java.text.DateFormat.Field HOUR_OF_DAY1;
+
+        static {
+            HOUR_OF_DAY1 = null;
+        }
+
+        public static final java.text.DateFormat.Field MILLISECOND;
+
+        static {
+            MILLISECOND = null;
+        }
+
+        public static final java.text.DateFormat.Field MINUTE;
+
+        static {
+            MINUTE = null;
+        }
+
+        public static final java.text.DateFormat.Field MONTH;
+
+        static {
+            MONTH = null;
+        }
+
+        public static final java.text.DateFormat.Field SECOND;
+
+        static {
+            SECOND = null;
+        }
+
+        public static final java.text.DateFormat.Field TIME_ZONE;
+
+        static {
+            TIME_ZONE = null;
+        }
+
+        public static final java.text.DateFormat.Field WEEK_OF_MONTH;
+
+        static {
+            WEEK_OF_MONTH = null;
+        }
+
+        public static final java.text.DateFormat.Field WEEK_OF_YEAR;
+
+        static {
+            WEEK_OF_YEAR = null;
+        }
+
+        public static final java.text.DateFormat.Field YEAR;
+
+        static {
+            YEAR = null;
+        }
+
+        private int calendarField;
+
+        private static final java.text.DateFormat.Field[] calendarToFieldMapping;
+
+        static {
+            calendarToFieldMapping = new java.text.DateFormat.Field[0];
+        }
+
+        private static final java.util.Map<java.lang.String, java.text.DateFormat.Field>
+                instanceMap;
+
+        static {
+            instanceMap = null;
+        }
+
+        private static final long serialVersionUID = 7441350119349544720L; // 0x6744fc81f123e710L
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java b/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java
new file mode 100644
index 0000000..52395a9
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java
@@ -0,0 +1,289 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.text;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DecimalFormatSymbols implements java.lang.Cloneable, java.io.Serializable {
+
+    public DecimalFormatSymbols() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DecimalFormatSymbols(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DecimalFormatSymbols getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getZeroDigit() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setZeroDigit(char zeroDigit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getGroupingSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setGroupingSeparator(char groupingSeparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getDecimalSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDecimalSeparator(char decimalSeparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getPerMill() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPerMill(char perMill) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getPercent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.String getPercentString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPercent(char percent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getDigit() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDigit(char digit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getPatternSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setPatternSeparator(char patternSeparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getInfinity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInfinity(java.lang.String infinity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getNaN() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setNaN(java.lang.String NaN) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getMinusSign() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getMinusSignString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMinusSign(char minusSign) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCurrencySymbol() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCurrencySymbol(java.lang.String currency) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getInternationalCurrencySymbol() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInternationalCurrencySymbol(java.lang.String currencyCode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Currency getCurrency() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCurrency(java.util.Currency currency) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char getMonetaryDecimalSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMonetaryDecimalSeparator(char sep) {
+        throw new RuntimeException("Stub!");
+    }
+
+    char getExponentialSymbol() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getExponentSeparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setExponentialSymbol(char exp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setExponentSeparator(java.lang.String exp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initialize(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static char maybeStripMarkers(java.lang.String symbol, char fallback) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected android.icu.text.DecimalFormatSymbols getIcuDecimalFormatSymbols() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected static java.text.DecimalFormatSymbols fromIcuInstance(
+            android.icu.text.DecimalFormatSymbols dfs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String NaN;
+
+    private transient android.icu.text.DecimalFormatSymbols cachedIcuDFS;
+
+    private transient java.util.Currency currency;
+
+    private java.lang.String currencySymbol;
+
+    private static final int currentSerialVersion = 3; // 0x3
+
+    private char decimalSeparator;
+
+    private char digit;
+
+    private char exponential;
+
+    private java.lang.String exponentialSeparator;
+
+    private char groupingSeparator;
+
+    private java.lang.String infinity;
+
+    private java.lang.String intlCurrencySymbol;
+
+    private java.util.Locale locale;
+
+    private char minusSign;
+
+    private char monetarySeparator;
+
+    private char patternSeparator;
+
+    private char perMill;
+
+    private char percent;
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    private int serialVersionOnStream = 3; // 0x3
+
+    static final long serialVersionUID = 5772796243397350300L; // 0x501d17990868939cL
+
+    private char zeroDigit;
+}
diff --git a/ojluni/annotations/hiddenapi/java/text/NumberFormat.java b/ojluni/annotations/hiddenapi/java/text/NumberFormat.java
new file mode 100644
index 0000000..a570716
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/text/NumberFormat.java
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.text;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class NumberFormat extends java.text.Format {
+
+    protected NumberFormat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.StringBuffer format(
+            java.lang.Object number,
+            java.lang.StringBuffer toAppendTo,
+            java.text.FieldPosition pos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.Object parseObject(
+            java.lang.String source, java.text.ParsePosition pos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String format(double number) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.lang.String format(long number) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.StringBuffer format(
+            double number, java.lang.StringBuffer toAppendTo, java.text.FieldPosition pos);
+
+    public abstract java.lang.StringBuffer format(
+            long number, java.lang.StringBuffer toAppendTo, java.text.FieldPosition pos);
+
+    public abstract java.lang.Number parse(
+            java.lang.String source, java.text.ParsePosition parsePosition);
+
+    public java.lang.Number parse(java.lang.String source) throws java.text.ParseException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isParseIntegerOnly() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setParseIntegerOnly(boolean value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.NumberFormat getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.text.NumberFormat getInstance(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.NumberFormat getNumberInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.text.NumberFormat getNumberInstance(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.NumberFormat getIntegerInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.text.NumberFormat getIntegerInstance(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.NumberFormat getCurrencyInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.text.NumberFormat getCurrencyInstance(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.text.NumberFormat getPercentInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.text.NumberFormat getPercentInstance(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isGroupingUsed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setGroupingUsed(boolean newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMaximumIntegerDigits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMaximumIntegerDigits(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinimumIntegerDigits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMinimumIntegerDigits(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMaximumFractionDigits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMaximumFractionDigits(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinimumFractionDigits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMinimumFractionDigits(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Currency getCurrency() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCurrency(java.util.Currency currency) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.RoundingMode getRoundingMode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setRoundingMode(java.math.RoundingMode roundingMode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.text.NumberFormat getInstance(java.util.Locale desiredLocale, int choice) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int CURRENCYSTYLE = 1; // 0x1
+
+    public static final int FRACTION_FIELD = 1; // 0x1
+
+    private static final int INTEGERSTYLE = 3; // 0x3
+
+    public static final int INTEGER_FIELD = 0; // 0x0
+
+    private static final int NUMBERSTYLE = 0; // 0x0
+
+    private static final int PERCENTSTYLE = 2; // 0x2
+
+    static final int currentSerialVersion = 1; // 0x1
+
+    private boolean groupingUsed = true;
+
+    private byte maxFractionDigits = 3; // 0x3
+
+    private byte maxIntegerDigits = 40; // 0x28
+
+    private int maximumFractionDigits = 3; // 0x3
+
+    private int maximumIntegerDigits = 40; // 0x28
+
+    private byte minFractionDigits = 0; // 0x0
+
+    private byte minIntegerDigits = 1; // 0x1
+
+    private int minimumFractionDigits = 0; // 0x0
+
+    private int minimumIntegerDigits = 1; // 0x1
+
+    private boolean parseIntegerOnly = false;
+
+    private int serialVersionOnStream = 1; // 0x1
+
+    static final long serialVersionUID = -2308460125733713944L; // 0xdff6b3bf137d07e8L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Field extends java.text.Format.Field {
+
+        protected Field(java.lang.String name) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.lang.Object readResolve() throws java.io.InvalidObjectException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static final java.text.NumberFormat.Field CURRENCY;
+
+        static {
+            CURRENCY = null;
+        }
+
+        public static final java.text.NumberFormat.Field DECIMAL_SEPARATOR;
+
+        static {
+            DECIMAL_SEPARATOR = null;
+        }
+
+        public static final java.text.NumberFormat.Field EXPONENT;
+
+        static {
+            EXPONENT = null;
+        }
+
+        public static final java.text.NumberFormat.Field EXPONENT_SIGN;
+
+        static {
+            EXPONENT_SIGN = null;
+        }
+
+        public static final java.text.NumberFormat.Field EXPONENT_SYMBOL;
+
+        static {
+            EXPONENT_SYMBOL = null;
+        }
+
+        public static final java.text.NumberFormat.Field FRACTION;
+
+        static {
+            FRACTION = null;
+        }
+
+        public static final java.text.NumberFormat.Field GROUPING_SEPARATOR;
+
+        static {
+            GROUPING_SEPARATOR = null;
+        }
+
+        public static final java.text.NumberFormat.Field INTEGER;
+
+        static {
+            INTEGER = null;
+        }
+
+        public static final java.text.NumberFormat.Field PERCENT;
+
+        static {
+            PERCENT = null;
+        }
+
+        public static final java.text.NumberFormat.Field PERMILLE;
+
+        static {
+            PERMILLE = null;
+        }
+
+        public static final java.text.NumberFormat.Field SIGN;
+
+        static {
+            SIGN = null;
+        }
+
+        private static final java.util.Map<java.lang.String, java.text.NumberFormat.Field>
+                instanceMap;
+
+        static {
+            instanceMap = null;
+        }
+
+        private static final long serialVersionUID = 7494728892700160890L; // 0x6802a038193ff37aL
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/time/Duration.java b/ojluni/annotations/hiddenapi/java/time/Duration.java
new file mode 100644
index 0000000..3090adb
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/time/Duration.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package java.time;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Duration
+        implements java.time.temporal.TemporalAmount,
+                java.lang.Comparable<java.time.Duration>,
+                java.io.Serializable {
+
+    private Duration(long seconds, int nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofDays(long days) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofHours(long hours) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofMinutes(long minutes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofSeconds(long seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofSeconds(long seconds, long nanoAdjustment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofMillis(long millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration ofNanos(long nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration of(long amount, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration from(java.time.temporal.TemporalAmount amount) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration parse(java.lang.CharSequence text) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long parseNumber(
+            java.lang.CharSequence text,
+            java.lang.String parsed,
+            int multiplier,
+            java.lang.String errorText) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int parseFraction(
+            java.lang.CharSequence text, java.lang.String parsed, int negate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.time.Duration create(
+            boolean negate,
+            long daysAsSecs,
+            long hoursAsSecs,
+            long minsAsSecs,
+            long secs,
+            int nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.Duration between(
+            java.time.temporal.Temporal startInclusive, java.time.temporal.Temporal endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.time.Duration create(long seconds, int nanoAdjustment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long get(java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.time.temporal.TemporalUnit> getUnits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isZero() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isNegative() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getSeconds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getNano() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration withSeconds(long seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration withNanos(int nanoOfSecond) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plus(java.time.Duration duration) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plus(long amountToAdd, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusDays(long daysToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusHours(long hoursToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusMinutes(long minutesToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusSeconds(long secondsToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusMillis(long millisToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration plusNanos(long nanosToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.time.Duration plus(long secondsToAdd, long nanosToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minus(java.time.Duration duration) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minus(long amountToSubtract, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusDays(long daysToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusHours(long hoursToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusMinutes(long minutesToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusSeconds(long secondsToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusMillis(long millisToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration minusNanos(long nanosToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration multipliedBy(long multiplicand) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration dividedBy(long divisor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private java.math.BigDecimal toSeconds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.time.Duration create(java.math.BigDecimal seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration negated() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Duration abs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.temporal.Temporal addTo(java.time.temporal.Temporal temporal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal temporal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toDays() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toHours() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toMinutes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toMillis() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toNanos() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.time.Duration otherDuration) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object otherDuration) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object writeReplace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s) throws java.io.InvalidObjectException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void writeExternal(java.io.DataOutput out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.time.Duration readExternal(java.io.DataInput in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.math.BigInteger BI_NANOS_PER_SECOND;
+
+    static {
+        BI_NANOS_PER_SECOND = null;
+    }
+
+    private static final java.util.regex.Pattern PATTERN;
+
+    static {
+        PATTERN = null;
+    }
+
+    public static final java.time.Duration ZERO;
+
+    static {
+        ZERO = null;
+    }
+
+    private final int nanos;
+
+    {
+        nanos = 0;
+    }
+
+    private final long seconds;
+
+    {
+        seconds = 0;
+    }
+
+    private static final long serialVersionUID = 3078945930695997490L; // 0x2aba9d02d1c4f832L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DurationUnits {
+
+        private DurationUnits() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.List<java.time.temporal.TemporalUnit> UNITS;
+
+        static {
+            UNITS = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java b/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java
new file mode 100644
index 0000000..f95f12f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package java.time;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class OffsetDateTime
+        implements java.time.temporal.Temporal,
+                java.time.temporal.TemporalAdjuster,
+                java.lang.Comparable<java.time.OffsetDateTime>,
+                java.io.Serializable {
+
+    @UnsupportedAppUsage
+    private OffsetDateTime(java.time.LocalDateTime dateTime, java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Comparator<java.time.OffsetDateTime> timeLineOrder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compareInstant(
+            java.time.OffsetDateTime datetime1, java.time.OffsetDateTime datetime2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime now() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime now(java.time.ZoneId zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime now(java.time.Clock clock) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime of(
+            java.time.LocalDate date, java.time.LocalTime time, java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime of(
+            java.time.LocalDateTime dateTime, java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime of(
+            int year,
+            int month,
+            int dayOfMonth,
+            int hour,
+            int minute,
+            int second,
+            int nanoOfSecond,
+            java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime ofInstant(
+            java.time.Instant instant, java.time.ZoneId zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime from(java.time.temporal.TemporalAccessor temporal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime parse(java.lang.CharSequence text) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.OffsetDateTime parse(
+            java.lang.CharSequence text, java.time.format.DateTimeFormatter formatter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.time.OffsetDateTime with(
+            java.time.LocalDateTime dateTime, java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSupported(java.time.temporal.TemporalField field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSupported(java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.temporal.ValueRange range(java.time.temporal.TemporalField field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int get(java.time.temporal.TemporalField field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getLong(java.time.temporal.TemporalField field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.ZoneOffset getOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withOffsetSameLocal(java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withOffsetSameInstant(java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.LocalDateTime toLocalDateTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.LocalDate toLocalDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMonthValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Month getMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.DayOfWeek getDayOfWeek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.LocalTime toLocalTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getHour() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinute() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getSecond() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getNano() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster adjuster) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime with(java.time.temporal.TemporalField field, long newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withYear(int year) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withMonth(int month) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withDayOfMonth(int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withDayOfYear(int dayOfYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withHour(int hour) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withMinute(int minute) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withSecond(int second) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime withNano(int nanoOfSecond) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount amountToAdd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plus(long amountToAdd, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusYears(long years) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusMonths(long months) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusWeeks(long weeks) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusDays(long days) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusHours(long hours) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusMinutes(long minutes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusSeconds(long seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime plusNanos(long nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount amountToSubtract) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minus(
+            long amountToSubtract, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusYears(long years) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusMonths(long months) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusWeeks(long weeks) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusDays(long days) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusHours(long hours) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusMinutes(long minutes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusSeconds(long seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetDateTime minusNanos(long nanos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <R> R query(java.time.temporal.TemporalQuery<R> query) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal temporal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long until(
+            java.time.temporal.Temporal endExclusive, java.time.temporal.TemporalUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String format(java.time.format.DateTimeFormatter formatter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.ZonedDateTime atZoneSameInstant(java.time.ZoneId zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.ZonedDateTime atZoneSimilarLocal(java.time.ZoneId zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.OffsetTime toOffsetTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.ZonedDateTime toZonedDateTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.time.Instant toInstant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long toEpochSecond() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.time.OffsetDateTime other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isAfter(java.time.OffsetDateTime other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isBefore(java.time.OffsetDateTime other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEqual(java.time.OffsetDateTime other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object writeReplace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s) throws java.io.InvalidObjectException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.time.OffsetDateTime readExternal(java.io.ObjectInput in)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.time.OffsetDateTime MAX;
+
+    static {
+        MAX = null;
+    }
+
+    public static final java.time.OffsetDateTime MIN;
+
+    static {
+        MIN = null;
+    }
+
+    private final java.time.LocalDateTime dateTime;
+
+    {
+        dateTime = null;
+    }
+
+    private final java.time.ZoneOffset offset;
+
+    {
+        offset = null;
+    }
+
+    private static final long serialVersionUID = 2287754244819255394L; // 0x1fbfbc5d57d80062L
+}
diff --git a/ojluni/annotations/hiddenapi/java/time/ZoneId.java b/ojluni/annotations/hiddenapi/java/time/ZoneId.java
new file mode 100644
index 0000000..f3ae76a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/time/ZoneId.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package java.time;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ZoneId implements java.io.Serializable {
+
+    ZoneId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.ZoneId systemDefault() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Set<java.lang.String> getAvailableZoneIds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.ZoneId of(
+            java.lang.String zoneId, java.util.Map<java.lang.String, java.lang.String> aliasMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.ZoneId of(java.lang.String zoneId) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.ZoneId ofOffset(java.lang.String prefix, java.time.ZoneOffset offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static java.time.ZoneId of(java.lang.String zoneId, boolean checkAvailable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.time.ZoneId ofWithPrefix(
+            java.lang.String zoneId, int prefixLength, boolean checkAvailable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.time.ZoneId from(java.time.temporal.TemporalAccessor temporal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.String getId();
+
+    public java.lang.String getDisplayName(
+            java.time.format.TextStyle style, java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.time.temporal.TemporalAccessor toTemporal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.time.zone.ZoneRules getRules();
+
+    public java.time.ZoneId normalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s) throws java.io.InvalidObjectException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object writeReplace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void write(java.io.DataOutput out) throws java.io.IOException;
+
+    public static final java.util.Map<java.lang.String, java.lang.String> SHORT_IDS;
+
+    static {
+        SHORT_IDS = null;
+    }
+
+    private static final long serialVersionUID = 8352817235686L; // 0x798cab446e6L
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/ArrayDeque.java b/ojluni/annotations/hiddenapi/java/util/ArrayDeque.java
new file mode 100644
index 0000000..59315d8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/ArrayDeque.java
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Josh Bloch of Google Inc. and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
+ */
+
+package java.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ArrayDeque<E> extends java.util.AbstractCollection<E>
+        implements java.util.Deque<E>, java.lang.Cloneable, java.io.Serializable {
+
+    public ArrayDeque() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ArrayDeque(int numElements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ArrayDeque(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void allocateElements(int numElements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void doubleCapacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeFirstOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeLastOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E element() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void push(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pop() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkInvariants() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean delete(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> descendingIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ArrayDeque<E> clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int MIN_INITIAL_CAPACITY = 8; // 0x8
+
+    @UnsupportedAppUsage
+    transient java.lang.Object[] elements;
+
+    @UnsupportedAppUsage
+    transient int head;
+
+    private static final long serialVersionUID = 2340985798034038923L; // 0x207cda2e240da08bL
+
+    @UnsupportedAppUsage
+    transient int tail;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class DeqIterator implements java.util.Iterator<E> {
+
+        private DeqIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int cursor;
+
+        private int fence;
+
+        private int lastRet = -1; // 0xffffffff
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class DeqSpliterator<E> implements java.util.Spliterator<E> {
+
+        DeqSpliterator(java.util.ArrayDeque<E> deq, int origin, int fence) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ArrayDeque.DeqSpliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.ArrayDeque<E> deq;
+
+        {
+            deq = null;
+        }
+
+        private int fence;
+
+        private int index;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class DescendingIterator implements java.util.Iterator<E> {
+
+        private DescendingIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int cursor;
+
+        private int fence;
+
+        private int lastRet = -1; // 0xffffffff
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/ArrayList.java b/ojluni/annotations/hiddenapi/java/util/ArrayList.java
new file mode 100644
index 0000000..7457f1e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/ArrayList.java
@@ -0,0 +1,431 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void trimToSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void ensureCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureCapacityInternal(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureExplicitCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void grow(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int hugeCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E get(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E set(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void add(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void fastRemove(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(int index, java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void removeRange(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String outOfBoundsMsg(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean retainAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean batchRemove(java.util.Collection<?> c, boolean complement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ListIterator<E> listIterator(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ListIterator<E> listIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<E> subList(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void forEach(java.util.function.Consumer<? super E> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sort(java.util.Comparator<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
+
+    static {
+        DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new java.lang.Object[0];
+    }
+
+    private static final int DEFAULT_CAPACITY = 10; // 0xa
+
+    private static final java.lang.Object[] EMPTY_ELEMENTDATA;
+
+    static {
+        EMPTY_ELEMENTDATA = new java.lang.Object[0];
+    }
+
+    private static final int MAX_ARRAY_SIZE = 2147483639; // 0x7ffffff7
+
+    @UnsupportedAppUsage
+    transient java.lang.Object[] elementData;
+
+    private static final long serialVersionUID = 8683452581122892189L; // 0x7881d21d99c7619dL
+
+    @UnsupportedAppUsage
+    private int size;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class ArrayListSpliterator<E> implements java.util.Spliterator<E> {
+
+        ArrayListSpliterator(
+                java.util.ArrayList<E> list, int origin, int fence, int expectedModCount) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ArrayList.ArrayListSpliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int expectedModCount;
+
+        private int fence;
+
+        private int index;
+
+        private final java.util.ArrayList<E> list;
+
+        {
+            list = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Itr implements java.util.Iterator<E> {
+
+        private Itr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int cursor;
+
+        int expectedModCount;
+
+        int lastRet = -1; // 0xffffffff
+
+        protected int limit;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ListItr extends Itr implements java.util.ListIterator<E> {
+
+        ListItr(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class SubList extends java.util.AbstractList<E> implements java.util.RandomAccess {
+
+        SubList(java.util.AbstractList<E> parent, int offset, int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(int index, E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void removeRange(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(int index, java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String outOfBoundsMsg(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        private final int offset;
+
+        {
+            offset = 0;
+        }
+
+        @UnsupportedAppUsage
+        private final java.util.AbstractList<E> parent;
+
+        {
+            parent = null;
+        }
+
+        @UnsupportedAppUsage
+        private final int parentOffset;
+
+        {
+            parentOffset = 0;
+        }
+
+        @UnsupportedAppUsage
+        int size;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Arrays.java b/ojluni/annotations/hiddenapi/java/util/Arrays.java
new file mode 100644
index 0000000..c763a2d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Arrays.java
@@ -0,0 +1,831 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Arrays {
+
+    private Arrays() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(int[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(int[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(long[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(long[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(short[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(short[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(char[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(char[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(byte[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(byte[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(float[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(float[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(double[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(double[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(byte[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(byte[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(char[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(char[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(short[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(short[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(int[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(int[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(long[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(long[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(float[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(float[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(double[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSort(double[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.Comparable<? super T>> void parallelSort(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.Comparable<? super T>> void parallelSort(
+            T[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void parallelSort(T[] a, java.util.Comparator<? super T> cmp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void parallelSort(
+            T[] a, int fromIndex, int toIndex, java.util.Comparator<? super T> cmp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void sort(java.lang.Object[] a, int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void mergeSort(
+            java.lang.Object[] src, java.lang.Object[] dest, int low, int high, int off) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void swap(java.lang.Object[] x, int a, int b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void sort(T[] a, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void sort(
+            T[] a, int fromIndex, int toIndex, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void parallelPrefix(T[] array, java.util.function.BinaryOperator<T> op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void parallelPrefix(
+            T[] array, int fromIndex, int toIndex, java.util.function.BinaryOperator<T> op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(long[] array, java.util.function.LongBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(
+            long[] array, int fromIndex, int toIndex, java.util.function.LongBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(double[] array, java.util.function.DoubleBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(
+            double[] array,
+            int fromIndex,
+            int toIndex,
+            java.util.function.DoubleBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(int[] array, java.util.function.IntBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelPrefix(
+            int[] array, int fromIndex, int toIndex, java.util.function.IntBinaryOperator op) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(long[] a, long key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(long[] a, int fromIndex, int toIndex, long key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(long[] a, int fromIndex, int toIndex, long key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(int[] a, int key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(short[] a, short key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(short[] a, int fromIndex, int toIndex, short key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(short[] a, int fromIndex, int toIndex, short key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(char[] a, char key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(char[] a, int fromIndex, int toIndex, char key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(char[] a, int fromIndex, int toIndex, char key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(byte[] a, byte key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(byte[] a, int fromIndex, int toIndex, byte key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(byte[] a, int fromIndex, int toIndex, byte key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(double[] a, double key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(double[] a, int fromIndex, int toIndex, double key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(double[] a, int fromIndex, int toIndex, double key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(float[] a, float key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(float[] a, int fromIndex, int toIndex, float key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(float[] a, int fromIndex, int toIndex, float key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(java.lang.Object[] a, java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int binarySearch(
+            java.lang.Object[] a, int fromIndex, int toIndex, java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int binarySearch0(
+            java.lang.Object[] a, int fromIndex, int toIndex, java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> int binarySearch(T[] a, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> int binarySearch(
+            T[] a, int fromIndex, int toIndex, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> int binarySearch0(
+            T[] a, int fromIndex, int toIndex, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(long[] a, long[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(int[] a, int[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(short[] a, short[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(char[] a, char[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(byte[] a, byte[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(boolean[] a, boolean[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(double[] a, double[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(float[] a, float[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean equals(java.lang.Object[] a, java.lang.Object[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(long[] a, long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(long[] a, int fromIndex, int toIndex, long val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(int[] a, int val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(int[] a, int fromIndex, int toIndex, int val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(short[] a, short val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(short[] a, int fromIndex, int toIndex, short val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(char[] a, char val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(char[] a, int fromIndex, int toIndex, char val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(byte[] a, byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(byte[] a, int fromIndex, int toIndex, byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(boolean[] a, boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(double[] a, double val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(double[] a, int fromIndex, int toIndex, double val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(float[] a, float val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(float[] a, int fromIndex, int toIndex, float val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(java.lang.Object[] a, java.lang.Object val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void fill(
+            java.lang.Object[] a, int fromIndex, int toIndex, java.lang.Object val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> T[] copyOf(T[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T, U> T[] copyOf(
+            U[] original, int newLength, java.lang.Class<? extends T[]> newType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] copyOf(byte[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short[] copyOf(short[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int[] copyOf(int[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long[] copyOf(long[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static char[] copyOf(char[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float[] copyOf(float[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double[] copyOf(double[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean[] copyOf(boolean[] original, int newLength) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> T[] copyOfRange(T[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T, U> T[] copyOfRange(
+            U[] original, int from, int to, java.lang.Class<? extends T[]> newType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] copyOfRange(byte[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static short[] copyOfRange(short[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int[] copyOfRange(int[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static long[] copyOfRange(long[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static char[] copyOfRange(char[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float[] copyOfRange(float[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double[] copyOfRange(double[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean[] copyOfRange(boolean[] original, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.List<T> asList(T... a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(long[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(int[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(short[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(char[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(byte[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(boolean[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(float[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(double[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int hashCode(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int deepHashCode(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean deepEquals(java.lang.Object[] a1, java.lang.Object[] a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean deepEquals0(java.lang.Object e1, java.lang.Object e2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(long[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(int[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(short[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(char[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(byte[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(boolean[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(float[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(double[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String deepToString(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static void deepToString(
+            java.lang.Object[] a,
+            java.lang.StringBuilder buf,
+            java.util.Set<java.lang.Object[]> dejaVu) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void setAll(
+            T[] array, java.util.function.IntFunction<? extends T> generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void parallelSetAll(
+            T[] array, java.util.function.IntFunction<? extends T> generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setAll(int[] array, java.util.function.IntUnaryOperator generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSetAll(int[] array, java.util.function.IntUnaryOperator generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setAll(long[] array, java.util.function.IntToLongFunction generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSetAll(
+            long[] array, java.util.function.IntToLongFunction generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setAll(double[] array, java.util.function.IntToDoubleFunction generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void parallelSetAll(
+            double[] array, java.util.function.IntToDoubleFunction generator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Spliterator<T> spliterator(T[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Spliterator<T> spliterator(
+            T[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfInt spliterator(int[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfInt spliterator(
+            int[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfLong spliterator(long[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfLong spliterator(
+            long[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfDouble spliterator(double[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Spliterator.OfDouble spliterator(
+            double[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.stream.Stream<T> stream(T[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.stream.Stream<T> stream(
+            T[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.IntStream stream(int[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.IntStream stream(
+            int[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.LongStream stream(long[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.LongStream stream(
+            long[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.DoubleStream stream(double[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.stream.DoubleStream stream(
+            double[] array, int startInclusive, int endExclusive) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int INSERTIONSORT_THRESHOLD = 7; // 0x7
+
+    public static final int MIN_ARRAY_SORT_GRAN = 8192; // 0x2000
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ArrayList<E> extends java.util.AbstractList<E>
+            implements java.util.RandomAccess, java.io.Serializable {
+
+        ArrayList(E[] array) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int indexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        private final E[] a;
+
+        {
+            a = null;
+        }
+
+        private static final long serialVersionUID = -2764017481108945198L; // 0xd9a43cbecd8806d2L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class NaturalOrder implements java.util.Comparator<java.lang.Object> {
+
+        NaturalOrder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int compare(java.lang.Object first, java.lang.Object second) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.Arrays.NaturalOrder INSTANCE;
+
+        static {
+            INSTANCE = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Calendar.java b/ojluni/annotations/hiddenapi/java/util/Calendar.java
new file mode 100644
index 0000000..99a76f7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Calendar.java
@@ -0,0 +1,734 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Calendar
+        implements java.io.Serializable,
+                java.lang.Cloneable,
+                java.lang.Comparable<java.util.Calendar> {
+
+    protected Calendar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected Calendar(java.util.TimeZone zone, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Calendar getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Calendar getInstance(java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Calendar getInstance(java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Calendar getInstance(
+            java.util.TimeZone zone, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Calendar getJapaneseImperialInstance(
+            java.util.TimeZone zone, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Calendar createCalendar(
+            java.util.TimeZone zone, java.util.Locale aLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void computeTime();
+
+    protected abstract void computeFields();
+
+    public final java.util.Date getTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void setTime(java.util.Date date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTimeInMillis() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTimeInMillis(long millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int get(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final int internalGet(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void internalSet(int field, int value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(int field, int value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void set(int year, int month, int date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void set(int year, int month, int date, int hourOfDay, int minute) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void set(int year, int month, int date, int hourOfDay, int minute, int second) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void clear(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isSet(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayName(int field, int style, java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Map<java.lang.String, java.lang.Integer> getDisplayNames(
+            int field, int style, java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Map<java.lang.String, java.lang.Integer> getDisplayNamesImpl(
+            int field, int style, java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean checkDisplayNameParams(
+            int field,
+            int style,
+            int minStyle,
+            int maxStyle,
+            java.util.Locale locale,
+            int fieldMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String[] getFieldStrings(
+            int field, int style, java.text.DateFormatSymbols symbols) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void complete() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isExternallySet(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int getSetStateFields() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void setFieldsComputed(int fieldMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void setFieldsNormalized(int fieldMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isPartiallyNormalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isFullyNormalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void setUnnormalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isFieldSet(int fieldMask, int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int selectFields() {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getBaseStyle(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int toStandaloneStyle(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isStandaloneStyle(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isNarrowStyle(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isNarrowFormatStyle(int style) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int aggregateStamp(int stamp_a, int stamp_b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Set<java.lang.String> getAvailableCalendarTypes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCalendarType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean before(java.lang.Object when) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean after(java.lang.Object when) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.util.Calendar anotherCalendar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract void add(int field, int amount);
+
+    public abstract void roll(int field, boolean up);
+
+    public void roll(int field, int amount) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTimeZone(java.util.TimeZone value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.TimeZone getTimeZone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.TimeZone getZone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setZoneShared(boolean shared) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLenient(boolean lenient) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLenient() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setFirstDayOfWeek(int value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getFirstDayOfWeek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMinimalDaysInFirstWeek(int value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinimalDaysInFirstWeek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isWeekDateSupported() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getWeekYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getWeeksInWeekYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract int getMinimum(int field);
+
+    public abstract int getMaximum(int field);
+
+    public abstract int getGreatestMinimum(int field);
+
+    public abstract int getLeastMaximum(int field);
+
+    public int getActualMinimum(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getActualMaximum(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String getFieldName(int field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendValue(
+            java.lang.StringBuilder sb, java.lang.String item, boolean valid, long value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setWeekCountData(java.util.Locale desiredLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void updateTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int compareTo(long t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long getMillisOf(java.util.Calendar calendar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void adjustStamp() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void invalidateWeekFields() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream stream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.time.Instant toInstant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int ALL_FIELDS = 131071; // 0x1ffff
+
+    public static final int ALL_STYLES = 0; // 0x0
+
+    public static final int AM = 0; // 0x0
+
+    public static final int AM_PM = 9; // 0x9
+
+    static final int AM_PM_MASK = 512; // 0x200
+
+    public static final int APRIL = 3; // 0x3
+
+    public static final int AUGUST = 7; // 0x7
+
+    private static final int COMPUTED = 1; // 0x1
+
+    public static final int DATE = 5; // 0x5
+
+    static final int DATE_MASK = 32; // 0x20
+
+    public static final int DAY_OF_MONTH = 5; // 0x5
+
+    static final int DAY_OF_MONTH_MASK = 32; // 0x20
+
+    public static final int DAY_OF_WEEK = 7; // 0x7
+
+    public static final int DAY_OF_WEEK_IN_MONTH = 8; // 0x8
+
+    static final int DAY_OF_WEEK_IN_MONTH_MASK = 256; // 0x100
+
+    static final int DAY_OF_WEEK_MASK = 128; // 0x80
+
+    public static final int DAY_OF_YEAR = 6; // 0x6
+
+    static final int DAY_OF_YEAR_MASK = 64; // 0x40
+
+    public static final int DECEMBER = 11; // 0xb
+
+    public static final int DST_OFFSET = 16; // 0x10
+
+    static final int DST_OFFSET_MASK = 65536; // 0x10000
+
+    public static final int ERA = 0; // 0x0
+
+    static final int ERA_MASK = 1; // 0x1
+
+    public static final int FEBRUARY = 1; // 0x1
+
+    public static final int FIELD_COUNT = 17; // 0x11
+
+    private static final java.lang.String[] FIELD_NAME;
+
+    static {
+        FIELD_NAME = new java.lang.String[0];
+    }
+
+    public static final int FRIDAY = 6; // 0x6
+
+    public static final int HOUR = 10; // 0xa
+
+    static final int HOUR_MASK = 1024; // 0x400
+
+    public static final int HOUR_OF_DAY = 11; // 0xb
+
+    static final int HOUR_OF_DAY_MASK = 2048; // 0x800
+
+    public static final int JANUARY = 0; // 0x0
+
+    public static final int JULY = 6; // 0x6
+
+    public static final int JUNE = 5; // 0x5
+
+    public static final int LONG = 2; // 0x2
+
+    public static final int LONG_FORMAT = 2; // 0x2
+
+    public static final int LONG_STANDALONE = 32770; // 0x8002
+
+    public static final int MARCH = 2; // 0x2
+
+    public static final int MAY = 4; // 0x4
+
+    public static final int MILLISECOND = 14; // 0xe
+
+    static final int MILLISECOND_MASK = 16384; // 0x4000
+
+    private static final int MINIMUM_USER_STAMP = 2; // 0x2
+
+    public static final int MINUTE = 12; // 0xc
+
+    static final int MINUTE_MASK = 4096; // 0x1000
+
+    public static final int MONDAY = 2; // 0x2
+
+    public static final int MONTH = 2; // 0x2
+
+    static final int MONTH_MASK = 4; // 0x4
+
+    public static final int NARROW_FORMAT = 4; // 0x4
+
+    public static final int NARROW_STANDALONE = 32772; // 0x8004
+
+    public static final int NOVEMBER = 10; // 0xa
+
+    public static final int OCTOBER = 9; // 0x9
+
+    public static final int PM = 1; // 0x1
+
+    public static final int SATURDAY = 7; // 0x7
+
+    public static final int SECOND = 13; // 0xd
+
+    static final int SECOND_MASK = 8192; // 0x2000
+
+    public static final int SEPTEMBER = 8; // 0x8
+
+    public static final int SHORT = 1; // 0x1
+
+    public static final int SHORT_FORMAT = 1; // 0x1
+
+    public static final int SHORT_STANDALONE = 32769; // 0x8001
+
+    static final int STANDALONE_MASK = 32768; // 0x8000
+
+    public static final int SUNDAY = 1; // 0x1
+
+    public static final int THURSDAY = 5; // 0x5
+
+    public static final int TUESDAY = 3; // 0x3
+
+    public static final int UNDECIMBER = 12; // 0xc
+
+    private static final int UNSET = 0; // 0x0
+
+    public static final int WEDNESDAY = 4; // 0x4
+
+    public static final int WEEK_OF_MONTH = 4; // 0x4
+
+    static final int WEEK_OF_MONTH_MASK = 16; // 0x10
+
+    public static final int WEEK_OF_YEAR = 3; // 0x3
+
+    static final int WEEK_OF_YEAR_MASK = 8; // 0x8
+
+    public static final int YEAR = 1; // 0x1
+
+    static final int YEAR_MASK = 2; // 0x2
+
+    public static final int ZONE_OFFSET = 15; // 0xf
+
+    static final int ZONE_OFFSET_MASK = 32768; // 0x8000
+
+    transient boolean areAllFieldsSet;
+
+    protected boolean areFieldsSet;
+
+    private static final java.util.concurrent.ConcurrentMap<java.util.Locale, int[]>
+            cachedLocaleData;
+
+    static {
+        cachedLocaleData = null;
+    }
+
+    static final int currentSerialVersion = 1; // 0x1
+
+    protected int[] fields;
+
+    private int firstDayOfWeek;
+
+    protected boolean[] isSet;
+
+    protected boolean isTimeSet;
+
+    private boolean lenient = true;
+
+    private int minimalDaysInFirstWeek;
+
+    private int nextStamp = 2; // 0x2
+
+    private int serialVersionOnStream = 1; // 0x1
+
+    static final long serialVersionUID = -1807547505821590642L; // 0xe6ea4d1ec8dc5b8eL
+
+    private transient boolean sharedZone = false;
+
+    private transient int[] stamp;
+
+    protected long time;
+
+    @UnsupportedAppUsage
+    private java.util.TimeZone zone;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class AvailableCalendarTypes {
+
+        private AvailableCalendarTypes() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.util.Set<java.lang.String> SET;
+
+        static {
+            SET = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Builder {
+
+        public Builder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setInstant(long instant) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setInstant(java.util.Date instant) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder set(int field, int value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setFields(int... fieldValuePairs) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setDate(int year, int month, int dayOfMonth) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setTimeOfDay(int hourOfDay, int minute, int second) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setTimeOfDay(
+                int hourOfDay, int minute, int second, int millis) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setTimeZone(java.util.TimeZone zone) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setLenient(boolean lenient) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setCalendarType(java.lang.String type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setLocale(java.util.Locale locale) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar.Builder setWeekDefinition(
+                int firstDayOfWeek, int minimalDaysInFirstWeek) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Calendar build() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void allocateFields() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void internalSet(int field, int value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean isInstantSet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean isSet(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean isValidWeekParameter(int value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int NFIELDS = 18; // 0x12
+
+        private static final int WEEK_YEAR = 17; // 0x11
+
+        private int[] fields;
+
+        private int firstDayOfWeek;
+
+        private long instant;
+
+        private boolean lenient = true;
+
+        private java.util.Locale locale;
+
+        private int maxFieldIndex;
+
+        private int minimalDaysInFirstWeek;
+
+        private int nextStamp;
+
+        private java.lang.String type;
+
+        private java.util.TimeZone zone;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CalendarAccessControlContext {
+
+        private CalendarAccessControlContext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.security.AccessControlContext INSTANCE;
+
+        static {
+            INSTANCE = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Collections.java b/ojluni/annotations/hiddenapi/java/util/Collections.java
new file mode 100644
index 0000000..010ba3d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Collections.java
@@ -0,0 +1,3651 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Collections {
+
+    private Collections() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void sort(java.util.List<T> list, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> int binarySearch(
+            java.util.List<? extends java.lang.Comparable<? super T>> list, T key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> int indexedBinarySearch(
+            java.util.List<? extends java.lang.Comparable<? super T>> list, T key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> int iteratorBinarySearch(
+            java.util.List<? extends java.lang.Comparable<? super T>> list, T key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> T get(java.util.ListIterator<? extends T> i, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> int binarySearch(
+            java.util.List<? extends T> list, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> int indexedBinarySearch(
+            java.util.List<? extends T> l, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> int iteratorBinarySearch(
+            java.util.List<? extends T> l, T key, java.util.Comparator<? super T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void reverse(java.util.List<?> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void shuffle(java.util.List<?> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void shuffle(java.util.List<?> list, java.util.Random rnd) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void swap(java.util.List<?> list, int i, int j) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void swap(java.lang.Object[] arr, int i, int j) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void fill(java.util.List<? super T> list, T obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> void copy(java.util.List<? super T> dest, java.util.List<? extends T> src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T min(
+            java.util.Collection<? extends T> coll) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> T min(
+            java.util.Collection<? extends T> coll, java.util.Comparator<? super T> comp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T max(
+            java.util.Collection<? extends T> coll) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> T max(
+            java.util.Collection<? extends T> coll, java.util.Comparator<? super T> comp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void rotate(java.util.List<?> list, int distance) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> void rotate1(java.util.List<T> list, int distance) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void rotate2(java.util.List<?> list, int distance) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> boolean replaceAll(java.util.List<T> list, T oldVal, T newVal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int indexOfSubList(java.util.List<?> source, java.util.List<?> target) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int lastIndexOfSubList(java.util.List<?> source, java.util.List<?> target) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Collection<T> unmodifiableCollection(
+            java.util.Collection<? extends T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Set<T> unmodifiableSet(java.util.Set<? extends T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.SortedSet<T> unmodifiableSortedSet(java.util.SortedSet<T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.NavigableSet<T> unmodifiableNavigableSet(
+            java.util.NavigableSet<T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.List<T> unmodifiableList(java.util.List<? extends T> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.Map<K, V> unmodifiableMap(
+            java.util.Map<? extends K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.SortedMap<K, V> unmodifiableSortedMap(
+            java.util.SortedMap<K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.NavigableMap<K, V> unmodifiableNavigableMap(
+            java.util.NavigableMap<K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Collection<T> synchronizedCollection(java.util.Collection<T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <T> java.util.Collection<T> synchronizedCollection(
+            java.util.Collection<T> c, java.lang.Object mutex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Set<T> synchronizedSet(java.util.Set<T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <T> java.util.Set<T> synchronizedSet(java.util.Set<T> s, java.lang.Object mutex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.SortedSet<T> synchronizedSortedSet(java.util.SortedSet<T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.NavigableSet<T> synchronizedNavigableSet(
+            java.util.NavigableSet<T> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.List<T> synchronizedList(java.util.List<T> list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <T> java.util.List<T> synchronizedList(java.util.List<T> list, java.lang.Object mutex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.Map<K, V> synchronizedMap(java.util.Map<K, V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.SortedMap<K, V> synchronizedSortedMap(
+            java.util.SortedMap<K, V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.NavigableMap<K, V> synchronizedNavigableMap(
+            java.util.NavigableMap<K, V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.Collection<E> checkedCollection(
+            java.util.Collection<E> c, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <T> T[] zeroLengthArray(java.lang.Class<T> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.Queue<E> checkedQueue(
+            java.util.Queue<E> queue, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.Set<E> checkedSet(java.util.Set<E> s, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.SortedSet<E> checkedSortedSet(
+            java.util.SortedSet<E> s, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.NavigableSet<E> checkedNavigableSet(
+            java.util.NavigableSet<E> s, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.List<E> checkedList(
+            java.util.List<E> list, java.lang.Class<E> type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.Map<K, V> checkedMap(
+            java.util.Map<K, V> m, java.lang.Class<K> keyType, java.lang.Class<V> valueType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.SortedMap<K, V> checkedSortedMap(
+            java.util.SortedMap<K, V> m, java.lang.Class<K> keyType, java.lang.Class<V> valueType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.NavigableMap<K, V> checkedNavigableMap(
+            java.util.NavigableMap<K, V> m,
+            java.lang.Class<K> keyType,
+            java.lang.Class<V> valueType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Iterator<T> emptyIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.ListIterator<T> emptyListIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Enumeration<T> emptyEnumeration() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final <T> java.util.Set<T> emptySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.SortedSet<E> emptySortedSet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.NavigableSet<E> emptyNavigableSet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final <T> java.util.List<T> emptyList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final <K, V> java.util.Map<K, V> emptyMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final <K, V> java.util.SortedMap<K, V> emptySortedMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final <K, V> java.util.NavigableMap<K, V> emptyNavigableMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Set<T> singleton(T o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <E> java.util.Iterator<E> singletonIterator(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static <T> java.util.Spliterator<T> singletonSpliterator(T element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.List<T> singletonList(T o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> java.util.Map<K, V> singletonMap(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.List<T> nCopies(int n, T o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Comparator<T> reverseOrder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Comparator<T> reverseOrder(java.util.Comparator<T> cmp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Enumeration<T> enumeration(java.util.Collection<T> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.ArrayList<T> list(java.util.Enumeration<T> e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean eq(java.lang.Object o1, java.lang.Object o2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int frequency(java.util.Collection<?> c, java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean disjoint(java.util.Collection<?> c1, java.util.Collection<?> c2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> boolean addAll(java.util.Collection<? super T> c, T... elements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E> java.util.Set<E> newSetFromMap(java.util.Map<E, java.lang.Boolean> map) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.Queue<T> asLifoQueue(java.util.Deque<T> deque) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int BINARYSEARCH_THRESHOLD = 5000; // 0x1388
+
+    private static final int COPY_THRESHOLD = 10; // 0xa
+
+    public static final java.util.List EMPTY_LIST;
+
+    static {
+        EMPTY_LIST = null;
+    }
+
+    public static final java.util.Map EMPTY_MAP;
+
+    static {
+        EMPTY_MAP = null;
+    }
+
+    public static final java.util.Set EMPTY_SET;
+
+    static {
+        EMPTY_SET = null;
+    }
+
+    private static final int FILL_THRESHOLD = 25; // 0x19
+
+    private static final int INDEXOFSUBLIST_THRESHOLD = 35; // 0x23
+
+    private static final int REPLACEALL_THRESHOLD = 11; // 0xb
+
+    private static final int REVERSE_THRESHOLD = 18; // 0x12
+
+    private static final int ROTATE_THRESHOLD = 100; // 0x64
+
+    private static final int SHUFFLE_THRESHOLD = 5; // 0x5
+
+    private static java.util.Random r;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class AsLIFOQueue<E> extends java.util.AbstractQueue<E>
+            implements java.util.Queue<E>, java.io.Serializable {
+
+        AsLIFOQueue(java.util.Deque<E> q) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean offer(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E poll() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E peek() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E element() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Deque<E> q;
+
+        {
+            q = null;
+        }
+
+        private static final long serialVersionUID = 1802017725587941708L; // 0x19020d92eca0694cL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedCollection<E> implements java.util.Collection<E>, java.io.Serializable {
+
+        CheckedCollection(java.util.Collection<E> c, java.lang.Class<E> type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        E typeCheck(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String badElementMsg(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private E[] zeroLengthElementArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.Collection<E> checkedCopyOf(java.util.Collection<? extends E> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(java.util.Collection<? extends E> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.Collection<E> c;
+
+        {
+            c = null;
+        }
+
+        private static final long serialVersionUID = 1578914078182001775L; // 0x15e96dfd18e6cc6fL
+
+        final java.lang.Class<E> type;
+
+        {
+            type = null;
+        }
+
+        private E[] zeroLengthElementArray;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedList<E> extends java.util.Collections.CheckedCollection<E>
+            implements java.util.List<E> {
+
+        CheckedList(java.util.List<E> list, java.lang.Class<E> type) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int indexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int lastIndexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(int index, java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.List<E> list;
+
+        {
+            list = null;
+        }
+
+        private static final long serialVersionUID = 65247728283967356L; // 0xe7ce7692c45f7cL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CheckedMap<K, V> implements java.util.Map<K, V>, java.io.Serializable {
+
+        CheckedMap(
+                java.util.Map<K, V> m, java.lang.Class<K> keyType, java.lang.Class<V> valueType) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void typeCheck(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.util.function.BiFunction<? super K, ? super V, ? extends V> typeCheck(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> func) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String badKeyMsg(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.String badValueMsg(java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsKey(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsValue(java.lang.Object v) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V get(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<V> values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V put(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void putAll(java.util.Map<? extends K, ? extends V> t) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V putIfAbsent(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V replace(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfAbsent(
+                K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfPresent(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V compute(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V merge(
+                K key,
+                V value,
+                java.util.function.BiFunction<? super V, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+        final java.lang.Class<K> keyType;
+
+        {
+            keyType = null;
+        }
+
+        private final java.util.Map<K, V> m;
+
+        {
+            m = null;
+        }
+
+        private static final long serialVersionUID = 5742860141034234728L; // 0x4fb2bcdf0d186368L
+
+        final java.lang.Class<V> valueType;
+
+        {
+            valueType = null;
+        }
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        static class CheckedEntrySet<K, V> implements java.util.Set<java.util.Map.Entry<K, V>> {
+
+            CheckedEntrySet(
+                    java.util.Set<java.util.Map.Entry<K, V>> s, java.lang.Class<V> valueType) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public int size() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean isEmpty() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.lang.String toString() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public int hashCode() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public void clear() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean add(java.util.Map.Entry<K, V> e) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean addAll(java.util.Collection<? extends java.util.Map.Entry<K, V>> coll) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.lang.Object[] toArray() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public <T> T[] toArray(T[] a) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean contains(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean containsAll(java.util.Collection<?> c) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean remove(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean removeAll(java.util.Collection<?> c) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean retainAll(java.util.Collection<?> c) {
+                throw new RuntimeException("Stub!");
+            }
+
+            private boolean batchRemove(java.util.Collection<?> c, boolean complement) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean equals(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            static <K, V, T>
+                    java.util.Collections.CheckedMap.CheckedEntrySet.CheckedEntry<K, V, T>
+                            checkedEntry(
+                                    java.util.Map.Entry<K, V> e, java.lang.Class<T> valueType) {
+                throw new RuntimeException("Stub!");
+            }
+
+            private final java.util.Set<java.util.Map.Entry<K, V>> s;
+
+            {
+                s = null;
+            }
+
+            private final java.lang.Class<V> valueType;
+
+            {
+                valueType = null;
+            }
+
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            private static class CheckedEntry<K, V, T> implements java.util.Map.Entry<K, V> {
+
+                CheckedEntry(java.util.Map.Entry<K, V> e, java.lang.Class<T> valueType) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public K getKey() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public V getValue() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public int hashCode() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public java.lang.String toString() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public V setValue(V value) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                private java.lang.String badValueMsg(java.lang.Object value) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public boolean equals(java.lang.Object o) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                private final java.util.Map.Entry<K, V> e;
+
+                {
+                    e = null;
+                }
+
+                private final java.lang.Class<T> valueType;
+
+                {
+                    valueType = null;
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedNavigableMap<K, V> extends java.util.Collections.CheckedSortedMap<K, V>
+            implements java.util.NavigableMap<K, V>, java.io.Serializable {
+
+        CheckedNavigableMap(
+                java.util.NavigableMap<K, V> m,
+                java.lang.Class<K> keyType,
+                java.lang.Class<V> valueType) {
+            super(null, null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super K> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K firstKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lastKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lowerEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lowerKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> floorEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K floorKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> ceilingEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K ceilingKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> higherEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K higherKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> firstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollFirstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollLastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> descendingMap() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> navigableKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> descendingKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> subMap(K fromKey, K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> headMap(K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> tailMap(K fromKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> subMap(
+                K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.NavigableMap<K, V> nm;
+
+        {
+            nm = null;
+        }
+
+        private static final long serialVersionUID = -4852462692372534096L; // 0xbca896e4074cacb0L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedNavigableSet<E> extends java.util.Collections.CheckedSortedSet<E>
+            implements java.util.NavigableSet<E>, java.io.Serializable {
+
+        CheckedNavigableSet(java.util.NavigableSet<E> s, java.lang.Class<E> type) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public E lower(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E floor(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E ceiling(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E higher(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollFirst() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollLast() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> descendingSet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> descendingIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> subSet(E fromElement, E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> headSet(E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> tailSet(E fromElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> subSet(
+                E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.NavigableSet<E> ns;
+
+        {
+            ns = null;
+        }
+
+        private static final long serialVersionUID = -5429120189805438922L; // 0xb4a7e3f3bbbed836L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedQueue<E> extends java.util.Collections.CheckedCollection<E>
+            implements java.util.Queue<E>, java.io.Serializable {
+
+        CheckedQueue(java.util.Queue<E> queue, java.lang.Class<E> elementType) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public E element() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E peek() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E poll() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean offer(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.Queue<E> queue;
+
+        {
+            queue = null;
+        }
+
+        private static final long serialVersionUID = 1433151992604707767L; // 0x13e39424e458cbb7L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedRandomAccessList<E> extends java.util.Collections.CheckedList<E>
+            implements java.util.RandomAccess {
+
+        CheckedRandomAccessList(java.util.List<E> list, java.lang.Class<E> type) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1638200125423088369L; // 0x16bc0e55a2d7f2f1L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedSet<E> extends java.util.Collections.CheckedCollection<E>
+            implements java.util.Set<E>, java.io.Serializable {
+
+        CheckedSet(java.util.Set<E> s, java.lang.Class<E> elementType) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 4694047833775013803L; // 0x41249ba27ad9ffabL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedSortedMap<K, V> extends java.util.Collections.CheckedMap<K, V>
+            implements java.util.SortedMap<K, V>, java.io.Serializable {
+
+        CheckedSortedMap(
+                java.util.SortedMap<K, V> m,
+                java.lang.Class<K> keyType,
+                java.lang.Class<V> valueType) {
+            super(null, null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super K> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K firstKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lastKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> subMap(K fromKey, K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> headMap(K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> tailMap(K fromKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1599671320688067438L; // 0x16332c973afe036eL
+
+        private final java.util.SortedMap<K, V> sm;
+
+        {
+            sm = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class CheckedSortedSet<E> extends java.util.Collections.CheckedSet<E>
+            implements java.util.SortedSet<E>, java.io.Serializable {
+
+        CheckedSortedSet(java.util.SortedSet<E> s, java.lang.Class<E> type) {
+            super(null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super E> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E first() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E last() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> subSet(E fromElement, E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> headSet(E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> tailSet(E fromElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1599911165492914959L; // 0x163406ba7362eb0fL
+
+        private final java.util.SortedSet<E> ss;
+
+        {
+            ss = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CopiesList<E> extends java.util.AbstractList<E>
+            implements java.util.RandomAccess, java.io.Serializable {
+
+        CopiesList(int n, E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int indexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int lastIndexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final E element;
+
+        {
+            element = null;
+        }
+
+        final int n;
+
+        {
+            n = 0;
+        }
+
+        private static final long serialVersionUID = 2739099268398711800L; // 0x26033c45b17003f8L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptyEnumeration<E> implements java.util.Enumeration<E> {
+
+        private EmptyEnumeration() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasMoreElements() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E nextElement() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.Collections.EmptyEnumeration<java.lang.Object> EMPTY_ENUMERATION;
+
+        static {
+            EMPTY_ENUMERATION = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptyIterator<E> implements java.util.Iterator<E> {
+
+        private EmptyIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.Collections.EmptyIterator<java.lang.Object> EMPTY_ITERATOR;
+
+        static {
+            EMPTY_ITERATOR = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptyList<E> extends java.util.AbstractList<E>
+            implements java.util.RandomAccess, java.io.Serializable {
+
+        @UnsupportedAppUsage
+        private EmptyList() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 8842843931221139166L; // 0x7ab817b43ca79edeL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptyListIterator<E> extends java.util.Collections.EmptyIterator<E>
+            implements java.util.ListIterator<E> {
+
+        private EmptyListIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.Collections.EmptyListIterator<java.lang.Object> EMPTY_ITERATOR;
+
+        static {
+            EMPTY_ITERATOR = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptyMap<K, V> extends java.util.AbstractMap<K, V>
+            implements java.io.Serializable {
+
+        @UnsupportedAppUsage
+        private EmptyMap() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsKey(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsValue(java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V get(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<V> values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getOrDefault(java.lang.Object k, V defaultValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V putIfAbsent(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V replace(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfAbsent(
+                K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfPresent(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V compute(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V merge(
+                K key,
+                V value,
+                java.util.function.BiFunction<? super V, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 6428348081105594320L; // 0x593614855adce7d0L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class EmptySet<E> extends java.util.AbstractSet<E>
+            implements java.io.Serializable {
+
+        private EmptySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1582296315990362920L; // 0x15f5721db403cb28L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ReverseComparator
+            implements java.util.Comparator<java.lang.Comparable<java.lang.Object>>,
+                    java.io.Serializable {
+
+        private ReverseComparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int compare(
+                java.lang.Comparable<java.lang.Object> c1,
+                java.lang.Comparable<java.lang.Object> c2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<java.lang.Comparable<java.lang.Object>> reversed() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.util.Collections.ReverseComparator REVERSE_ORDER;
+
+        static {
+            REVERSE_ORDER = null;
+        }
+
+        private static final long serialVersionUID = 7207038068494060240L; // 0x64048af0534e4ad0L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ReverseComparator2<T>
+            implements java.util.Comparator<T>, java.io.Serializable {
+
+        ReverseComparator2(java.util.Comparator<T> cmp) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int compare(T t1, T t2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<T> reversed() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.Comparator<T> cmp;
+
+        {
+            cmp = null;
+        }
+
+        private static final long serialVersionUID = 4374092139857L; // 0x3fa6c354d51L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SetFromMap<E> extends java.util.AbstractSet<E>
+            implements java.util.Set<E>, java.io.Serializable {
+
+        SetFromMap(java.util.Map<E, java.lang.Boolean> map) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void readObject(java.io.ObjectInputStream stream)
+                throws java.lang.ClassNotFoundException, java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Map<E, java.lang.Boolean> m;
+
+        {
+            m = null;
+        }
+
+        private transient java.util.Set<E> s;
+
+        private static final long serialVersionUID = 2454657854757543876L; // 0x2210b25045f21fc4L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SingletonList<E> extends java.util.AbstractList<E>
+            implements java.util.RandomAccess, java.io.Serializable {
+
+        SingletonList(E obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final E element;
+
+        {
+            element = null;
+        }
+
+        private static final long serialVersionUID = 3093736618740652951L; // 0x2aef29103ca79b97L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SingletonMap<K, V> extends java.util.AbstractMap<K, V>
+            implements java.io.Serializable {
+
+        SingletonMap(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsKey(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsValue(java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V get(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<V> values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getOrDefault(java.lang.Object key, V defaultValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V putIfAbsent(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V replace(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfAbsent(
+                K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfPresent(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V compute(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V merge(
+                K key,
+                V value,
+                java.util.function.BiFunction<? super V, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+        private final K k;
+
+        {
+            k = null;
+        }
+
+        private transient java.util.Set<K> keySet;
+
+        private static final long serialVersionUID = -6979724477215052911L; // 0x9f230991717f6b91L
+
+        private final V v;
+
+        {
+            v = null;
+        }
+
+        private transient java.util.Collection<V> values;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SingletonSet<E> extends java.util.AbstractSet<E>
+            implements java.io.Serializable {
+
+        SingletonSet(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final E element;
+
+        {
+            element = null;
+        }
+
+        private static final long serialVersionUID = 3193687207550431679L; // 0x2c52419829c0b1bfL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedCollection<E>
+            implements java.util.Collection<E>, java.io.Serializable {
+
+        SynchronizedCollection(java.util.Collection<E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedCollection(java.util.Collection<E> c, java.lang.Object mutex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(java.util.Collection<? extends E> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        final java.util.Collection<E> c;
+
+        {
+            c = null;
+        }
+
+        final java.lang.Object mutex;
+
+        {
+            mutex = null;
+        }
+
+        private static final long serialVersionUID = 3053995032091335093L; // 0x2a61f84d099c99b5L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedList<E> extends java.util.Collections.SynchronizedCollection<E>
+            implements java.util.List<E> {
+
+        SynchronizedList(java.util.List<E> list) {
+            super((java.util.Collection) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedList(java.util.List<E> list, java.lang.Object mutex) {
+            super((java.util.Collection) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int indexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int lastIndexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(int index, java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        final java.util.List<E> list;
+
+        {
+            list = null;
+        }
+
+        private static final long serialVersionUID = -7754090372962971524L; // 0x9463efe38344107cL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SynchronizedMap<K, V>
+            implements java.util.Map<K, V>, java.io.Serializable {
+
+        SynchronizedMap(java.util.Map<K, V> m) {
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedMap(java.util.Map<K, V> m, java.lang.Object mutex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsKey(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsValue(java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V get(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V put(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void putAll(java.util.Map<? extends K, ? extends V> map) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<V> values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getOrDefault(java.lang.Object k, V defaultValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V putIfAbsent(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V replace(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfAbsent(
+                K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfPresent(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V compute(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V merge(
+                K key,
+                V value,
+                java.util.function.BiFunction<? super V, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+        private transient java.util.Set<K> keySet;
+
+        @UnsupportedAppUsage
+        private final java.util.Map<K, V> m;
+
+        {
+            m = null;
+        }
+
+        final java.lang.Object mutex;
+
+        {
+            mutex = null;
+        }
+
+        private static final long serialVersionUID = 1978198479659022715L; // 0x1b73f9094b4b397bL
+
+        private transient java.util.Collection<V> values;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedNavigableMap<K, V>
+            extends java.util.Collections.SynchronizedSortedMap<K, V>
+            implements java.util.NavigableMap<K, V> {
+
+        SynchronizedNavigableMap(java.util.NavigableMap<K, V> m) {
+            super((java.util.SortedMap) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedNavigableMap(java.util.NavigableMap<K, V> m, java.lang.Object mutex) {
+            super((java.util.SortedMap) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lowerEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lowerKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> floorEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K floorKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> ceilingEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K ceilingKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> higherEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K higherKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> firstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollFirstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollLastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> descendingMap() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> navigableKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> descendingKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> subMap(K fromKey, K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> headMap(K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> tailMap(K fromKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> subMap(
+                K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.NavigableMap<K, V> nm;
+
+        {
+            nm = null;
+        }
+
+        private static final long serialVersionUID = 699392247599746807L; // 0x9b4bd8b2cd84ef7L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedNavigableSet<E> extends java.util.Collections.SynchronizedSortedSet<E>
+            implements java.util.NavigableSet<E> {
+
+        SynchronizedNavigableSet(java.util.NavigableSet<E> s) {
+            super((java.util.SortedSet) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedNavigableSet(java.util.NavigableSet<E> s, java.lang.Object mutex) {
+            super((java.util.SortedSet) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public E lower(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E floor(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E ceiling(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E higher(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollFirst() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollLast() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> descendingSet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> descendingIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> subSet(E fromElement, E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> headSet(E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> tailSet(E fromElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> subSet(
+                E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.NavigableSet<E> ns;
+
+        {
+            ns = null;
+        }
+
+        private static final long serialVersionUID = -5505529816273629798L; // 0xb3986dcd38b04d9aL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedRandomAccessList<E> extends java.util.Collections.SynchronizedList<E>
+            implements java.util.RandomAccess {
+
+        SynchronizedRandomAccessList(java.util.List<E> list) {
+            super((java.util.List) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedRandomAccessList(java.util.List<E> list, java.lang.Object mutex) {
+            super((java.util.List) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object writeReplace() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1530674583602358482L; // 0x153e0c6c865668d2L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedSet<E> extends java.util.Collections.SynchronizedCollection<E>
+            implements java.util.Set<E> {
+
+        SynchronizedSet(java.util.Set<E> s) {
+            super((java.util.Collection) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedSet(java.util.Set<E> s, java.lang.Object mutex) {
+            super((java.util.Collection) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 487447009682186044L; // 0x6c3c27902eedf3cL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedSortedMap<K, V> extends java.util.Collections.SynchronizedMap<K, V>
+            implements java.util.SortedMap<K, V> {
+
+        SynchronizedSortedMap(java.util.SortedMap<K, V> m) {
+            super((java.util.Map) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedSortedMap(java.util.SortedMap<K, V> m, java.lang.Object mutex) {
+            super((java.util.Map) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super K> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> subMap(K fromKey, K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> headMap(K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> tailMap(K fromKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K firstKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lastKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -8798146769416483793L; // 0x85e6b420b72e0c2fL
+
+        private final java.util.SortedMap<K, V> sm;
+
+        {
+            sm = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class SynchronizedSortedSet<E> extends java.util.Collections.SynchronizedSet<E>
+            implements java.util.SortedSet<E> {
+
+        SynchronizedSortedSet(java.util.SortedSet<E> s) {
+            super((java.util.Set) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        SynchronizedSortedSet(java.util.SortedSet<E> s, java.lang.Object mutex) {
+            super((java.util.Set) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super E> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> subSet(E fromElement, E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> headSet(E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> tailSet(E fromElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E first() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E last() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 8695801310862127406L; // 0x78adb1384b50312eL
+
+        private final java.util.SortedSet<E> ss;
+
+        {
+            ss = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableCollection<E>
+            implements java.util.Collection<E>, java.io.Serializable {
+
+        UnmodifiableCollection(java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(java.util.Collection<? extends E> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> coll) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> stream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.stream.Stream<E> parallelStream() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        final java.util.Collection<? extends E> c;
+
+        {
+            c = null;
+        }
+
+        private static final long serialVersionUID = 1820017752578914078L; // 0x19420080cb5ef71eL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableList<E> extends java.util.Collections.UnmodifiableCollection<E>
+            implements java.util.List<E> {
+
+        UnmodifiableList(java.util.List<? extends E> list) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int indexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int lastIndexOf(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean addAll(int index, java.util.Collection<? extends E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.List<? extends E> list;
+
+        {
+            list = null;
+        }
+
+        private static final long serialVersionUID = -283967356065247728L; // 0xfc0f2531b5ec8e10L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class UnmodifiableMap<K, V>
+            implements java.util.Map<K, V>, java.io.Serializable {
+
+        UnmodifiableMap(java.util.Map<? extends K, ? extends V> m) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsKey(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean containsValue(java.lang.Object val) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V get(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V put(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void putAll(java.util.Map<? extends K, ? extends V> m) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<K> keySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<V> values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getOrDefault(java.lang.Object k, V defaultValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(
+                java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V putIfAbsent(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key, java.lang.Object value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V replace(K key, V value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfAbsent(
+                K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V computeIfPresent(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V compute(
+                K key,
+                java.util.function.BiFunction<? super K, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V merge(
+                K key,
+                V value,
+                java.util.function.BiFunction<? super V, ? super V, ? extends V>
+                        remappingFunction) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+        private transient java.util.Set<K> keySet;
+
+        @UnsupportedAppUsage
+        private final java.util.Map<? extends K, ? extends V> m;
+
+        {
+            m = null;
+        }
+
+        private static final long serialVersionUID = -1034234728574286014L; // 0xf1a5a8fe74f50742L
+
+        private transient java.util.Collection<V> values;
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        static class UnmodifiableEntrySet<K, V>
+                extends java.util.Collections.UnmodifiableSet<java.util.Map.Entry<K, V>> {
+
+            UnmodifiableEntrySet(
+                    java.util.Set<? extends java.util.Map.Entry<? extends K, ? extends V>> s) {
+                super(null);
+                throw new RuntimeException("Stub!");
+            }
+
+            static <K, V> java.util.function.Consumer<java.util.Map.Entry<K, V>> entryConsumer(
+                    java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public void forEach(
+                    java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.Spliterator<java.util.Map.Entry<K, V>> spliterator() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.stream.Stream<java.util.Map.Entry<K, V>> stream() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.stream.Stream<java.util.Map.Entry<K, V>> parallelStream() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.lang.Object[] toArray() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public <T> T[] toArray(T[] a) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean contains(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean containsAll(java.util.Collection<?> coll) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean equals(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            private static final long serialVersionUID =
+                    7854390611657943733L; // 0x6d0066a59f08eab5L
+
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            private static class UnmodifiableEntry<K, V> implements java.util.Map.Entry<K, V> {
+
+                UnmodifiableEntry(java.util.Map.Entry<? extends K, ? extends V> e) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public K getKey() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public V getValue() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public V setValue(V value) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public int hashCode() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public boolean equals(java.lang.Object o) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public java.lang.String toString() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                private java.util.Map.Entry<? extends K, ? extends V> e;
+            }
+
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            static final class UnmodifiableEntrySetSpliterator<K, V>
+                    implements java.util.Spliterator<java.util.Map.Entry<K, V>> {
+
+                UnmodifiableEntrySetSpliterator(
+                        java.util.Spliterator<java.util.Map.Entry<K, V>> s) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public boolean tryAdvance(
+                        java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public void forEachRemaining(
+                        java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public java.util.Spliterator<java.util.Map.Entry<K, V>> trySplit() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public long estimateSize() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public long getExactSizeIfKnown() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public int characteristics() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public boolean hasCharacteristics(int characteristics) {
+                    throw new RuntimeException("Stub!");
+                }
+
+                public java.util.Comparator<? super java.util.Map.Entry<K, V>> getComparator() {
+                    throw new RuntimeException("Stub!");
+                }
+
+                final java.util.Spliterator<java.util.Map.Entry<K, V>> s;
+
+                {
+                    s = null;
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableNavigableMap<K, V>
+            extends java.util.Collections.UnmodifiableSortedMap<K, V>
+            implements java.util.NavigableMap<K, V>, java.io.Serializable {
+
+        UnmodifiableNavigableMap(java.util.NavigableMap<K, ? extends V> m) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lowerKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K floorKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K ceilingKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K higherKey(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lowerEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> floorEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> ceilingEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> higherEntry(K key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> firstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> lastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollFirstEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> pollLastEntry() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> descendingMap() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> navigableKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<K> descendingKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> subMap(
+                K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.util.Collections.UnmodifiableNavigableMap.EmptyNavigableMap<?, ?>
+                EMPTY_NAVIGABLE_MAP;
+
+        static {
+            EMPTY_NAVIGABLE_MAP = null;
+        }
+
+        private final java.util.NavigableMap<K, ? extends V> nm;
+
+        {
+            nm = null;
+        }
+
+        private static final long serialVersionUID = -4858195264774772197L; // 0xbc943925819d6a1bL
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private static class EmptyNavigableMap<K, V>
+                extends java.util.Collections.UnmodifiableNavigableMap<K, V>
+                implements java.io.Serializable {
+
+            EmptyNavigableMap() {
+                super(null);
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.util.NavigableSet<K> navigableKeySet() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private java.lang.Object readResolve() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private static final long serialVersionUID =
+                    -2239321462712562324L; // 0xe0ec54fe7d1c0d6cL
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableNavigableSet<E> extends java.util.Collections.UnmodifiableSortedSet<E>
+            implements java.util.NavigableSet<E>, java.io.Serializable {
+
+        UnmodifiableNavigableSet(java.util.NavigableSet<E> s) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public E lower(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E floor(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E ceiling(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E higher(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollFirst() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E pollLast() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> descendingSet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> descendingIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> subSet(
+                E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.util.NavigableSet<?> EMPTY_NAVIGABLE_SET;
+
+        static {
+            EMPTY_NAVIGABLE_SET = null;
+        }
+
+        private final java.util.NavigableSet<E> ns;
+
+        {
+            ns = null;
+        }
+
+        private static final long serialVersionUID = -6027448201786391929L; // 0xac5a33cb96748287L
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private static class EmptyNavigableSet<E>
+                extends java.util.Collections.UnmodifiableNavigableSet<E>
+                implements java.io.Serializable {
+
+            public EmptyNavigableSet() {
+                super(null);
+                throw new RuntimeException("Stub!");
+            }
+
+            private java.lang.Object readResolve() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private static final long serialVersionUID =
+                    -6291252904449939134L; // 0xa8b0fad0de1de942L
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableRandomAccessList<E> extends java.util.Collections.UnmodifiableList<E>
+            implements java.util.RandomAccess {
+
+        UnmodifiableRandomAccessList(java.util.List<? extends E> list) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object writeReplace() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -2542308836966382001L; // 0xdcb7e7951f48464fL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableSet<E> extends java.util.Collections.UnmodifiableCollection<E>
+            implements java.util.Set<E>, java.io.Serializable {
+
+        UnmodifiableSet(java.util.Set<? extends E> s) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -9215047833775013803L; // 0x801d92d18f9b8055L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableSortedMap<K, V> extends java.util.Collections.UnmodifiableMap<K, V>
+            implements java.util.SortedMap<K, V>, java.io.Serializable {
+
+        UnmodifiableSortedMap(java.util.SortedMap<K, ? extends V> m) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super K> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> subMap(K fromKey, K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> headMap(K toKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedMap<K, V> tailMap(K fromKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K firstKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K lastKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -8806743815996713206L; // 0x85c82928d3a5d70aL
+
+        private final java.util.SortedMap<K, ? extends V> sm;
+
+        {
+            sm = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class UnmodifiableSortedSet<E> extends java.util.Collections.UnmodifiableSet<E>
+            implements java.util.SortedSet<E>, java.io.Serializable {
+
+        UnmodifiableSortedSet(java.util.SortedSet<E> s) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Comparator<? super E> comparator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> subSet(E fromElement, E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> headSet(E toElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.SortedSet<E> tailSet(E fromElement) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E first() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E last() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -4929149591599911165L; // 0xbb98248febecef03L
+
+        private final java.util.SortedSet<E> ss;
+
+        {
+            ss = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/EnumMap.java b/ojluni/annotations/hiddenapi/java/util/EnumMap.java
new file mode 100644
index 0000000..81cd885
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/EnumMap.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class EnumMap<K extends java.lang.Enum<K>, V> extends java.util.AbstractMap<K, V>
+        implements java.io.Serializable, java.lang.Cloneable {
+
+    public EnumMap(java.lang.Class<K> keyType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public EnumMap(java.util.EnumMap<K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public EnumMap(java.util.Map<K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object maskNull(java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private V unmaskNull(java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsValue(java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsKey(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean containsMapping(java.lang.Object key, java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V get(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V put(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V remove(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean removeMapping(java.lang.Object key, java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isValidKey(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putAll(java.util.Map<? extends K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<K> keySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Collection<V> values() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean equals(java.util.EnumMap<?, ?> em) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int entryHashCode(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.EnumMap<K, V> clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void typeCheck(K key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <K extends java.lang.Enum<K>> K[] getKeyUniverse(java.lang.Class<K> keyType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.Object NULL;
+
+    static {
+        NULL = null;
+    }
+
+    private static final java.lang.Enum<?>[] ZERO_LENGTH_ENUM_ARRAY;
+
+    static {
+        ZERO_LENGTH_ENUM_ARRAY = new java.lang.Enum[0];
+    }
+
+    private transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+    @UnsupportedAppUsage
+    private final java.lang.Class<K> keyType;
+
+    {
+        keyType = null;
+    }
+
+    private transient K[] keyUniverse;
+
+    private static final long serialVersionUID = 458661240069192865L; // 0x65d7df7be907ca1L
+
+    private transient int size = 0; // 0x0
+
+    private transient java.lang.Object[] vals;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class EntryIterator
+            extends EnumMapIterator<java.util.Map.Entry<K, V>> {
+
+        private EntryIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Map.Entry<K, V> next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.util.EnumMap.EntryIterator.Entry lastReturnedEntry;
+
+        @SuppressWarnings({"unchecked", "deprecation", "all"})
+        private class Entry implements java.util.Map.Entry<K, V> {
+
+            private Entry(int index) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public K getKey() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public V getValue() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public V setValue(V value) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public boolean equals(java.lang.Object o) {
+                throw new RuntimeException("Stub!");
+            }
+
+            public int hashCode() {
+                throw new RuntimeException("Stub!");
+            }
+
+            public java.lang.String toString() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private void checkIndexForEntryUse() {
+                throw new RuntimeException("Stub!");
+            }
+
+            private int index;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class EntrySet extends java.util.AbstractSet<java.util.Map.Entry<K, V>> {
+
+        private EntrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T[] toArray(T[] a) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object[] fillEntryArray(java.lang.Object[] a) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private abstract class EnumMapIterator<T> implements java.util.Iterator<T> {
+
+        private EnumMapIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkLastReturnedIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int index = 0; // 0x0
+
+        int lastReturnedIndex = -1; // 0xffffffff
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class KeyIterator extends EnumMapIterator<K> {
+
+        private KeyIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class KeySet extends java.util.AbstractSet<K> {
+
+        private KeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<K> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ValueIterator extends EnumMapIterator<V> {
+
+        private ValueIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Values extends java.util.AbstractCollection<V> {
+
+        private Values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<V> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/EnumSet.java b/ojluni/annotations/hiddenapi/java/util/EnumSet.java
new file mode 100644
index 0000000..f8edb19
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/EnumSet.java
@@ -0,0 +1,161 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class EnumSet<E extends java.lang.Enum<E>> extends java.util.AbstractSet<E>
+        implements java.lang.Cloneable, java.io.Serializable {
+
+    EnumSet(java.lang.Class<E> elementType, java.lang.Enum<?>[] universe) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> noneOf(
+            java.lang.Class<E> elementType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> allOf(
+            java.lang.Class<E> elementType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void addAll();
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(
+            java.util.EnumSet<E> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(
+            java.util.Collection<E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> complementOf(
+            java.util.EnumSet<E> s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E e1, E e2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E e1, E e2, E e3) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E e1, E e2, E e3, E e4) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(
+            E e1, E e2, E e3, E e4, E e5) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E first, E... rest) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> range(E from, E to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void addRange(E from, E to);
+
+    public java.util.EnumSet<E> clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    abstract void complement();
+
+    final void typeCheck(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <E extends java.lang.Enum<E>> E[] getUniverse(java.lang.Class<E> elementType) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.Object writeReplace() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream)
+            throws java.io.InvalidObjectException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Enum<?>[] ZERO_LENGTH_ENUM_ARRAY;
+
+    @UnsupportedAppUsage
+    final java.lang.Class<E> elementType;
+
+    {
+        elementType = null;
+    }
+
+    final java.lang.Enum<?>[] universe;
+
+    {
+        universe = new java.lang.Enum[0];
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SerializationProxy<E extends java.lang.Enum<E>>
+            implements java.io.Serializable {
+
+        SerializationProxy(java.util.EnumSet<E> set) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object readResolve() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.Class<E> elementType;
+
+        {
+            elementType = null;
+        }
+
+        private final java.lang.Enum<?>[] elements;
+
+        {
+            elements = new java.lang.Enum[0];
+        }
+
+        private static final long serialVersionUID = 362491234563181265L; // 0x507d3db7654cad1L
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/HashMap.java b/ojluni/annotations/hiddenapi/java/util/HashMap.java
new file mode 100644
index 0000000..af1c342
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/HashMap.java
@@ -0,0 +1,705 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@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(java.util.Map<? extends K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int hash(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.Class<?> comparableClassFor(java.lang.Object x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int compareComparables(java.lang.Class<?> kc, java.lang.Object k, java.lang.Object x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int tableSizeFor(int cap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void putMapEntries(java.util.Map<? extends K, ? extends V> m, boolean evict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V get(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.util.HashMap.Node<K, V> getNode(int hash, java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsKey(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V put(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.util.HashMap.Node<K, V>[] resize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void treeifyBin(java.util.HashMap.Node<K, V>[] tab, int hash) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putAll(java.util.Map<? extends K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V remove(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.util.HashMap.Node<K, V> removeNode(
+            int hash,
+            java.lang.Object key,
+            java.lang.Object value,
+            boolean matchValue,
+            boolean movable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsValue(java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<K> keySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Collection<V> values() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V getOrDefault(java.lang.Object key, V defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V putIfAbsent(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object key, java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean replace(K key, V oldValue, V newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V replace(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V computeIfAbsent(
+            K key, java.util.function.Function<? super K, ? extends V> mappingFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V computeIfPresent(
+            K key,
+            java.util.function.BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V compute(
+            K key,
+            java.util.function.BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V merge(
+            K key,
+            V value,
+            java.util.function.BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void replaceAll(
+            java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final float loadFactor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int capacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.Node<K, V> newNode(
+            int hash, K key, V value, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.Node<K, V> replacementNode(
+            java.util.HashMap.Node<K, V> p, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.TreeNode<K, V> newTreeNode(
+            int hash, K key, V value, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.TreeNode<K, V> replacementTreeNode(
+            java.util.HashMap.Node<K, V> p, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void reinitialize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeAccess(java.util.HashMap.Node<K, V> p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeInsertion(boolean evict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeRemoval(java.util.HashMap.Node<K, V> p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void internalWriteEntries(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int DEFAULT_INITIAL_CAPACITY = 16; // 0x10
+
+    static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+    static final int MAXIMUM_CAPACITY = 1073741824; // 0x40000000
+
+    static final int MIN_TREEIFY_CAPACITY = 64; // 0x40
+
+    static final int TREEIFY_THRESHOLD = 8; // 0x8
+
+    static final int UNTREEIFY_THRESHOLD = 6; // 0x6
+
+    transient java.util.Set<java.util.Map.Entry<K, V>> entrySet;
+
+    final float loadFactor;
+
+    {
+        loadFactor = 0;
+    }
+
+    @UnsupportedAppUsage
+    transient int modCount;
+
+    private static final long serialVersionUID = 362498820763181265L; // 0x507dac1c31660d1L
+
+    transient int size;
+
+    @UnsupportedAppUsage
+    transient java.util.HashMap.Node<K, V>[] table;
+
+    int threshold;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class EntryIterator extends java.util.HashMap.HashIterator
+            implements java.util.Iterator<java.util.Map.Entry<K, V>> {
+
+        @UnsupportedAppUsage(trackingBug = 122551864)
+        public java.util.Map.Entry<K, V> next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class EntrySet extends java.util.AbstractSet<java.util.Map.Entry<K, V>> {
+
+        EntrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<java.util.Map.Entry<K, V>> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class EntrySpliterator<K, V> extends java.util.HashMap.HashMapSpliterator<K, V>
+            implements java.util.Spliterator<java.util.Map.Entry<K, V>> {
+
+        EntrySpliterator(
+                java.util.HashMap<K, V> m, int origin, int fence, int est, int expectedModCount) {
+            super(null, 0, 0, 0, 0);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.HashMap.EntrySpliterator<K, V> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(
+                java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(
+                java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    abstract class HashIterator {
+
+        HashIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.HashMap.Node<K, V> nextNode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.Node<K, V> current;
+
+        int expectedModCount;
+
+        int index;
+
+        java.util.HashMap.Node<K, V> next;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class HashMapSpliterator<K, V> {
+
+        HashMapSpliterator(
+                java.util.HashMap<K, V> m, int origin, int fence, int est, int expectedModCount) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.Node<K, V> current;
+
+        int est;
+
+        int expectedModCount;
+
+        int fence;
+
+        int index;
+
+        final java.util.HashMap<K, V> map;
+
+        {
+            map = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class KeyIterator extends java.util.HashMap.HashIterator
+            implements java.util.Iterator<K> {
+
+        public K next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class KeySet extends java.util.AbstractSet<K> {
+
+        KeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<K> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<K> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super K> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class KeySpliterator<K, V> extends java.util.HashMap.HashMapSpliterator<K, V>
+            implements java.util.Spliterator<K> {
+
+        KeySpliterator(
+                java.util.HashMap<K, V> m, int origin, int fence, int est, int expectedModCount) {
+            super(null, 0, 0, 0, 0);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.HashMap.KeySpliterator<K, V> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super K> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super K> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class Node<K, V> implements java.util.Map.Entry<K, V> {
+
+        Node(int hash, K key, V value, java.util.HashMap.Node<K, V> next) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final K getKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final V getValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final V setValue(V newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final int hash;
+
+        {
+            hash = 0;
+        }
+
+        @UnsupportedAppUsage
+        final K key;
+
+        {
+            key = null;
+        }
+
+        @UnsupportedAppUsage
+        java.util.HashMap.Node<K, V> next;
+
+        @UnsupportedAppUsage
+        V value;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class TreeNode<K, V> extends java.util.LinkedHashMap.LinkedHashMapEntry<K, V> {
+
+        TreeNode(int hash, K key, V val, java.util.HashMap.Node<K, V> next) {
+            super(0, null, null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.TreeNode<K, V> root() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> void moveRootToFront(
+                java.util.HashMap.Node<K, V>[] tab, java.util.HashMap.TreeNode<K, V> root) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.TreeNode<K, V> find(int h, java.lang.Object k, java.lang.Class<?> kc) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.TreeNode<K, V> getTreeNode(int h, java.lang.Object k) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static int tieBreakOrder(java.lang.Object a, java.lang.Object b) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void treeify(java.util.HashMap.Node<K, V>[] tab) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.Node<K, V> untreeify(java.util.HashMap<K, V> map) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.TreeNode<K, V> putTreeVal(
+                java.util.HashMap<K, V> map, java.util.HashMap.Node<K, V>[] tab, int h, K k, V v) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void removeTreeNode(
+                java.util.HashMap<K, V> map, java.util.HashMap.Node<K, V>[] tab, boolean movable) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void split(
+                java.util.HashMap<K, V> map,
+                java.util.HashMap.Node<K, V>[] tab,
+                int index,
+                int bit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> java.util.HashMap.TreeNode<K, V> rotateLeft(
+                java.util.HashMap.TreeNode<K, V> root, java.util.HashMap.TreeNode<K, V> p) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> java.util.HashMap.TreeNode<K, V> rotateRight(
+                java.util.HashMap.TreeNode<K, V> root, java.util.HashMap.TreeNode<K, V> p) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> java.util.HashMap.TreeNode<K, V> balanceInsertion(
+                java.util.HashMap.TreeNode<K, V> root, java.util.HashMap.TreeNode<K, V> x) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> java.util.HashMap.TreeNode<K, V> balanceDeletion(
+                java.util.HashMap.TreeNode<K, V> root, java.util.HashMap.TreeNode<K, V> x) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static <K, V> boolean checkInvariants(java.util.HashMap.TreeNode<K, V> t) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap.TreeNode<K, V> left;
+
+        java.util.HashMap.TreeNode<K, V> parent;
+
+        java.util.HashMap.TreeNode<K, V> prev;
+
+        boolean red;
+
+        java.util.HashMap.TreeNode<K, V> right;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class ValueIterator extends java.util.HashMap.HashIterator
+            implements java.util.Iterator<V> {
+
+        public V next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class ValueSpliterator<K, V> extends java.util.HashMap.HashMapSpliterator<K, V>
+            implements java.util.Spliterator<V> {
+
+        ValueSpliterator(
+                java.util.HashMap<K, V> m, int origin, int fence, int est, int expectedModCount) {
+            super(null, 0, 0, 0, 0);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.HashMap.ValueSpliterator<K, V> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class Values extends java.util.AbstractCollection<V> {
+
+        Values() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<V> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<V> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/HashSet.java b/ojluni/annotations/hiddenapi/java/util/HashSet.java
new file mode 100644
index 0000000..a006121
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/HashSet.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class HashSet<E> extends java.util.AbstractSet<E>
+        implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
+
+    public HashSet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public HashSet(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public HashSet(int initialCapacity, float loadFactor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public HashSet(int initialCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.Object PRESENT;
+
+    static {
+        PRESENT = null;
+    }
+
+    @UnsupportedAppUsage
+    private transient java.util.HashMap<E, java.lang.Object> map;
+
+    static final long serialVersionUID = -5024744406713321676L; // 0xba44859596b8b734L
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java b/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java
new file mode 100644
index 0000000..8294334
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java
@@ -0,0 +1,330 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LinkedHashMap<K, V> extends java.util.HashMap<K, V> implements java.util.Map<K, V> {
+
+    public LinkedHashMap(int initialCapacity, float loadFactor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedHashMap(int initialCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedHashMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedHashMap(java.util.Map<? extends K, ? extends V> m) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void linkNodeLast(java.util.LinkedHashMap.LinkedHashMapEntry<K, V> p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void transferLinks(
+            java.util.LinkedHashMap.LinkedHashMapEntry<K, V> src,
+            java.util.LinkedHashMap.LinkedHashMapEntry<K, V> dst) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void reinitialize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.Node<K, V> newNode(int hash, K key, V value, java.util.HashMap.Node<K, V> e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.Node<K, V> replacementNode(
+            java.util.HashMap.Node<K, V> p, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.TreeNode<K, V> newTreeNode(
+            int hash, K key, V value, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.HashMap.TreeNode<K, V> replacementTreeNode(
+            java.util.HashMap.Node<K, V> p, java.util.HashMap.Node<K, V> next) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeRemoval(java.util.HashMap.Node<K, V> e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeInsertion(boolean evict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void afterNodeAccess(java.util.HashMap.Node<K, V> e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void internalWriteEntries(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsValue(java.lang.Object value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V get(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V getOrDefault(java.lang.Object key, V defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.util.Map.Entry<K, V> eldest() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<K> keySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Collection<V> values() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.util.Map.Entry<K, V>> entrySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void forEach(java.util.function.BiConsumer<? super K, ? super V> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void replaceAll(
+            java.util.function.BiFunction<? super K, ? super V, ? extends V> function) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    final boolean accessOrder;
+
+    {
+        accessOrder = false;
+    }
+
+    transient java.util.LinkedHashMap.LinkedHashMapEntry<K, V> head;
+
+    private static final long serialVersionUID = 3801124242820219131L; // 0x34c04e5c106cc0fbL
+
+    transient java.util.LinkedHashMap.LinkedHashMapEntry<K, V> tail;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedEntryIterator extends java.util.LinkedHashMap.LinkedHashIterator
+            implements java.util.Iterator<java.util.Map.Entry<K, V>> {
+
+        public java.util.Map.Entry<K, V> next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedEntrySet extends java.util.AbstractSet<java.util.Map.Entry<K, V>> {
+
+        LinkedEntrySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<java.util.Map.Entry<K, V>> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<java.util.Map.Entry<K, V>> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super java.util.Map.Entry<K, V>> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    abstract class LinkedHashIterator {
+
+        LinkedHashIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.LinkedHashMap.LinkedHashMapEntry<K, V> nextNode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public final void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.LinkedHashMap.LinkedHashMapEntry<K, V> current;
+
+        int expectedModCount;
+
+        java.util.LinkedHashMap.LinkedHashMapEntry<K, V> next;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class LinkedHashMapEntry<K, V> extends java.util.HashMap.Node<K, V> {
+
+        LinkedHashMapEntry(int hash, K key, V value, java.util.HashMap.Node<K, V> next) {
+            super(0, null, null, null);
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.LinkedHashMap.LinkedHashMapEntry<K, V> after;
+
+        java.util.LinkedHashMap.LinkedHashMapEntry<K, V> before;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedKeyIterator extends java.util.LinkedHashMap.LinkedHashIterator
+            implements java.util.Iterator<K> {
+
+        public K next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedKeySet extends java.util.AbstractSet<K> {
+
+        LinkedKeySet() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<K> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<K> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super K> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedValueIterator extends java.util.LinkedHashMap.LinkedHashIterator
+            implements java.util.Iterator<V> {
+
+        public V next() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LinkedValues extends java.util.AbstractCollection<V> {
+
+        LinkedValues() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<V> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean contains(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<V> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super V> action) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/LinkedList.java b/ojluni/annotations/hiddenapi/java/util/LinkedList.java
new file mode 100644
index 0000000..c7eb048
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/LinkedList.java
@@ -0,0 +1,427 @@
+/*
+ * 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LinkedList<E> extends java.util.AbstractSequentialList<E>
+        implements java.util.List<E>,
+                java.util.Deque<E>,
+                java.lang.Cloneable,
+                java.io.Serializable {
+
+    public LinkedList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedList(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void linkFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void linkLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void linkBefore(E e, java.util.LinkedList.Node<E> succ) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E unlinkFirst(java.util.LinkedList.Node<E> f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E unlinkLast(java.util.LinkedList.Node<E> l) {
+        throw new RuntimeException("Stub!");
+    }
+
+    E unlink(java.util.LinkedList.Node<E> x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(int index, java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E get(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E set(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void add(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isElementIndex(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isPositionIndex(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String outOfBoundsMsg(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkElementIndex(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkPositionIndex(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.LinkedList.Node<E> node(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E element() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void push(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pop() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeFirstOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeLastOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ListIterator<E> listIterator(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> descendingIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.LinkedList<E> superClone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    transient java.util.LinkedList.Node<E> first;
+
+    transient java.util.LinkedList.Node<E> last;
+
+    private static final long serialVersionUID = 876323262645176354L; // 0xc29535d4a608822L
+
+    @UnsupportedAppUsage
+    transient int size = 0; // 0x0
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class DescendingIterator implements java.util.Iterator<E> {
+
+        private DescendingIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.LinkedList.ListItr itr;
+
+        {
+            itr = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class LLSpliterator<E> implements java.util.Spliterator<E> {
+
+        LLSpliterator(java.util.LinkedList<E> list, int est, int expectedModCount) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int getEst() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final int BATCH_UNIT = 1024; // 0x400
+
+        static final int MAX_BATCH = 33554432; // 0x2000000
+
+        int batch;
+
+        java.util.LinkedList.Node<E> current;
+
+        int est;
+
+        int expectedModCount;
+
+        final java.util.LinkedList<E> list;
+
+        {
+            list = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ListItr implements java.util.ListIterator<E> {
+
+        ListItr(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final void checkForComodification() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int expectedModCount;
+
+        private java.util.LinkedList.Node<E> lastReturned;
+
+        private java.util.LinkedList.Node<E> next;
+
+        private int nextIndex;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Node<E> {
+
+        Node(java.util.LinkedList.Node<E> prev, E element, java.util.LinkedList.Node<E> next) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        E item;
+
+        @UnsupportedAppUsage
+        java.util.LinkedList.Node<E> next;
+
+        java.util.LinkedList.Node<E> prev;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Locale.java b/ojluni/annotations/hiddenapi/java/util/Locale.java
new file mode 100644
index 0000000..3f6a54f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Locale.java
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+package java.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Locale implements java.lang.Cloneable, java.io.Serializable {
+
+    private Locale(
+            sun.util.locale.BaseLocale baseLocale, sun.util.locale.LocaleExtensions extensions) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Locale(java.lang.String language, java.lang.String country, java.lang.String variant) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Locale(java.lang.String language, java.lang.String country) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Locale(java.lang.String language) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static java.util.Locale createConstant(
+            java.lang.String lang, java.lang.String country) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.util.Locale getInstance(
+            java.lang.String language, java.lang.String country, java.lang.String variant) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.util.Locale getInstance(
+            java.lang.String language,
+            java.lang.String script,
+            java.lang.String country,
+            java.lang.String variant,
+            sun.util.locale.LocaleExtensions extensions) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static java.util.Locale getInstance(
+            sun.util.locale.BaseLocale baseloc, sun.util.locale.LocaleExtensions extensions) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale getDefault() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale getDefault(java.util.Locale.Category category) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale initDefault() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Locale initDefault(java.util.Locale.Category category) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setDefault(java.util.Locale newLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setDefault(
+            java.util.Locale.Category category, java.util.Locale newLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale[] getAvailableLocales() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String[] getISOCountries() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String[] getISOLanguages() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getLanguage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getScript() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCountry() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getVariant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Locale stripExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getExtension(char key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.Character> getExtensionKeys() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getUnicodeLocaleAttributes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getUnicodeLocaleType(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getUnicodeLocaleKeys() {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.util.locale.BaseLocale getBaseLocale() {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.util.locale.LocaleExtensions getLocaleExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toLanguageTag() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale forLanguageTag(java.lang.String languageTag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getISO3Language() throws java.util.MissingResourceException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getISO3Country() throws java.util.MissingResourceException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayLanguage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayLanguage(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String normalizeAndValidateLanguage(
+            java.lang.String language, boolean strict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isAsciiAlphaNum(java.lang.String string) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayScript() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayScript(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayCountry() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayCountry(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String normalizeAndValidateRegion(
+            java.lang.String region, boolean strict) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isValidBcp47Alpha(
+            java.lang.String string, int lowerBound, int upperBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isUnM49AreaCode(java.lang.String code) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayVariant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayVariant(java.util.Locale inLocale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String normalizeAndValidateVariant(java.lang.String variant) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isValidVariantSubtag(java.lang.String subTag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayName(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String formatList(
+            java.lang.String[] stringList,
+            java.lang.String listPattern,
+            java.lang.String listCompositionPattern) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String[] composeList(
+            java.text.MessageFormat format, java.lang.String[] list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isUnicodeExtensionKey(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream in)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object readResolve() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String convertOldISOCodes(java.lang.String language) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.util.locale.LocaleExtensions getCompatibilityExtensions(
+            java.lang.String language,
+            java.lang.String script,
+            java.lang.String country,
+            java.lang.String variant) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String adjustLanguageCode(java.lang.String languageCode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.util.Locale> filter(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.util.Locale> locales,
+            java.util.Locale.FilteringMode mode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.util.Locale> filter(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.util.Locale> locales) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.lang.String> filterTags(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.lang.String> tags,
+            java.util.Locale.FilteringMode mode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.lang.String> filterTags(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.lang.String> tags) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Locale lookup(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.util.Locale> locales) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String lookupTag(
+            java.util.List<java.util.Locale.LanguageRange> priorityList,
+            java.util.Collection<java.lang.String> tags) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.util.Locale CANADA;
+
+    static {
+        CANADA = null;
+    }
+
+    public static final java.util.Locale CANADA_FRENCH;
+
+    static {
+        CANADA_FRENCH = null;
+    }
+
+    public static final java.util.Locale CHINA;
+
+    static {
+        CHINA = null;
+    }
+
+    public static final java.util.Locale CHINESE;
+
+    static {
+        CHINESE = null;
+    }
+
+    private static final int DISPLAY_COUNTRY = 1; // 0x1
+
+    private static final int DISPLAY_LANGUAGE = 0; // 0x0
+
+    private static final int DISPLAY_SCRIPT = 3; // 0x3
+
+    private static final int DISPLAY_VARIANT = 2; // 0x2
+
+    public static final java.util.Locale ENGLISH;
+
+    static {
+        ENGLISH = null;
+    }
+
+    public static final java.util.Locale FRANCE;
+
+    static {
+        FRANCE = null;
+    }
+
+    public static final java.util.Locale FRENCH;
+
+    static {
+        FRENCH = null;
+    }
+
+    public static final java.util.Locale GERMAN;
+
+    static {
+        GERMAN = null;
+    }
+
+    public static final java.util.Locale GERMANY;
+
+    static {
+        GERMANY = null;
+    }
+
+    public static final java.util.Locale ITALIAN;
+
+    static {
+        ITALIAN = null;
+    }
+
+    public static final java.util.Locale ITALY;
+
+    static {
+        ITALY = null;
+    }
+
+    public static final java.util.Locale JAPAN;
+
+    static {
+        JAPAN = null;
+    }
+
+    public static final java.util.Locale JAPANESE;
+
+    static {
+        JAPANESE = null;
+    }
+
+    public static final java.util.Locale KOREA;
+
+    static {
+        KOREA = null;
+    }
+
+    public static final java.util.Locale KOREAN;
+
+    static {
+        KOREAN = null;
+    }
+
+    private static final java.util.Locale.Cache LOCALECACHE;
+
+    static {
+        LOCALECACHE = null;
+    }
+
+    public static final java.util.Locale PRC;
+
+    static {
+        PRC = null;
+    }
+
+    public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
+
+    public static final java.util.Locale ROOT;
+
+    static {
+        ROOT = null;
+    }
+
+    public static final java.util.Locale SIMPLIFIED_CHINESE;
+
+    static {
+        SIMPLIFIED_CHINESE = null;
+    }
+
+    public static final java.util.Locale TAIWAN;
+
+    static {
+        TAIWAN = null;
+    }
+
+    public static final java.util.Locale TRADITIONAL_CHINESE;
+
+    static {
+        TRADITIONAL_CHINESE = null;
+    }
+
+    public static final java.util.Locale UK;
+
+    static {
+        UK = null;
+    }
+
+    private static final java.lang.String UNDETERMINED_LANGUAGE = "und";
+
+    public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
+
+    public static final java.util.Locale US;
+
+    static {
+        US = null;
+    }
+
+    private transient sun.util.locale.BaseLocale baseLocale;
+
+    private static volatile java.util.Locale defaultDisplayLocale;
+
+    private static volatile java.util.Locale defaultFormatLocale;
+
+    private transient volatile int hashCodeValue = 0; // 0x0
+
+    private static volatile java.lang.String[] isoCountries;
+
+    private static volatile java.lang.String[] isoLanguages;
+
+    private transient volatile java.lang.String languageTag;
+
+    private transient sun.util.locale.LocaleExtensions localeExtensions;
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    static final long serialVersionUID = 9149081749638150636L; // 0x7ef811609c30f9ecL
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class Builder {
+
+        public Builder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setLocale(java.util.Locale locale) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setLanguageTag(java.lang.String languageTag) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setLanguage(java.lang.String language) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setScript(java.lang.String script) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setRegion(java.lang.String region) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setVariant(java.lang.String variant) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setExtension(char key, java.lang.String value) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder setUnicodeLocaleKeyword(
+                java.lang.String key, java.lang.String type) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder addUnicodeLocaleAttribute(java.lang.String attribute) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder removeUnicodeLocaleAttribute(java.lang.String attribute) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale.Builder clearExtensions() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Locale build() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final sun.util.locale.InternalLocaleBuilder localeBuilder;
+
+        {
+            localeBuilder = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Cache
+            extends sun.util.locale.LocaleObjectCache<
+                    java.util.Locale.LocaleKey, java.util.Locale> {
+
+        private Cache() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected java.util.Locale createObject(java.util.Locale.LocaleKey key) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum Category {
+        DISPLAY,
+        FORMAT;
+
+        private Category(
+                java.lang.String languageKey,
+                java.lang.String scriptKey,
+                java.lang.String countryKey,
+                java.lang.String variantKey) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private Category() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.lang.String countryKey = null;
+
+        final java.lang.String languageKey = null;
+
+        final java.lang.String scriptKey = null;
+
+        final java.lang.String variantKey = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum FilteringMode {
+        AUTOSELECT_FILTERING,
+        EXTENDED_FILTERING,
+        IGNORE_EXTENDED_RANGES,
+        MAP_EXTENDED_RANGES,
+        REJECT_EXTENDED_RANGES;
+
+        private FilteringMode() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class LanguageRange {
+
+        public LanguageRange(java.lang.String range) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public LanguageRange(java.lang.String range, double weight) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static boolean isSubtagIllFormed(java.lang.String subtag, boolean isFirstSubtag) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String getRange() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public double getWeight() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.util.List<java.util.Locale.LanguageRange> parse(
+                java.lang.String ranges) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.util.List<java.util.Locale.LanguageRange> parse(
+                java.lang.String ranges,
+                java.util.Map<java.lang.String, java.util.List<java.lang.String>> map) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.util.List<java.util.Locale.LanguageRange> mapEquivalents(
+                java.util.List<java.util.Locale.LanguageRange> priorityList,
+                java.util.Map<java.lang.String, java.util.List<java.lang.String>> map) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static final double MAX_WEIGHT = 1.0;
+
+        public static final double MIN_WEIGHT = 0.0;
+
+        private volatile int hash = 0; // 0x0
+
+        private final java.lang.String range;
+
+        {
+            range = null;
+        }
+
+        private final double weight;
+
+        {
+            weight = 0;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class LocaleKey {
+
+        private LocaleKey(
+                sun.util.locale.BaseLocale baseLocale,
+                sun.util.locale.LocaleExtensions extensions) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final sun.util.locale.BaseLocale base;
+
+        {
+            base = null;
+        }
+
+        private final sun.util.locale.LocaleExtensions exts;
+
+        {
+            exts = null;
+        }
+
+        private final int hash;
+
+        {
+            hash = 0;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class NoImagePreloadHolder {
+
+        private NoImagePreloadHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static volatile java.util.Locale defaultLocale;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/PriorityQueue.java b/ojluni/annotations/hiddenapi/java/util/PriorityQueue.java
new file mode 100644
index 0000000..b8d2a18
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/PriorityQueue.java
@@ -0,0 +1,277 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PriorityQueue<E> extends java.util.AbstractQueue<E> implements java.io.Serializable {
+
+    public PriorityQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(int initialCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(java.util.Comparator<? super E> comparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(int initialCapacity, java.util.Comparator<? super E> comparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(java.util.PriorityQueue<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityQueue(java.util.SortedSet<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initFromPriorityQueue(java.util.PriorityQueue<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initElementsFromCollection(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initFromCollection(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void grow(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int hugeCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean removeEq(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    E removeAt(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftUp(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftUpComparable(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftUpUsingComparator(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftDown(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftDownComparable(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void siftDownUsingComparator(int k, E x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void heapify() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Comparator<? super E> comparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int DEFAULT_INITIAL_CAPACITY = 11; // 0xb
+
+    private static final int MAX_ARRAY_SIZE = 2147483639; // 0x7ffffff7
+
+    private final java.util.Comparator<? super E> comparator;
+
+    {
+        comparator = null;
+    }
+
+    @UnsupportedAppUsage
+    transient int modCount;
+
+    @UnsupportedAppUsage
+    transient java.lang.Object[] queue;
+
+    private static final long serialVersionUID = -7720805057305804111L; // 0x94da30b4fb3f82b1L
+
+    @UnsupportedAppUsage
+    int size;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private final class Itr implements java.util.Iterator<E> {
+
+        private Itr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int cursor;
+
+        private int expectedModCount;
+
+        private java.util.ArrayDeque<E> forgetMeNot;
+
+        private int lastRet = -1; // 0xffffffff
+
+        private E lastRetElt;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class PriorityQueueSpliterator<E> implements java.util.Spliterator<E> {
+
+        PriorityQueueSpliterator(
+                java.util.PriorityQueue<E> pq, int origin, int fence, int expectedModCount) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.PriorityQueue.PriorityQueueSpliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int expectedModCount;
+
+        private int fence;
+
+        private int index;
+
+        private final java.util.PriorityQueue<E> pq;
+
+        {
+            pq = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Properties.java b/ojluni/annotations/hiddenapi/java/util/Properties.java
new file mode 100644
index 0000000..3aee2d1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Properties.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Properties extends java.util.Hashtable<java.lang.Object, java.lang.Object> {
+
+    public Properties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Properties(java.util.Properties defaults) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Object setProperty(java.lang.String key, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void load(java.io.Reader reader) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void load(java.io.InputStream inStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void load0(java.util.Properties.LineReader lr) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String loadConvert(char[] in, int off, int len, char[] convtBuf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private java.lang.String saveConvert(
+            java.lang.String theString, boolean escapeSpace, boolean escapeUnicode) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void writeComments(java.io.BufferedWriter bw, java.lang.String comments)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void save(java.io.OutputStream out, java.lang.String comments) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void store(java.io.Writer writer, java.lang.String comments) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void store(java.io.OutputStream out, java.lang.String comments)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void store0(java.io.BufferedWriter bw, java.lang.String comments, boolean escUnicode)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void loadFromXML(java.io.InputStream in)
+            throws java.io.IOException, java.util.InvalidPropertiesFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void storeToXML(java.io.OutputStream os, java.lang.String comment)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void storeToXML(
+            java.io.OutputStream os, java.lang.String comment, java.lang.String encoding)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getProperty(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getProperty(java.lang.String key, java.lang.String defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<?> propertyNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> stringPropertyNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void list(java.io.PrintStream out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void list(java.io.PrintWriter out) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void enumerate(java.util.Hashtable<java.lang.String, java.lang.Object> h) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void enumerateStringProperties(
+            java.util.Hashtable<java.lang.String, java.lang.String> h) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static char toHex(int nibble) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.util.Properties defaults;
+
+    private static final char[] hexDigit;
+
+    static {
+        hexDigit = new char[0];
+    }
+
+    private static final long serialVersionUID = 4112578634029874840L; // 0x3912d07a70363e98L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    class LineReader {
+
+        public LineReader(java.io.InputStream inStream) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public LineReader(java.io.Reader reader) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int readLine() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        byte[] inByteBuf;
+
+        char[] inCharBuf;
+
+        int inLimit = 0; // 0x0
+
+        int inOff = 0; // 0x0
+
+        java.io.InputStream inStream;
+
+        char[] lineBuf;
+
+        java.io.Reader reader;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Random.java b/ojluni/annotations/hiddenapi/java/util/Random.java
new file mode 100644
index 0000000..ce80aa1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Random.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 1995, 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;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Random implements java.io.Serializable {
+
+    public Random() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Random(long seed) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static long seedUniquifier() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long initialScramble(long seed) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSeed(long seed) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int next(int bits) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void nextBytes(byte[] bytes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final long internalNextLong(long origin, long bound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int internalNextInt(int origin, int bound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final double internalNextDouble(double origin, double bound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int nextInt() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int nextInt(int bound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long nextLong() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean nextBoolean() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public float nextFloat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public double nextDouble() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized double nextGaussian() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.IntStream ints(long streamSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.IntStream ints() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.IntStream ints(
+            long streamSize, int randomNumberOrigin, int randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.LongStream longs(long streamSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.LongStream longs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.LongStream longs(
+            long streamSize, long randomNumberOrigin, long randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.DoubleStream doubles(long streamSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.DoubleStream doubles() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.DoubleStream doubles(
+            long streamSize, double randomNumberOrigin, double randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.DoubleStream doubles(
+            double randomNumberOrigin, double randomNumberBound) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void resetSeed(long seedVal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final java.lang.String BadBound = "bound must be positive";
+
+    static final java.lang.String BadRange = "bound must be greater than origin";
+
+    static final java.lang.String BadSize = "size must be non-negative";
+
+    private static final double DOUBLE_UNIT = 1.1102230246251565E-16;
+
+    private static final long addend = 11L; // 0xbL
+
+    private boolean haveNextNextGaussian = false;
+
+    private static final long mask = 281474976710655L; // 0xffffffffffffL
+
+    private static final long multiplier = 25214903917L; // 0x5deece66dL
+
+    private double nextNextGaussian;
+
+    private final java.util.concurrent.atomic.AtomicLong seed;
+
+    {
+        seed = null;
+    }
+
+    private static final long seedOffset;
+
+    static {
+        seedOffset = 0;
+    }
+
+    private static final java.util.concurrent.atomic.AtomicLong seedUniquifier;
+
+    static {
+        seedUniquifier = null;
+    }
+
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+
+    static {
+        serialPersistentFields = new java.io.ObjectStreamField[0];
+    }
+
+    static final long serialVersionUID = 3905348978240129619L; // 0x363296344bf00a53L
+
+    private static final sun.misc.Unsafe unsafe;
+
+    static {
+        unsafe = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class RandomDoublesSpliterator implements java.util.Spliterator.OfDouble {
+
+        RandomDoublesSpliterator(
+                java.util.Random rng, long index, long fence, double origin, double bound) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Random.RandomDoublesSpliterator trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.DoubleConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.DoubleConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final double bound;
+
+        {
+            bound = 0;
+        }
+
+        final long fence;
+
+        {
+            fence = 0;
+        }
+
+        long index;
+
+        final double origin;
+
+        {
+            origin = 0;
+        }
+
+        final java.util.Random rng;
+
+        {
+            rng = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class RandomIntsSpliterator implements java.util.Spliterator.OfInt {
+
+        RandomIntsSpliterator(java.util.Random rng, long index, long fence, int origin, int bound) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Random.RandomIntsSpliterator trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.IntConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.IntConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final int bound;
+
+        {
+            bound = 0;
+        }
+
+        final long fence;
+
+        {
+            fence = 0;
+        }
+
+        long index;
+
+        final int origin;
+
+        {
+            origin = 0;
+        }
+
+        final java.util.Random rng;
+
+        {
+            rng = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class RandomLongsSpliterator implements java.util.Spliterator.OfLong {
+
+        RandomLongsSpliterator(
+                java.util.Random rng, long index, long fence, long origin, long bound) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Random.RandomLongsSpliterator trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.LongConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.LongConsumer consumer) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final long bound;
+
+        {
+            bound = 0;
+        }
+
+        final long fence;
+
+        {
+            fence = 0;
+        }
+
+        long index;
+
+        final long origin;
+
+        {
+            origin = 0;
+        }
+
+        final java.util.Random rng;
+
+        {
+            rng = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/TimerTask.java b/ojluni/annotations/hiddenapi/java/util/TimerTask.java
new file mode 100644
index 0000000..8a5c6d5
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/TimerTask.java
@@ -0,0 +1,67 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class TimerTask implements java.lang.Runnable {
+
+    protected TimerTask() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract void run();
+
+    public boolean cancel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long scheduledExecutionTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int CANCELLED = 3; // 0x3
+
+    static final int EXECUTED = 2; // 0x2
+
+    static final int SCHEDULED = 1; // 0x1
+
+    static final int VIRGIN = 0; // 0x0
+
+    final java.lang.Object lock;
+
+    {
+        lock = null;
+    }
+
+    long nextExecutionTime;
+
+    @UnsupportedAppUsage
+    long period = 0; // 0x0
+
+    int state = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/UUID.java b/ojluni/annotations/hiddenapi/java/util/UUID.java
new file mode 100644
index 0000000..0585e5de
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/UUID.java
@@ -0,0 +1,130 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class UUID implements java.io.Serializable, java.lang.Comparable<java.util.UUID> {
+
+    private UUID(byte[] data) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public UUID(long mostSigBits, long leastSigBits) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.UUID randomUUID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.UUID nameUUIDFromBytes(byte[] name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.UUID fromString(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getLeastSignificantBits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getMostSignificantBits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int version() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int variant() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long timestamp() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int clockSequence() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long node() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String digits(long val, int digits) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(java.util.UUID val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final long leastSigBits;
+
+    {
+        leastSigBits = 0;
+    }
+
+    @UnsupportedAppUsage
+    private final long mostSigBits;
+
+    {
+        mostSigBits = 0;
+    }
+
+    private static final long serialVersionUID = -4856846361193249489L; // 0xbc9903f7986d852fL
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Holder {
+
+        private Holder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final java.security.SecureRandom numberGenerator;
+
+        static {
+            numberGenerator = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/Vector.java b/ojluni/annotations/hiddenapi/java/util/Vector.java
new file mode 100644
index 0000000..394a097
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/Vector.java
@@ -0,0 +1,402 @@
+/*
+ * 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.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Vector<E> extends java.util.AbstractList<E>
+        implements java.util.List<E>,
+                java.util.RandomAccess,
+                java.lang.Cloneable,
+                java.io.Serializable {
+
+    public Vector(int initialCapacity, int capacityIncrement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Vector(int initialCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Vector() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Vector(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void copyInto(java.lang.Object[] anArray) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void trimToSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void ensureCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureCapacityHelper(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void grow(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int hugeCapacity(int minCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setSize(int newSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int capacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<E> elements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int indexOf(java.lang.Object o, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int lastIndexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int lastIndexOf(java.lang.Object o, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E elementAt(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E firstElement() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E lastElement() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setElementAt(E obj, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void removeElementAt(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void insertElementAt(E obj, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void addElement(E obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean removeElement(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void removeAllElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    E elementData(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E get(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E set(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void add(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized E remove(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean containsAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean addAll(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean removeAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean retainAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean addAll(int index, java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean equals(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.List<E> subList(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected synchronized void removeRange(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.ListIterator<E> listIterator(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.ListIterator<E> listIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void forEach(java.util.function.Consumer<? super E> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized boolean removeIf(java.util.function.Predicate<? super E> filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void replaceAll(java.util.function.UnaryOperator<E> operator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void sort(java.util.Comparator<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int MAX_ARRAY_SIZE = 2147483639; // 0x7ffffff7
+
+    protected int capacityIncrement;
+
+    protected int elementCount;
+
+    protected java.lang.Object[] elementData;
+
+    private static final long serialVersionUID = -2767605614048989439L; // 0xd9977d5b803baf01L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Itr implements java.util.Iterator<E> {
+
+        private Itr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final void checkForComodification() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int cursor;
+
+        int expectedModCount;
+
+        int lastRet = -1; // 0xffffffff
+
+        protected int limit;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class ListItr extends Itr implements java.util.ListIterator<E> {
+
+        ListItr(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class VectorSpliterator<E> implements java.util.Spliterator<E> {
+
+        VectorSpliterator(
+                java.util.Vector<E> list,
+                java.lang.Object[] array,
+                int origin,
+                int fence,
+                int expectedModCount) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object[] array;
+
+        private int expectedModCount;
+
+        private int fence;
+
+        private int index;
+
+        private final java.util.Vector<E> list;
+
+        {
+            list = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArrayList.java b/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArrayList.java
new file mode 100644
index 0000000..7d526a7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArrayList.java
@@ -0,0 +1,497 @@
+/*
+ * 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.
+ */
+
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group.  Adapted and released, under explicit permission,
+ * from JDK ArrayList.java which carries the following copyright:
+ *
+ * Copyright 1997 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CopyOnWriteArrayList<E>
+        implements java.util.List<E>,
+                java.util.RandomAccess,
+                java.lang.Cloneable,
+                java.io.Serializable {
+
+    public CopyOnWriteArrayList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CopyOnWriteArrayList(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CopyOnWriteArrayList(E[] toCopyIn) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.lang.Object[] getArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void setArray(java.lang.Object[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int indexOf(
+            java.lang.Object o, java.lang.Object[] elements, int index, int fence) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int lastIndexOf(java.lang.Object o, java.lang.Object[] elements, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int indexOf(E e, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int lastIndexOf(E e, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E get(java.lang.Object[] a, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String outOfBounds(int index, int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E get(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E set(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void add(int index, E element) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean remove(java.lang.Object o, java.lang.Object[] snapshot, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void removeRange(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addIfAbsent(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean addIfAbsent(E e, java.lang.Object[] snapshot) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean retainAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int addAllAbsent(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(int index, java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void forEach(java.util.function.Consumer<? super E> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sort(java.util.Comparator<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ListIterator<E> listIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ListIterator<E> listIterator(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<E> subList(int fromIndex, int toIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void resetLock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long LOCK;
+
+    static {
+        LOCK = 0;
+    }
+
+    private static final sun.misc.Unsafe U;
+
+    static {
+        U = null;
+    }
+
+    @UnsupportedAppUsage
+    private transient volatile java.lang.Object[] elements;
+
+    final transient java.lang.Object lock;
+
+    {
+        lock = null;
+    }
+
+    private static final long serialVersionUID = 8673264195747942595L; // 0x785d9fd546ab90c3L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class COWIterator<E> implements java.util.ListIterator<E> {
+
+        COWIterator(java.lang.Object[] elements, int initialCursor) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int cursor;
+
+        private final java.lang.Object[] snapshot;
+
+        {
+            snapshot = new java.lang.Object[0];
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class COWSubList<E> extends java.util.AbstractList<E>
+            implements java.util.RandomAccess {
+
+        COWSubList(java.util.concurrent.CopyOnWriteArrayList<E> list, int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkForComodification() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void rangeCheck(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E set(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(int index, E element) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void clear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E remove(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean remove(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<E> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.ListIterator<E> listIterator(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<E> subList(int fromIndex, int toIndex) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEach(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replaceAll(java.util.function.UnaryOperator<E> operator) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void sort(java.util.Comparator<? super E> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean retainAll(java.util.Collection<?> c) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> spliterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.Object[] expectedArray;
+
+        private final java.util.concurrent.CopyOnWriteArrayList<E> l;
+
+        {
+            l = null;
+        }
+
+        private final int offset;
+
+        {
+            offset = 0;
+        }
+
+        private int size;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class COWSubListIterator<E> implements java.util.ListIterator<E> {
+
+        COWSubListIterator(java.util.List<E> l, int index, int offset, int size) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasPrevious() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E previous() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int nextIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int previousIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void set(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(E e) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.ListIterator<E> it;
+
+        {
+            it = null;
+        }
+
+        private final int offset;
+
+        {
+            offset = 0;
+        }
+
+        private final int size;
+
+        {
+            size = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArraySet.java b/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArraySet.java
new file mode 100644
index 0000000..98c53b0
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/CopyOnWriteArraySet.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CopyOnWriteArraySet<E> extends java.util.AbstractSet<E>
+        implements java.io.Serializable {
+
+    public CopyOnWriteArraySet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CopyOnWriteArraySet(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean containsAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int compareSets(java.lang.Object[] snapshot, java.util.Set<?> set) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addAll(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean retainAll(java.util.Collection<?> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeIf(java.util.function.Predicate<? super E> filter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void forEach(java.util.function.Consumer<? super E> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.CopyOnWriteArrayList<E> al;
+
+    {
+        al = null;
+    }
+
+    private static final long serialVersionUID = 5457747651344034263L; // 0x4bbdd092901569d7L
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/Executors.java b/ojluni/annotations/hiddenapi/java/util/concurrent/Executors.java
new file mode 100644
index 0000000..1fbd62c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/Executors.java
@@ -0,0 +1,429 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Executors {
+
+    private Executors() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newFixedThreadPool(int nThreads) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newWorkStealingPool(int parallelism) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newWorkStealingPool() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newFixedThreadPool(
+            int nThreads, java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newSingleThreadExecutor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newSingleThreadExecutor(
+            java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newCachedThreadPool() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService newCachedThreadPool(
+            java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(
+            java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(
+            int corePoolSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(
+            int corePoolSize, java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ExecutorService unconfigurableExecutorService(
+            java.util.concurrent.ExecutorService executor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ScheduledExecutorService
+            unconfigurableScheduledExecutorService(
+                    java.util.concurrent.ScheduledExecutorService executor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ThreadFactory defaultThreadFactory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.ThreadFactory privilegedThreadFactory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.concurrent.Callable<T> callable(java.lang.Runnable task, T result) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.Callable<java.lang.Object> callable(
+            java.lang.Runnable task) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.Callable<java.lang.Object> callable(
+            java.security.PrivilegedAction<?> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.concurrent.Callable<java.lang.Object> callable(
+            java.security.PrivilegedExceptionAction<?> action) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.concurrent.Callable<T> privilegedCallable(
+            java.util.concurrent.Callable<T> callable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <T> java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(
+            java.util.concurrent.Callable<T> callable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DefaultThreadFactory implements java.util.concurrent.ThreadFactory {
+
+        DefaultThreadFactory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Thread newThread(java.lang.Runnable r) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.ThreadGroup group;
+
+        {
+            group = null;
+        }
+
+        private final java.lang.String namePrefix;
+
+        {
+            namePrefix = null;
+        }
+
+        private static final java.util.concurrent.atomic.AtomicInteger poolNumber;
+
+        static {
+            poolNumber = null;
+        }
+
+        private final java.util.concurrent.atomic.AtomicInteger threadNumber;
+
+        {
+            threadNumber = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DelegatedExecutorService
+            extends java.util.concurrent.AbstractExecutorService {
+
+        DelegatedExecutorService(java.util.concurrent.ExecutorService executor) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void execute(java.lang.Runnable command) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void shutdown() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<java.lang.Runnable> shutdownNow() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isShutdown() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isTerminated() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean awaitTermination(long timeout, java.util.concurrent.TimeUnit unit)
+                throws java.lang.InterruptedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.concurrent.Future<?> submit(java.lang.Runnable task) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T> task) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> java.util.concurrent.Future<T> submit(java.lang.Runnable task, T result) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(
+                java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks)
+                throws java.lang.InterruptedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(
+                java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks,
+                long timeout,
+                java.util.concurrent.TimeUnit unit)
+                throws java.lang.InterruptedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T invokeAny(
+                java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks)
+                throws java.util.concurrent.ExecutionException, java.lang.InterruptedException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <T> T invokeAny(
+                java.util.Collection<? extends java.util.concurrent.Callable<T>> tasks,
+                long timeout,
+                java.util.concurrent.TimeUnit unit)
+                throws java.util.concurrent.ExecutionException, java.lang.InterruptedException,
+                        java.util.concurrent.TimeoutException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.concurrent.ExecutorService e;
+
+        {
+            e = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class DelegatedScheduledExecutorService
+            extends java.util.concurrent.Executors.DelegatedExecutorService
+            implements java.util.concurrent.ScheduledExecutorService {
+
+        DelegatedScheduledExecutorService(java.util.concurrent.ScheduledExecutorService executor) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.concurrent.ScheduledFuture<?> schedule(
+                java.lang.Runnable command, long delay, java.util.concurrent.TimeUnit unit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public <V> java.util.concurrent.ScheduledFuture<V> schedule(
+                java.util.concurrent.Callable<V> callable,
+                long delay,
+                java.util.concurrent.TimeUnit unit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(
+                java.lang.Runnable command,
+                long initialDelay,
+                long period,
+                java.util.concurrent.TimeUnit unit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(
+                java.lang.Runnable command,
+                long initialDelay,
+                long delay,
+                java.util.concurrent.TimeUnit unit) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.concurrent.ScheduledExecutorService e;
+
+        {
+            e = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class FinalizableDelegatedExecutorService
+            extends java.util.concurrent.Executors.DelegatedExecutorService {
+
+        FinalizableDelegatedExecutorService(java.util.concurrent.ExecutorService executor) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void finalize() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class PrivilegedCallable<T> implements java.util.concurrent.Callable<T> {
+
+        PrivilegedCallable(java.util.concurrent.Callable<T> task) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public T call() throws java.lang.Exception {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.security.AccessControlContext acc;
+
+        {
+            acc = null;
+        }
+
+        final java.util.concurrent.Callable<T> task;
+
+        {
+            task = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class PrivilegedCallableUsingCurrentClassLoader<T>
+            implements java.util.concurrent.Callable<T> {
+
+        PrivilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T> task) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public T call() throws java.lang.Exception {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.security.AccessControlContext acc;
+
+        {
+            acc = null;
+        }
+
+        final java.lang.ClassLoader ccl;
+
+        {
+            ccl = null;
+        }
+
+        final java.util.concurrent.Callable<T> task;
+
+        {
+            task = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class PrivilegedThreadFactory
+            extends java.util.concurrent.Executors.DefaultThreadFactory {
+
+        PrivilegedThreadFactory() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Thread newThread(java.lang.Runnable r) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.security.AccessControlContext acc;
+
+        {
+            acc = null;
+        }
+
+        final java.lang.ClassLoader ccl;
+
+        {
+            ccl = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class RunnableAdapter<T> implements java.util.concurrent.Callable<T> {
+
+        RunnableAdapter(java.lang.Runnable task, T result) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public T call() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final T result;
+
+        {
+            result = null;
+        }
+
+        @UnsupportedAppUsage
+        private final java.lang.Runnable task;
+
+        {
+            task = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/FutureTask.java b/ojluni/annotations/hiddenapi/java/util/concurrent/FutureTask.java
new file mode 100644
index 0000000..2274611
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/FutureTask.java
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FutureTask<V> implements java.util.concurrent.RunnableFuture<V> {
+
+    public FutureTask(java.util.concurrent.Callable<V> callable) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public FutureTask(java.lang.Runnable runnable, V result) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private V report(int s) throws java.util.concurrent.ExecutionException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isCancelled() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isDone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public V get(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.util.concurrent.ExecutionException, java.lang.InterruptedException,
+                    java.util.concurrent.TimeoutException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void done() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void set(V v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setException(java.lang.Throwable t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void run() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean runAndReset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void handlePossibleCancellationInterrupt(int s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void finishCompletion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int awaitDone(boolean timed, long nanos) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void removeWaiter(java.util.concurrent.FutureTask.WaitNode node) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int CANCELLED = 4; // 0x4
+
+    private static final int COMPLETING = 1; // 0x1
+
+    @UnsupportedAppUsage
+    private static final int EXCEPTIONAL = 3; // 0x3
+
+    private static final int INTERRUPTED = 6; // 0x6
+
+    private static final int INTERRUPTING = 5; // 0x5
+
+    private static final int NEW = 0; // 0x0
+
+    private static final int NORMAL = 2; // 0x2
+
+    private static final long RUNNER;
+
+    static {
+        RUNNER = 0;
+    }
+
+    private static final long STATE;
+
+    static {
+        STATE = 0;
+    }
+
+    private static final sun.misc.Unsafe U;
+
+    static {
+        U = null;
+    }
+
+    private static final long WAITERS;
+
+    static {
+        WAITERS = 0;
+    }
+
+    @UnsupportedAppUsage
+    private java.util.concurrent.Callable<V> callable;
+
+    @UnsupportedAppUsage
+    private java.lang.Object outcome;
+
+    private volatile java.lang.Thread runner;
+
+    @UnsupportedAppUsage
+    private volatile int state;
+
+    private volatile java.util.concurrent.FutureTask.WaitNode waiters;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class WaitNode {
+
+        WaitNode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        volatile java.util.concurrent.FutureTask.WaitNode next;
+
+        volatile java.lang.Thread thread;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingDeque.java b/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingDeque.java
new file mode 100644
index 0000000..de84037
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingDeque.java
@@ -0,0 +1,444 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LinkedBlockingDeque<E> extends java.util.AbstractQueue<E>
+        implements java.util.concurrent.BlockingDeque<E>, java.io.Serializable {
+
+    public LinkedBlockingDeque() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedBlockingDeque(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedBlockingDeque(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean linkFirst(Node<E> node) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean linkLast(Node<E> node) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E unlinkFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E unlinkLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void unlink(Node<E> x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerFirst(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerLast(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putFirst(E e) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putLast(E e) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerFirst(E e, long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offerLast(E e, long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E removeLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E takeFirst() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E takeLast() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollFirst(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pollLast(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E getLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekFirst() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peekLast() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeFirstOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean removeLastOccurrence(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void put(E e) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e, long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E remove() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E take() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E element() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int remainingCapacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c, int maxElements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void push(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E pop() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> descendingIterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final int capacity;
+
+    {
+        capacity = 0;
+    }
+
+    private transient int count;
+
+    @UnsupportedAppUsage
+    transient Node<E> first;
+
+    transient Node<E> last;
+
+    @UnsupportedAppUsage
+    final java.util.concurrent.locks.ReentrantLock lock;
+
+    {
+        lock = null;
+    }
+
+    private final java.util.concurrent.locks.Condition notEmpty;
+
+    {
+        notEmpty = null;
+    }
+
+    private final java.util.concurrent.locks.Condition notFull;
+
+    {
+        notFull = null;
+    }
+
+    private static final long serialVersionUID = -387911632671998426L; // 0xfa9ddc6ce257fe26L
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private abstract class AbstractItr implements java.util.Iterator<E> {
+
+        AbstractItr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        abstract Node<E> firstNode();
+
+        abstract Node<E> nextNode(
+                Node<E> n);
+
+        private Node<E> succ(
+                Node<E> n) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void advance() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private Node<E> lastRet;
+
+        Node<E> next;
+
+        E nextItem;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class DescendingItr extends AbstractItr {
+
+        DescendingItr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        Node<E> firstNode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        Node<E> nextNode(
+                Node<E> n) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Itr extends AbstractItr {
+
+        Itr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        Node<E> firstNode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        Node<E> nextNode(
+                Node<E> n) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class LBDSpliterator<E> implements java.util.Spliterator<E> {
+
+        LBDSpliterator(java.util.concurrent.LinkedBlockingDeque<E> queue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final int MAX_BATCH = 33554432; // 0x2000000
+
+        int batch;
+
+        Node<E> current;
+
+        long est;
+
+        boolean exhausted;
+
+        final java.util.concurrent.LinkedBlockingDeque<E> queue;
+
+        {
+            queue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class Node<E> {
+
+        Node(E x) {
+            throw new RuntimeException("Stub!");
+        }
+
+        E item;
+
+        Node<E> next;
+
+        Node<E> prev;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingQueue.java b/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingQueue.java
new file mode 100644
index 0000000..f7aec5c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/LinkedBlockingQueue.java
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LinkedBlockingQueue<E> extends java.util.AbstractQueue<E>
+        implements java.util.concurrent.BlockingQueue<E>, java.io.Serializable {
+
+    public LinkedBlockingQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedBlockingQueue(int capacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public LinkedBlockingQueue(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void signalNotEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void signalNotFull() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void enqueue(java.util.concurrent.LinkedBlockingQueue.Node<E> node) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private E dequeue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void fullyLock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void fullyUnlock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int remainingCapacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void put(E e) throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e, long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E take() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void unlink(
+            java.util.concurrent.LinkedBlockingQueue.Node<E> p,
+            java.util.concurrent.LinkedBlockingQueue.Node<E> trail) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c, int maxElements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private final int capacity;
+
+    {
+        capacity = 0;
+    }
+
+    private final java.util.concurrent.atomic.AtomicInteger count;
+
+    {
+        count = null;
+    }
+
+    @UnsupportedAppUsage
+    transient java.util.concurrent.LinkedBlockingQueue.Node<E> head;
+
+    private transient java.util.concurrent.LinkedBlockingQueue.Node<E> last;
+
+    private final java.util.concurrent.locks.Condition notEmpty;
+
+    {
+        notEmpty = null;
+    }
+
+    private final java.util.concurrent.locks.Condition notFull;
+
+    {
+        notFull = null;
+    }
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.ReentrantLock putLock;
+
+    {
+        putLock = null;
+    }
+
+    private static final long serialVersionUID = -6903933977591709194L; // 0xa0304ca040e581f6L
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.ReentrantLock takeLock;
+
+    {
+        takeLock = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Itr implements java.util.Iterator<E> {
+
+        Itr() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.util.concurrent.LinkedBlockingQueue.Node<E> current;
+
+        private E currentElement;
+
+        private java.util.concurrent.LinkedBlockingQueue.Node<E> lastRet;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class LBQSpliterator<E> implements java.util.Spliterator<E> {
+
+        LBQSpliterator(java.util.concurrent.LinkedBlockingQueue<E> queue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Spliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static final int MAX_BATCH = 33554432; // 0x2000000
+
+        int batch;
+
+        java.util.concurrent.LinkedBlockingQueue.Node<E> current;
+
+        long est;
+
+        boolean exhausted;
+
+        final java.util.concurrent.LinkedBlockingQueue<E> queue;
+
+        {
+            queue = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class Node<E> {
+
+        Node(E x) {
+            throw new RuntimeException("Stub!");
+        }
+
+        E item;
+
+        java.util.concurrent.LinkedBlockingQueue.Node<E> next;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/PriorityBlockingQueue.java b/ojluni/annotations/hiddenapi/java/util/concurrent/PriorityBlockingQueue.java
new file mode 100644
index 0000000..0577e8c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/PriorityBlockingQueue.java
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PriorityBlockingQueue<E> extends java.util.AbstractQueue<E>
+        implements java.util.concurrent.BlockingQueue<E>, java.io.Serializable {
+
+    public PriorityBlockingQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityBlockingQueue(int initialCapacity) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityBlockingQueue(int initialCapacity, java.util.Comparator<? super E> comparator) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PriorityBlockingQueue(java.util.Collection<? extends E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void tryGrow(java.lang.Object[] array, int oldCap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private E dequeue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> void siftUpComparable(int k, T x, java.lang.Object[] array) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> void siftUpUsingComparator(
+            int k, T x, java.lang.Object[] array, java.util.Comparator<? super T> cmp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> void siftDownComparable(int k, T x, java.lang.Object[] array, int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static <T> void siftDownUsingComparator(
+            int k, T x, java.lang.Object[] array, int n, java.util.Comparator<? super T> cmp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void heapify() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean add(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void put(E e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean offer(E e, long timeout, java.util.concurrent.TimeUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E take() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E poll(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public E peek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Comparator<? super E> comparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int remainingCapacity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int indexOf(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void removeAt(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void removeEQ(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean contains(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int drainTo(java.util.Collection<? super E> c, int maxElements) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public <T> T[] toArray(T[] a) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<E> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Spliterator<E> spliterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long ALLOCATIONSPINLOCK;
+
+    static {
+        ALLOCATIONSPINLOCK = 0;
+    }
+
+    private static final int DEFAULT_INITIAL_CAPACITY = 11; // 0xb
+
+    private static final int MAX_ARRAY_SIZE = 2147483639; // 0x7ffffff7
+
+    private static final sun.misc.Unsafe U;
+
+    static {
+        U = null;
+    }
+
+    private transient volatile int allocationSpinLock;
+
+    private transient java.util.Comparator<? super E> comparator;
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.ReentrantLock lock;
+
+    {
+        lock = null;
+    }
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.Condition notEmpty;
+
+    {
+        notEmpty = null;
+    }
+
+    private java.util.PriorityQueue<E> q;
+
+    private transient java.lang.Object[] queue;
+
+    private static final long serialVersionUID = 5595510919245408276L; // 0x4da73f88e6712814L
+
+    private transient int size;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class Itr implements java.util.Iterator<E> {
+
+        Itr(java.lang.Object[] array) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public E next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.lang.Object[] array;
+
+        {
+            array = new java.lang.Object[0];
+        }
+
+        int cursor;
+
+        int lastRet;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class PBQSpliterator<E> implements java.util.Spliterator<E> {
+
+        PBQSpliterator(
+                java.util.concurrent.PriorityBlockingQueue<E> queue,
+                java.lang.Object[] array,
+                int index,
+                int fence) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int getFence() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.concurrent.PriorityBlockingQueue.PBQSpliterator<E> trySplit() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void forEachRemaining(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryAdvance(java.util.function.Consumer<? super E> action) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long estimateSize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int characteristics() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Object[] array;
+
+        int fence;
+
+        int index;
+
+        final java.util.concurrent.PriorityBlockingQueue<E> queue;
+
+        {
+            queue = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java b/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java
new file mode 100644
index 0000000..e89f678
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java
@@ -0,0 +1,508 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
+
+    public ThreadPoolExecutor(
+            int corePoolSize,
+            int maximumPoolSize,
+            long keepAliveTime,
+            java.util.concurrent.TimeUnit unit,
+            java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ThreadPoolExecutor(
+            int corePoolSize,
+            int maximumPoolSize,
+            long keepAliveTime,
+            java.util.concurrent.TimeUnit unit,
+            java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue,
+            java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ThreadPoolExecutor(
+            int corePoolSize,
+            int maximumPoolSize,
+            long keepAliveTime,
+            java.util.concurrent.TimeUnit unit,
+            java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue,
+            java.util.concurrent.RejectedExecutionHandler handler) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ThreadPoolExecutor(
+            int corePoolSize,
+            int maximumPoolSize,
+            long keepAliveTime,
+            java.util.concurrent.TimeUnit unit,
+            java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue,
+            java.util.concurrent.ThreadFactory threadFactory,
+            java.util.concurrent.RejectedExecutionHandler handler) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int runStateOf(int c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int workerCountOf(int c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int ctlOf(int rs, int wc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean runStateLessThan(int c, int s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean runStateAtLeast(int c, int s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isRunning(int c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean compareAndIncrementWorkerCount(int expect) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean compareAndDecrementWorkerCount(int expect) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void decrementWorkerCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void advanceRunState(int targetState) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void tryTerminate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkShutdownAccess() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void interruptWorkers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void interruptIdleWorkers(boolean onlyOne) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void interruptIdleWorkers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void reject(java.lang.Runnable command) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void onShutdown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isRunningOrShutdown(boolean shutdownOK) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.List<java.lang.Runnable> drainQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean addWorker(java.lang.Runnable firstTask, boolean core) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void addWorkerFailed(java.util.concurrent.ThreadPoolExecutor.Worker w) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void processWorkerExit(
+            java.util.concurrent.ThreadPoolExecutor.Worker w, boolean completedAbruptly) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Runnable getTask() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void runWorker(java.util.concurrent.ThreadPoolExecutor.Worker w) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void execute(java.lang.Runnable command) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void shutdown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.lang.Runnable> shutdownNow() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isShutdown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isTerminating() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isTerminated() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean awaitTermination(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setThreadFactory(java.util.concurrent.ThreadFactory threadFactory) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.concurrent.ThreadFactory getThreadFactory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setRejectedExecutionHandler(java.util.concurrent.RejectedExecutionHandler handler) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.concurrent.RejectedExecutionHandler getRejectedExecutionHandler() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCorePoolSize(int corePoolSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getCorePoolSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean prestartCoreThread() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void ensurePrestart() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int prestartAllCoreThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean allowsCoreThreadTimeOut() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void allowCoreThreadTimeOut(boolean value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMaximumPoolSize(int maximumPoolSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMaximumPoolSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setKeepAliveTime(long time, java.util.concurrent.TimeUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getKeepAliveTime(java.util.concurrent.TimeUnit unit) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.concurrent.BlockingQueue<java.lang.Runnable> getQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean remove(java.lang.Runnable task) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void purge() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getPoolSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getActiveCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getLargestPoolSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTaskCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getCompletedTaskCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void beforeExecute(java.lang.Thread t, java.lang.Runnable r) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void afterExecute(java.lang.Runnable r, java.lang.Throwable t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void terminated() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int CAPACITY = 536870911; // 0x1fffffff
+
+    private static final int COUNT_BITS = 29; // 0x1d
+
+    private static final boolean ONLY_ONE = true;
+
+    private static final int RUNNING = -536870912; // 0xe0000000
+
+    private static final int SHUTDOWN = 0; // 0x0
+
+    private static final int STOP = 536870912; // 0x20000000
+
+    private static final int TERMINATED = 1610612736; // 0x60000000
+
+    private static final int TIDYING = 1073741824; // 0x40000000
+
+    @UnsupportedAppUsage
+    private volatile boolean allowCoreThreadTimeOut;
+
+    private long completedTaskCount;
+
+    private volatile int corePoolSize;
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.atomic.AtomicInteger ctl;
+
+    {
+        ctl = null;
+    }
+
+    @UnsupportedAppUsage
+    private static final java.util.concurrent.RejectedExecutionHandler defaultHandler;
+
+    static {
+        defaultHandler = null;
+    }
+
+    private volatile java.util.concurrent.RejectedExecutionHandler handler;
+
+    private volatile long keepAliveTime;
+
+    private int largestPoolSize;
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.ReentrantLock mainLock;
+
+    {
+        mainLock = null;
+    }
+
+    private volatile int maximumPoolSize;
+
+    private static final java.lang.RuntimePermission shutdownPerm;
+
+    static {
+        shutdownPerm = null;
+    }
+
+    private final java.util.concurrent.locks.Condition termination;
+
+    {
+        termination = null;
+    }
+
+    private volatile java.util.concurrent.ThreadFactory threadFactory;
+
+    private final java.util.concurrent.BlockingQueue<java.lang.Runnable> workQueue;
+
+    {
+        workQueue = null;
+    }
+
+    private final java.util.HashSet<java.util.concurrent.ThreadPoolExecutor.Worker> workers;
+
+    {
+        workers = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class AbortPolicy implements java.util.concurrent.RejectedExecutionHandler {
+
+        public AbortPolicy() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void rejectedExecution(
+                java.lang.Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class CallerRunsPolicy implements java.util.concurrent.RejectedExecutionHandler {
+
+        public CallerRunsPolicy() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void rejectedExecution(
+                java.lang.Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class DiscardOldestPolicy
+            implements java.util.concurrent.RejectedExecutionHandler {
+
+        public DiscardOldestPolicy() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void rejectedExecution(
+                java.lang.Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class DiscardPolicy implements java.util.concurrent.RejectedExecutionHandler {
+
+        public DiscardPolicy() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void rejectedExecution(
+                java.lang.Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private final class Worker extends java.util.concurrent.locks.AbstractQueuedSynchronizer
+            implements java.lang.Runnable {
+
+        Worker(java.lang.Runnable firstTask) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void run() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean isHeldExclusively() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean tryAcquire(int unused) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean tryRelease(int unused) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void lock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean tryLock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void unlock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isLocked() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void interruptIfStarted() {
+            throw new RuntimeException("Stub!");
+        }
+
+        volatile long completedTasks;
+
+        java.lang.Runnable firstTask;
+
+        private static final long serialVersionUID = 6138294804551838833L; // 0x552f9a9a47f02c71L
+
+        final java.lang.Thread thread;
+
+        {
+            thread = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/atomic/AtomicInteger.java b/ojluni/annotations/hiddenapi/java/util/concurrent/atomic/AtomicInteger.java
new file mode 100644
index 0000000..a5718ac
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/atomic/AtomicInteger.java
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent.atomic;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
+
+    public AtomicInteger(int initialValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public AtomicInteger() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int get() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void set(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void lazySet(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndSet(int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean compareAndSet(int expect, int update) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean weakCompareAndSet(int expect, int update) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndIncrement() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndDecrement() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndAdd(int delta) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int incrementAndGet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int decrementAndGet() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int addAndGet(int delta) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndUpdate(java.util.function.IntUnaryOperator updateFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int updateAndGet(java.util.function.IntUnaryOperator updateFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getAndAccumulate(
+            int x, java.util.function.IntBinaryOperator accumulatorFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int accumulateAndGet(
+            int x, java.util.function.IntBinaryOperator accumulatorFunction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        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!");
+    }
+
+    private static final sun.misc.Unsafe U;
+
+    static {
+        U = null;
+    }
+
+    private static final long VALUE;
+
+    static {
+        VALUE = 0;
+    }
+
+    private static final long serialVersionUID = 6214790243416807050L; // 0x563f5ecc8c6c168aL
+
+    @UnsupportedAppUsage
+    private volatile int value;
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/locks/ReentrantLock.java b/ojluni/annotations/hiddenapi/java/util/concurrent/locks/ReentrantLock.java
new file mode 100644
index 0000000..1ad6e8d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/locks/ReentrantLock.java
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent.locks;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ReentrantLock implements java.util.concurrent.locks.Lock, java.io.Serializable {
+
+    public ReentrantLock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ReentrantLock(boolean fair) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void lock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void lockInterruptibly() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean tryLock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean tryLock(long timeout, java.util.concurrent.TimeUnit unit)
+            throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void unlock() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.concurrent.locks.Condition newCondition() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getHoldCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isHeldByCurrentThread() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLocked() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean isFair() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Thread getOwner() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean hasQueuedThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean hasQueuedThread(java.lang.Thread thread) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final int getQueueLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.util.Collection<java.lang.Thread> getQueuedThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasWaiters(java.util.concurrent.locks.Condition condition) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getWaitQueueLength(java.util.concurrent.locks.Condition condition) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.util.Collection<java.lang.Thread> getWaitingThreads(
+            java.util.concurrent.locks.Condition condition) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long serialVersionUID = 7373984872572414699L; // 0x6655a82c2cc86aebL
+
+    @UnsupportedAppUsage
+    private final java.util.concurrent.locks.ReentrantLock.Sync sync;
+
+    {
+        sync = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class FairSync extends java.util.concurrent.locks.ReentrantLock.Sync {
+
+        FairSync() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void lock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean tryAcquire(int acquires) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -3000897897090466540L; // 0xd65aab4314b4bd14L
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class NonfairSync extends java.util.concurrent.locks.ReentrantLock.Sync {
+
+        NonfairSync() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void lock() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected boolean tryAcquire(int acquires) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 7316153563782823691L; // 0x658832e7537bbf0bL
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    abstract static class Sync extends java.util.concurrent.locks.AbstractQueuedSynchronizer {
+
+        Sync() {
+            throw new RuntimeException("Stub!");
+        }
+
+        abstract void lock();
+
+        final boolean nonfairTryAcquire(int acquires) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected final boolean tryRelease(int releases) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected final boolean isHeldExclusively() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject newCondition() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.lang.Thread getOwner() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final int getHoldCount() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final boolean isLocked() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void readObject(java.io.ObjectInputStream s)
+                throws java.lang.ClassNotFoundException, java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -5179523762034025860L; // 0xb81ea294aa445a7cL
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/jar/JarFile.java b/ojluni/annotations/hiddenapi/java/util/jar/JarFile.java
new file mode 100644
index 0000000..1c97964
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/jar/JarFile.java
@@ -0,0 +1,210 @@
+/*
+ * 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.jar;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class JarFile extends java.util.zip.ZipFile {
+
+    public JarFile(java.lang.String name) throws java.io.IOException {
+        super((java.lang.String) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public JarFile(java.lang.String name, boolean verify) throws java.io.IOException {
+        super((java.lang.String) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public JarFile(java.io.File file) throws java.io.IOException {
+        super((java.lang.String) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public JarFile(java.io.File file, boolean verify) throws java.io.IOException {
+        super((java.lang.String) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public JarFile(java.io.File file, boolean verify, int mode) throws java.io.IOException {
+        super((java.lang.String) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.jar.Manifest getManifest() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized java.util.jar.Manifest getManifestFromReference()
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native java.lang.String[] getMetaInfEntryNames();
+
+    public java.util.jar.JarEntry getJarEntry(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry getEntry(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.util.jar.JarEntry> entries() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.Stream<java.util.jar.JarEntry> stream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void maybeInstantiateVerifier() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void initializeVerifier() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] getBytes(java.util.zip.ZipEntry ze) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry ze)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized java.util.jar.JarEntry getManEntry() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasClassPathAttribute() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkForSpecialAttributes() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.jar.JarEntry newEntry(java.util.zip.ZipEntry ze) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final char[] CLASSPATH_CHARS;
+
+    static {
+        CLASSPATH_CHARS = new char[0];
+    }
+
+    private static final int[] CLASSPATH_LASTOCC;
+
+    static {
+        CLASSPATH_LASTOCC = new int[0];
+    }
+
+    private static final int[] CLASSPATH_OPTOSFT;
+
+    static {
+        CLASSPATH_OPTOSFT = new int[0];
+    }
+
+    public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
+
+    private volatile boolean hasCheckedSpecialAttributes;
+
+    private boolean hasClassPathAttribute;
+
+    private java.util.jar.JarVerifier jv;
+
+    private boolean jvInitialized;
+
+    private java.util.jar.JarEntry manEntry;
+
+    @UnsupportedAppUsage
+    private java.util.jar.Manifest manifest;
+
+    private boolean verify;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class JarEntryIterator
+            implements java.util.Enumeration<java.util.jar.JarEntry>,
+                    java.util.Iterator<java.util.jar.JarEntry> {
+
+        private JarEntryIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.jar.JarEntry next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasMoreElements() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.jar.JarEntry nextElement() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.Enumeration<? extends java.util.zip.ZipEntry> e;
+
+        {
+            e = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class JarFileEntry extends java.util.jar.JarEntry {
+
+        JarFileEntry(java.util.zip.ZipEntry ze) {
+            super((java.lang.String) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.jar.Attributes getAttributes() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.cert.Certificate[] getCertificates() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.CodeSigner[] getCodeSigners() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/logging/Handler.java b/ojluni/annotations/hiddenapi/java/util/logging/Handler.java
new file mode 100644
index 0000000..2d04f15
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/logging/Handler.java
@@ -0,0 +1,123 @@
+/*
+ * 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
+ * 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.logging;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Handler {
+
+    protected Handler() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract void publish(java.util.logging.LogRecord record);
+
+    public abstract void flush();
+
+    public abstract void close() throws java.lang.SecurityException;
+
+    public synchronized void setFormatter(java.util.logging.Formatter newFormatter)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Formatter getFormatter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setEncoding(java.lang.String encoding)
+            throws java.lang.SecurityException, java.io.UnsupportedEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getEncoding() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setFilter(java.util.logging.Filter newFilter)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Filter getFilter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setErrorManager(java.util.logging.ErrorManager em) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.ErrorManager getErrorManager() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void reportError(java.lang.String msg, java.lang.Exception ex, int code) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setLevel(java.util.logging.Level newLevel)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Level getLevel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLoggable(java.util.logging.LogRecord record) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkPermission() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private volatile java.lang.String encoding;
+
+    private volatile java.util.logging.ErrorManager errorManager;
+
+    private volatile java.util.logging.Filter filter;
+
+    private volatile java.util.logging.Formatter formatter;
+
+    private volatile java.util.logging.Level logLevel;
+
+    private final java.util.logging.LogManager manager;
+
+    {
+        manager = null;
+    }
+
+    private static final int offValue;
+
+    static {
+        offValue = 0;
+    }
+
+    @UnsupportedAppUsage
+    boolean sealed = true;
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java b/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java
new file mode 100644
index 0000000..a140100
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.logging;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LogManager {
+
+    protected LogManager() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private LogManager(java.lang.Void checked) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Void checkSubclassPermissions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void ensureLogManagerInitialized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.logging.LogManager getLogManager() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readPrimordialConfiguration() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void addPropertyChangeListener(java.beans.PropertyChangeListener l)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void removePropertyChangeListener(java.beans.PropertyChangeListener l)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.logging.LogManager.LoggerContext getUserContext() {
+        throw new RuntimeException("Stub!");
+    }
+
+    final java.util.logging.LogManager.LoggerContext getSystemContext() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.List<java.util.logging.LogManager.LoggerContext> contexts() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.logging.Logger demandLogger(
+            java.lang.String name, java.lang.String resourceBundleName, java.lang.Class<?> caller) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.logging.Logger demandSystemLogger(
+            java.lang.String name, java.lang.String resourceBundleName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Class getClassInstance(java.lang.String cname)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void loadLoggerHandlers(
+            java.util.logging.Logger logger,
+            java.lang.String name,
+            java.lang.String handlersPropertyName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void drainLoggerRefQueueBounded() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean addLogger(java.util.logging.Logger logger) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void doSetLevel(java.util.logging.Logger logger, java.util.logging.Level level) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void doSetParent(
+            java.util.logging.Logger logger, java.util.logging.Logger parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Logger getLogger(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getLoggerNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void readConfiguration() throws java.io.IOException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void resetLogger(java.util.logging.Logger logger) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String[] parseClassNames(java.lang.String propertyName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void readConfiguration(java.io.InputStream ins)
+            throws java.io.IOException, java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getProperty(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.String getStringProperty(java.lang.String name, java.lang.String defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getIntProperty(java.lang.String name, int defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean getBooleanProperty(java.lang.String name, boolean defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.logging.Level getLevelProperty(
+            java.lang.String name, java.util.logging.Level defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.logging.Filter getFilterProperty(
+            java.lang.String name, java.util.logging.Filter defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    java.util.logging.Formatter getFormatterProperty(
+            java.lang.String name, java.util.logging.Formatter defaultValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void initializeGlobalHandlers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void checkPermission() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void checkAccess() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void setLevelsOnExistingLoggers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized java.util.logging.LoggingMXBean getLoggingMXBean() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
+
+    private static final int MAX_ITERATIONS = 400; // 0x190
+
+    private java.util.WeakHashMap<java.lang.Object, java.util.logging.LogManager.LoggerContext>
+            contextsMap;
+
+    private final java.security.Permission controlPermission;
+
+    {
+        controlPermission = null;
+    }
+
+    private boolean deathImminent;
+
+    private static final java.util.logging.Level defaultLevel;
+
+    static {
+        defaultLevel = null;
+    }
+
+    private volatile boolean initializationDone = false;
+
+    private boolean initializedCalled = false;
+
+    private boolean initializedGlobalHandlers = true;
+
+    private final java.util.Map<java.lang.Object, java.lang.Integer> listenerMap;
+
+    {
+        listenerMap = null;
+    }
+
+    private final java.lang.ref.ReferenceQueue<java.util.logging.Logger> loggerRefQueue;
+
+    {
+        loggerRefQueue = null;
+    }
+
+    private static java.util.logging.LoggingMXBean loggingMXBean;
+
+    private static final java.util.logging.LogManager manager;
+
+    static {
+        manager = null;
+    }
+
+    private volatile java.util.Properties props;
+
+    private volatile boolean readPrimordialConfiguration;
+
+    private volatile java.util.logging.Logger rootLogger;
+
+    private final java.util.logging.LogManager.LoggerContext systemContext;
+
+    {
+        systemContext = null;
+    }
+
+    private final java.util.logging.LogManager.LoggerContext userContext;
+
+    {
+        userContext = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Beans {
+
+        private Beans() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.Class<?> getClass(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.reflect.Constructor<?> getConstructor(
+                java.lang.Class<?> c, java.lang.Class<?>... types) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static java.lang.reflect.Method getMethod(
+                java.lang.Class<?> c, java.lang.String name, java.lang.Class<?>... types) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static boolean isBeansPresent() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static java.lang.Object newPropertyChangeEvent(
+                java.lang.Object source,
+                java.lang.String prop,
+                java.lang.Object oldValue,
+                java.lang.Object newValue) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static void invokePropertyChange(java.lang.Object listener, java.lang.Object ev) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.lang.Class<?> propertyChangeEventClass;
+
+        static {
+            propertyChangeEventClass = null;
+        }
+
+        private static final java.lang.Class<?> propertyChangeListenerClass;
+
+        static {
+            propertyChangeListenerClass = null;
+        }
+
+        private static final java.lang.reflect.Method propertyChangeMethod;
+
+        static {
+            propertyChangeMethod = null;
+        }
+
+        private static final java.lang.reflect.Constructor<?> propertyEventCtor;
+
+        static {
+            propertyEventCtor = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class Cleaner extends java.lang.Thread {
+
+        private Cleaner() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void run() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class LogNode {
+
+        LogNode(
+                java.util.logging.LogManager.LogNode parent,
+                java.util.logging.LogManager.LoggerContext context) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void walkAndSetParent(java.util.logging.Logger parent) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.HashMap<java.lang.String, java.util.logging.LogManager.LogNode> children;
+
+        final java.util.logging.LogManager.LoggerContext context;
+
+        {
+            context = null;
+        }
+
+        java.util.logging.LogManager.LoggerWeakRef loggerRef;
+
+        java.util.logging.LogManager.LogNode parent;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    class LoggerContext {
+
+        private LoggerContext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final boolean requiresDefaultLoggers() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.logging.LogManager getOwner() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.logging.Logger getRootLogger() {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.logging.Logger getGlobalLogger() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.logging.Logger demandLogger(
+                java.lang.String name, java.lang.String resourceBundleName) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void ensureInitialized() {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized java.util.logging.Logger findLogger(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void ensureAllDefaultLoggers(java.util.logging.Logger logger) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void ensureDefaultLogger(java.util.logging.Logger logger) {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean addLocalLogger(java.util.logging.Logger logger) {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized boolean addLocalLogger(
+                java.util.logging.Logger logger, boolean addDefaultLoggersIfNeeded) {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized void removeLoggerRef(
+                java.lang.String name, java.util.logging.LogManager.LoggerWeakRef ref) {
+            throw new RuntimeException("Stub!");
+        }
+
+        synchronized java.util.Enumeration<java.lang.String> getLoggerNames() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void processParentHandlers(java.util.logging.Logger logger, java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.logging.LogManager.LogNode getNode(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.Hashtable<
+                        java.lang.String, java.util.logging.LogManager.LoggerWeakRef>
+                namedLoggers;
+
+        {
+            namedLoggers = null;
+        }
+
+        private final java.util.logging.LogManager.LogNode root;
+
+        {
+            root = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class LoggerWeakRef extends java.lang.ref.WeakReference<java.util.logging.Logger> {
+
+        LoggerWeakRef(java.util.logging.Logger logger) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        void dispose() {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setNode(java.util.logging.LogManager.LogNode node) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setParentRef(java.lang.ref.WeakReference<java.util.logging.Logger> parentRef) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean disposed = false;
+
+        private java.lang.String name;
+
+        private java.util.logging.LogManager.LogNode node;
+
+        private java.lang.ref.WeakReference<java.util.logging.Logger> parentRef;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private final class RootLogger extends java.util.logging.Logger {
+
+        private RootLogger() {
+            super("", null, null, LogManager.this, true);
+            throw new RuntimeException("Stub!");
+        }
+
+        public void log(java.util.logging.LogRecord record) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void addHandler(java.util.logging.Handler h) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void removeHandler(java.util.logging.Handler h) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.logging.Handler[] accessCheckedHandlers() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    final class SystemLoggerContext extends java.util.logging.LogManager.LoggerContext {
+
+        SystemLoggerContext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.util.logging.Logger demandLogger(
+                java.lang.String name, java.lang.String resourceBundleName) {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/logging/Logger.java b/ojluni/annotations/hiddenapi/java/util/logging/Logger.java
new file mode 100644
index 0000000..f504c96
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/logging/Logger.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2000, 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.logging;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Logger {
+
+    protected Logger(java.lang.String name, java.lang.String resourceBundleName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    Logger(
+            java.lang.String name,
+            java.lang.String resourceBundleName,
+            java.lang.Class<?> caller,
+            java.util.logging.LogManager manager,
+            boolean isSystemLogger) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private Logger(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.util.logging.Logger getGlobal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setCallersClassLoaderRef(java.lang.Class<?> caller) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.ClassLoader getCallersClassLoader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setLogManager(java.util.logging.LogManager manager) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkPermission() throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.logging.Logger demandLogger(
+            java.lang.String name, java.lang.String resourceBundleName, java.lang.Class<?> caller) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.logging.Logger getLogger(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.logging.Logger getLogger(
+            java.lang.String name, java.lang.String resourceBundleName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.util.logging.Logger getPlatformLogger(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.logging.Logger getAnonymousLogger() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.logging.Logger getAnonymousLogger(java.lang.String resourceBundleName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.ResourceBundle getResourceBundle() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getResourceBundleName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setFilter(java.util.logging.Filter newFilter) throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Filter getFilter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(java.util.logging.LogRecord record) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void doLog(java.util.logging.LogRecord lr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(java.util.logging.Level level, java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(
+            java.util.logging.Level level,
+            java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(java.util.logging.Level level, java.lang.String msg, java.lang.Object param1) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(
+            java.util.logging.Level level, java.lang.String msg, java.lang.Object[] params) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(
+            java.util.logging.Level level, java.lang.String msg, java.lang.Throwable thrown) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void log(
+            java.util.logging.Level level,
+            java.lang.Throwable thrown,
+            java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String msg,
+            java.lang.Object param1) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String msg,
+            java.lang.Object[] params) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String msg,
+            java.lang.Throwable thrown) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logp(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.Throwable thrown,
+            java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void doLog(java.util.logging.LogRecord lr, java.lang.String rbname) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void doLog(java.util.logging.LogRecord lr, java.util.ResourceBundle rb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String bundleName,
+            java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String bundleName,
+            java.lang.String msg,
+            java.lang.Object param1) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String bundleName,
+            java.lang.String msg,
+            java.lang.Object[] params) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.util.ResourceBundle bundle,
+            java.lang.String msg,
+            java.lang.Object... params) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.String bundleName,
+            java.lang.String msg,
+            java.lang.Throwable thrown) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void logrb(
+            java.util.logging.Level level,
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.util.ResourceBundle bundle,
+            java.lang.String msg,
+            java.lang.Throwable thrown) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void entering(java.lang.String sourceClass, java.lang.String sourceMethod) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void entering(
+            java.lang.String sourceClass, java.lang.String sourceMethod, java.lang.Object param1) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void entering(
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.Object[] params) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void exiting(java.lang.String sourceClass, java.lang.String sourceMethod) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void exiting(
+            java.lang.String sourceClass, java.lang.String sourceMethod, java.lang.Object result) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void throwing(
+            java.lang.String sourceClass,
+            java.lang.String sourceMethod,
+            java.lang.Throwable thrown) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void severe(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void warning(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void info(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void config(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void fine(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finer(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finest(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void severe(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void warning(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void info(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void config(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void fine(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finer(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finest(java.util.function.Supplier<java.lang.String> msgSupplier) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLevel(java.util.logging.Level newLevel) throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    final boolean isLevelInitialized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Level getLevel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLoggable(java.util.logging.Level level) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addHandler(java.util.logging.Handler handler) throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void removeHandler(java.util.logging.Handler handler)
+            throws java.lang.SecurityException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Handler[] getHandlers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.util.logging.Handler[] accessCheckedHandlers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setUseParentHandlers(boolean useParentHandlers) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getUseParentHandlers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.ResourceBundle findSystemResourceBundle(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized java.util.ResourceBundle findResourceBundle(
+            java.lang.String name, boolean useCallersClassLoader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void setupResourceInfo(
+            java.lang.String name, java.lang.Class<?> callersClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setResourceBundle(java.util.ResourceBundle bundle) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.logging.Logger getParent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setParent(java.util.logging.Logger parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void doSetParent(java.util.logging.Logger newParent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final void removeChildLogger(java.util.logging.LogManager.LoggerWeakRef child) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void updateEffectiveLevel() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.logging.Logger.LoggerBundle getEffectiveLoggerBundle() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String GLOBAL_LOGGER_NAME = "global";
+
+    private static final java.util.logging.Logger.LoggerBundle NO_RESOURCE_BUNDLE;
+
+    static {
+        NO_RESOURCE_BUNDLE = null;
+    }
+
+    private static final java.util.logging.Logger.LoggerBundle SYSTEM_BUNDLE;
+
+    static {
+        SYSTEM_BUNDLE = null;
+    }
+
+    static final java.lang.String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
+
+    private boolean anonymous;
+
+    private java.lang.ref.WeakReference<java.lang.ClassLoader> callersClassLoaderRef;
+
+    private java.util.ResourceBundle catalog;
+
+    private java.util.Locale catalogLocale;
+
+    private java.lang.String catalogName;
+
+    private static final java.util.logging.Handler[] emptyHandlers;
+
+    static {
+        emptyHandlers = new java.util.logging.Handler[0];
+    }
+
+    private volatile java.util.logging.Filter filter;
+
+    @Deprecated public static final java.util.logging.Logger global;
+
+    static {
+        global = null;
+    }
+
+    private final java.util.concurrent.CopyOnWriteArrayList<java.util.logging.Handler> handlers;
+
+    {
+        handlers = null;
+    }
+
+    private final boolean isSystemLogger;
+
+    {
+        isSystemLogger = false;
+    }
+
+    private java.util.ArrayList<java.util.logging.LogManager.LoggerWeakRef> kids;
+
+    private volatile java.util.logging.Level levelObject;
+
+    private volatile int levelValue;
+
+    private volatile java.util.logging.Logger.LoggerBundle loggerBundle;
+
+    private volatile java.util.logging.LogManager manager;
+
+    private java.lang.String name;
+
+    private static final int offValue;
+
+    static {
+        offValue = 0;
+    }
+
+    private volatile java.util.logging.Logger parent;
+
+    @UnsupportedAppUsage
+    private static final java.lang.Object treeLock;
+
+    static {
+        treeLock = null;
+    }
+
+    private volatile boolean useParentHandlers = true;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class LoggerBundle {
+
+        private LoggerBundle(java.lang.String resourceBundleName, java.util.ResourceBundle bundle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean isSystemBundle() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static java.util.logging.Logger.LoggerBundle get(
+                java.lang.String name, java.util.ResourceBundle bundle) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.lang.String resourceBundleName;
+
+        {
+            resourceBundleName = null;
+        }
+
+        final java.util.ResourceBundle userBundle;
+
+        {
+            userBundle = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SystemLoggerHelper {
+
+        private SystemLoggerHelper() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static boolean getBooleanProperty(java.lang.String key) {
+            throw new RuntimeException("Stub!");
+        }
+
+        static boolean disableCallerCheck;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java b/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java
new file mode 100644
index 0000000..18d6d95
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java
@@ -0,0 +1,309 @@
+/*
+ * 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.util.regex;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Matcher implements java.util.regex.MatchResult {
+
+    Matcher(java.util.regex.Pattern parent, java.lang.CharSequence text) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Pattern pattern() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.MatchResult toMatchResult() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher usePattern(java.util.regex.Pattern newPattern) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher reset(java.lang.CharSequence input) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int start() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int start(int group) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int start(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int end() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int end(int group) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int end(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String group() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String group(int group) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String group(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int groupCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean matches() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean find() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean find(int start) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean lookingAt() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String quoteReplacement(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher appendReplacement(
+            java.lang.StringBuffer sb, java.lang.String replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void appendEvaluated(java.lang.StringBuffer buffer, java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.StringBuffer appendTail(java.lang.StringBuffer sb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String replaceAll(java.lang.String replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String replaceFirst(java.lang.String replacement) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher region(int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int regionStart() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int regionEnd() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasTransparentBounds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher useTransparentBounds(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasAnchoringBounds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.regex.Matcher useAnchoringBounds(boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hitEnd() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean requireEnd() {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getTextLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.lang.CharSequence getSubSequence(int beginIndex, int endIndex) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.regex.Matcher reset(java.lang.CharSequence input, int start, int end) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void resetForInput() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureMatch() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getMatchedGroupIndex(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native int getMatchedGroupIndex0(long patternAddr, java.lang.String name);
+
+    private static native boolean findImpl(long addr, int startIndex, int[] offsets);
+
+    private static native boolean findNextImpl(long addr, int[] offsets);
+
+    private static native long getNativeFinalizer();
+
+    private static native int groupCountImpl(long addr);
+
+    private static native boolean hitEndImpl(long addr);
+
+    private static native boolean lookingAtImpl(long addr, int[] offsets);
+
+    private static native boolean matchesImpl(long addr, int[] offsets);
+
+    private static native int nativeSize();
+
+    private static native long openImpl(long patternAddr);
+
+    private static native boolean requireEndImpl(long addr);
+
+    private static native void setInputImpl(long addr, java.lang.String s, int start, int end);
+
+    private static native void useAnchoringBoundsImpl(long addr, boolean value);
+
+    private static native void useTransparentBoundsImpl(long addr, boolean value);
+
+    private long address;
+
+    boolean anchoringBounds = true;
+
+    @UnsupportedAppUsage
+    int appendPos = 0; // 0x0
+
+    int from;
+
+    int[] groups;
+
+    private boolean matchFound;
+
+    private java.lang.Runnable nativeFinalizer;
+
+    private java.lang.CharSequence originalInput;
+
+    private java.util.regex.Pattern parentPattern;
+
+    private static final libcore.util.NativeAllocationRegistry registry;
+
+    static {
+        registry = null;
+    }
+
+    java.lang.String text;
+
+    int to;
+
+    boolean transparentBounds = false;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static final class OffsetBasedMatchResult implements java.util.regex.MatchResult {
+
+        OffsetBasedMatchResult(java.lang.String input, int[] offsets) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int start() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int start(int group) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int end() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int end(int group) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String group() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String group(int group) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int groupCount() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.String input;
+
+        {
+            input = null;
+        }
+
+        private final int[] offsets;
+
+        {
+            offsets = new int[0];
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/Adler32.java b/ojluni/annotations/hiddenapi/java/util/zip/Adler32.java
new file mode 100644
index 0000000..f78844f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/Adler32.java
@@ -0,0 +1,69 @@
+/*
+ * 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.util.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Adler32 implements java.util.zip.Checksum {
+
+    public Adler32() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(int b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(java.nio.ByteBuffer buffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native int update(int adler, int b);
+
+    private static native int updateBytes(int adler, byte[] b, int off, int len);
+
+    private static native int updateByteBuffer(int adler, long addr, int off, int len);
+
+    private int adler = 1; // 0x1
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/CRC32.java b/ojluni/annotations/hiddenapi/java/util/zip/CRC32.java
new file mode 100644
index 0000000..0e25349
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/CRC32.java
@@ -0,0 +1,69 @@
+/*
+ * 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.util.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CRC32 implements java.util.zip.Checksum {
+
+    public CRC32() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(int b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void update(java.nio.ByteBuffer buffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native int update(int crc, int b);
+
+    private static native int updateBytes(int crc, byte[] b, int off, int len);
+
+    private static native int updateByteBuffer(int adler, long addr, int off, int len);
+
+    private int crc;
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java b/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java
new file mode 100644
index 0000000..f8f419d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java
@@ -0,0 +1,202 @@
+/*
+ * 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.util.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Deflater {
+
+    public Deflater(int level, boolean nowrap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Deflater(int level) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Deflater() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInput(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInput(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDictionary(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDictionary(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setStrategy(int strategy) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLevel(int level) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean needsInput() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finish() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean finished() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int deflate(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int deflate(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int deflate(byte[] b, int off, int len, int flush) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getAdler() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getTotalIn() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getBytesRead() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getTotalOut() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getBytesWritten() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void end() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpen() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native long init(int level, int strategy, boolean nowrap);
+
+    private static native void setDictionary(long addr, byte[] b, int off, int len);
+
+    private native int deflateBytes(long addr, byte[] b, int off, int len, int flush);
+
+    private static native int getAdler(long addr);
+
+    private static native void reset(long addr);
+
+    private static native void end(long addr);
+
+    public static final int BEST_COMPRESSION = 9; // 0x9
+
+    public static final int BEST_SPEED = 1; // 0x1
+
+    public static final int DEFAULT_COMPRESSION = -1; // 0xffffffff
+
+    public static final int DEFAULT_STRATEGY = 0; // 0x0
+
+    public static final int DEFLATED = 8; // 0x8
+
+    public static final int FILTERED = 1; // 0x1
+
+    public static final int FULL_FLUSH = 3; // 0x3
+
+    public static final int HUFFMAN_ONLY = 2; // 0x2
+
+    public static final int NO_COMPRESSION = 0; // 0x0
+
+    public static final int NO_FLUSH = 0; // 0x0
+
+    public static final int SYNC_FLUSH = 2; // 0x2
+
+    @UnsupportedAppUsage
+    private byte[] buf;
+
+    private long bytesRead;
+
+    private long bytesWritten;
+
+    @UnsupportedAppUsage
+    private boolean finish;
+
+    @UnsupportedAppUsage
+    private boolean finished;
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    @UnsupportedAppUsage
+    private int len;
+
+    @UnsupportedAppUsage
+    private int level;
+
+    @UnsupportedAppUsage
+    private int off;
+
+    @UnsupportedAppUsage
+    private boolean setParams;
+
+    @UnsupportedAppUsage
+    private int strategy;
+
+    private final java.util.zip.ZStreamRef zsRef;
+
+    {
+        zsRef = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java b/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java
new file mode 100644
index 0000000..c4194d2
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java
@@ -0,0 +1,171 @@
+/*
+ * 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.util.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Inflater {
+
+    public Inflater(boolean nowrap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Inflater() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInput(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setInput(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDictionary(byte[] b, int off, int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setDictionary(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getRemaining() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean needsInput() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean needsDictionary() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean finished() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int inflate(byte[] b, int off, int len) throws java.util.zip.DataFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int inflate(byte[] b) throws java.util.zip.DataFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getAdler() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getTotalIn() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getBytesRead() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getTotalOut() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getBytesWritten() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void end() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpen() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean ended() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native long init(boolean nowrap);
+
+    private static native void setDictionary(long addr, byte[] b, int off, int len);
+
+    private native int inflateBytes(long addr, byte[] b, int off, int len)
+            throws java.util.zip.DataFormatException;
+
+    private static native int getAdler(long addr);
+
+    private static native void reset(long addr);
+
+    private static native void end(long addr);
+
+    @UnsupportedAppUsage
+    private byte[] buf;
+
+    private long bytesRead;
+
+    private long bytesWritten;
+
+    private static final byte[] defaultBuf;
+
+    static {
+        defaultBuf = new byte[0];
+    }
+
+    @UnsupportedAppUsage
+    private boolean finished;
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    @UnsupportedAppUsage
+    private int len;
+
+    @UnsupportedAppUsage
+    private boolean needDict;
+
+    @UnsupportedAppUsage
+    private int off;
+
+    private final java.util.zip.ZStreamRef zsRef;
+
+    {
+        zsRef = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java
new file mode 100644
index 0000000..87ca0f5
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ZipEntry implements java.util.zip.ZipConstants, java.lang.Cloneable {
+
+    @UnsupportedAppUsage
+    public ZipEntry(
+            java.lang.String name,
+            java.lang.String comment,
+            long crc,
+            long compressedSize,
+            long size,
+            int compressionMethod,
+            int xdostime,
+            byte[] extra,
+            long dataOffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipEntry(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipEntry(java.util.zip.ZipEntry e) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ZipEntry() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getDataOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setTime(long time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.file.attribute.FileTime getLastModifiedTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.file.attribute.FileTime getLastAccessTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.file.attribute.FileTime getCreationTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setSize(long size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getCompressedSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCompressedSize(long csize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setCrc(long crc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getCrc() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMethod(int method) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setExtra(byte[] extra) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setExtra0(byte[] extra, boolean doZIP64) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getExtra() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setComment(java.lang.String comment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getComment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isDirectory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int DEFLATED = 8; // 0x8
+
+    static final long DOSTIME_BEFORE_1980 = 2162688L; // 0x210000L
+
+    public static final int STORED = 0; // 0x0
+
+    public static final long UPPER_DOSTIME_BOUND = 4036608000000L; // 0x3abd8960000L
+
+    java.nio.file.attribute.FileTime atime;
+
+    java.lang.String comment;
+
+    long crc = -1; // 0xffffffff
+
+    long csize = -1; // 0xffffffff
+
+    java.nio.file.attribute.FileTime ctime;
+
+    long dataOffset;
+
+    byte[] extra;
+
+    int flag = 0; // 0x0
+
+    @UnsupportedAppUsage
+    int method = -1; // 0xffffffff
+
+    java.nio.file.attribute.FileTime mtime;
+
+    java.lang.String name;
+
+    long size = -1; // 0xffffffff
+
+    long xdostime = -1; // 0xffffffff
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java
new file mode 100644
index 0000000..371659a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ZipFile implements java.util.zip.ZipConstants, java.io.Closeable {
+
+    public ZipFile(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipFile(java.io.File file, int mode) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipFile(java.io.File file) throws java.io.IOException, java.util.zip.ZipException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipFile(java.io.File file, int mode, java.nio.charset.Charset charset)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipFile(java.lang.String name, java.nio.charset.Charset charset)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipFile(java.io.File file, java.nio.charset.Charset charset) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getComment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry getEntry(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native long getEntry(long jzfile, byte[] name, boolean addSlash);
+
+    private static native void freeEntry(long jzfile, long jzentry);
+
+    public java.io.InputStream getInputStream(java.util.zip.ZipEntry entry)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.zip.Inflater getInflater() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void releaseInflater(java.util.zip.Inflater inf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.zip.ZipEntry getZipEntry(java.lang.String name, long jzentry) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native long getNextEntry(long jzfile, int i);
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static native void close(long jzfile);
+
+    private void ensureOpen() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpenOrZipException() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean startsWithLocHeader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getFileDescriptor() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static native int getFileDescriptor(long jzfile);
+
+    private static native long open(
+            java.lang.String name, int mode, long lastModified, boolean usemmap)
+            throws java.io.IOException;
+
+    private static native int getTotal(long jzfile);
+
+    private static native boolean startsWithLOC(long jzfile);
+
+    private static native int read(long jzfile, long jzentry, long pos, byte[] b, int off, int len);
+
+    private static native long getEntryTime(long jzentry);
+
+    private static native long getEntryCrc(long jzentry);
+
+    private static native long getEntryCSize(long jzentry);
+
+    private static native long getEntrySize(long jzentry);
+
+    private static native int getEntryMethod(long jzentry);
+
+    private static native int getEntryFlag(long jzentry);
+
+    private static native byte[] getCommentBytes(long jzfile);
+
+    private static native byte[] getEntryBytes(long jzentry, int type);
+
+    private static native java.lang.String getZipMessage(long jzfile);
+
+    private static final int DEFLATED = 8; // 0x8
+
+    private static final int JZENTRY_COMMENT = 2; // 0x2
+
+    private static final int JZENTRY_EXTRA = 1; // 0x1
+
+    private static final int JZENTRY_NAME = 0; // 0x0
+
+    public static final int OPEN_DELETE = 4; // 0x4
+
+    public static final int OPEN_READ = 1; // 0x1
+
+    private static final int STORED = 0; // 0x0
+
+    private volatile boolean closeRequested = false;
+
+    private final java.io.File fileToRemoveOnClose;
+
+    {
+        fileToRemoveOnClose = null;
+    }
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    private java.util.Deque<java.util.zip.Inflater> inflaterCache;
+
+    @UnsupportedAppUsage
+    private long jzfile;
+
+    private final boolean locsig;
+
+    {
+        locsig = false;
+    }
+
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    private final java.util.Map<java.io.InputStream, java.util.zip.Inflater> streams;
+
+    {
+        streams = null;
+    }
+
+    private final int total;
+
+    {
+        total = 0;
+    }
+
+    private static final boolean usemmap;
+
+    static {
+        usemmap = false;
+    }
+
+    private java.util.zip.ZipCoder zc;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ZipEntryIterator
+            implements java.util.Enumeration<java.util.zip.ZipEntry>,
+                    java.util.Iterator<java.util.zip.ZipEntry> {
+
+        public ZipEntryIterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasMoreElements() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        public java.util.zip.ZipEntry nextElement() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.zip.ZipEntry next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int i = 0; // 0x0
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ZipFileInflaterInputStream extends java.util.zip.InflaterInputStream {
+
+        ZipFileInflaterInputStream(
+                java.util.zip.ZipFile.ZipFileInputStream zfin,
+                java.util.zip.Inflater inf,
+                int size) {
+            super((java.io.InputStream) null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void fill() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int available() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void finalize() throws java.lang.Throwable {
+            throw new RuntimeException("Stub!");
+        }
+
+        private volatile boolean closeRequested = false;
+
+        private boolean eof = false;
+
+        private final java.util.zip.ZipFile.ZipFileInputStream zfin;
+
+        {
+            zfin = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private class ZipFileInputStream extends java.io.InputStream {
+
+        ZipFileInputStream(long jzentry) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read(byte[] b, int off, int len) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int read() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long skip(long n) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int available() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public long size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void finalize() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected long jzentry;
+
+        private long pos;
+
+        protected long rem;
+
+        protected long size;
+
+        private volatile boolean zfisCloseRequested = false;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java
new file mode 100644
index 0000000..90947b7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ZipInputStream extends java.util.zip.InflaterInputStream
+        implements java.util.zip.ZipConstants {
+
+    public ZipInputStream(java.io.InputStream in) {
+        super((java.io.InputStream) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipInputStream(java.io.InputStream in, java.nio.charset.Charset charset) {
+        super((java.io.InputStream) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpen() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.zip.ZipEntry getNextEntry() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void closeEntry() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int available() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long skip(long n) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.zip.ZipEntry readLOC() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.util.zip.ZipEntry createZipEntry(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readEnd(java.util.zip.ZipEntry e) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readFully(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int DEFLATED = 8; // 0x8
+
+    private static final int STORED = 0; // 0x0
+
+    private byte[] b;
+
+    private boolean closed = false;
+
+    private java.util.zip.CRC32 crc;
+
+    private java.util.zip.ZipEntry entry;
+
+    private boolean entryEOF = false;
+
+    @UnsupportedAppUsage
+    private int flag;
+
+    private long remaining;
+
+    @UnsupportedAppUsage
+    private byte[] tmpbuf;
+
+    private java.util.zip.ZipCoder zc;
+}
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipOutputStream.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipOutputStream.java
new file mode 100644
index 0000000..943fefa
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipOutputStream.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.zip;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ZipOutputStream extends java.util.zip.DeflaterOutputStream
+        implements java.util.zip.ZipConstants {
+
+    public ZipOutputStream(java.io.OutputStream out) {
+        super((java.io.OutputStream) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public ZipOutputStream(java.io.OutputStream out, java.nio.charset.Charset charset) {
+        super((java.io.OutputStream) null);
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int version(java.util.zip.ZipEntry e) throws java.util.zip.ZipException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpen() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setComment(java.lang.String comment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setMethod(int method) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setLevel(int level) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putNextEntry(java.util.zip.ZipEntry e) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void closeEntry() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void write(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void finish() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeLOC(java.util.zip.ZipOutputStream.XEntry xentry) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeEXT(java.util.zip.ZipEntry e) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeCEN(java.util.zip.ZipOutputStream.XEntry xentry) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeEND(long off, long len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getExtraLen(byte[] extra) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeExtra(byte[] extra) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeByte(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeShort(int v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeInt(long v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeLong(long v) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeBytes(byte[] b, int off, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int DEFLATED = 8; // 0x8
+
+    public static final int STORED = 0; // 0x0
+
+    private boolean closed = false;
+
+    private byte[] comment;
+
+    private java.util.zip.CRC32 crc;
+
+    private java.util.zip.ZipOutputStream.XEntry current;
+
+    private boolean finished;
+
+    private static final boolean inhibitZip64 = false;
+
+    private long locoff = 0; // 0x0
+
+    @UnsupportedAppUsage
+    private int method = 8; // 0x8
+
+    @UnsupportedAppUsage
+    private java.util.HashSet<java.lang.String> names;
+
+    @UnsupportedAppUsage
+    private long written = 0; // 0x0
+
+    private java.util.Vector<java.util.zip.ZipOutputStream.XEntry> xentries;
+
+    private final java.util.zip.ZipCoder zc;
+
+    {
+        zc = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class XEntry {
+
+        public XEntry(java.util.zip.ZipEntry entry, long offset) {
+            throw new RuntimeException("Stub!");
+        }
+
+        final java.util.zip.ZipEntry entry;
+
+        {
+            entry = null;
+        }
+
+        final long offset;
+
+        {
+            offset = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/javax/net/ssl/SSLServerSocketFactory.java b/ojluni/annotations/hiddenapi/javax/net/ssl/SSLServerSocketFactory.java
new file mode 100644
index 0000000..26989a8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/javax/net/ssl/SSLServerSocketFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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 javax.net.ssl;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SSLServerSocketFactory extends javax.net.ServerSocketFactory {
+
+    protected SSLServerSocketFactory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void log(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized javax.net.ServerSocketFactory getDefault() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.String[] getDefaultCipherSuites();
+
+    public abstract java.lang.String[] getSupportedCipherSuites();
+
+    /**
+     * @deprecated Use {@link #getDefault()} to read the current default; from Android API
+     * level 21 onwards, apps should have no need to ever write this value because it is
+     * automatically recomputed when the set of {@link java.security.Provider security providers}
+     * changes.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P,
+        trackingBug = 118741276)
+    private static javax.net.ssl.SSLServerSocketFactory defaultServerSocketFactory;
+
+    private static int lastVersion = -1; // 0xffffffff
+}
diff --git a/ojluni/annotations/hiddenapi/javax/net/ssl/SSLSocketFactory.java b/ojluni/annotations/hiddenapi/javax/net/ssl/SSLSocketFactory.java
new file mode 100644
index 0000000..6ce4b5e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/javax/net/ssl/SSLSocketFactory.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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 javax.net.ssl;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SSLSocketFactory extends javax.net.SocketFactory {
+
+    public SSLSocketFactory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void log(java.lang.String msg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized javax.net.SocketFactory getDefault() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String getSecurityProperty(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.String[] getDefaultCipherSuites();
+
+    public abstract java.lang.String[] getSupportedCipherSuites();
+
+    public abstract java.net.Socket createSocket(
+            java.net.Socket s, java.lang.String host, int port, boolean autoClose)
+            throws java.io.IOException;
+
+    @UnsupportedAppUsage
+    public java.net.Socket createSocket(
+            java.net.Socket s, java.io.InputStream consumed, boolean autoClose)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final boolean DEBUG;
+
+    static {
+        DEBUG = false;
+    }
+
+    /**
+     * @deprecated Use {@link #getDefault()} to read the current default; from Android API
+     * level 21 onwards, apps should have no need to ever write this value because it is
+     * automatically recomputed when the set of {@link java.security.Provider security providers}
+     * changes.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P,
+            trackingBug = 118741276)
+    private static javax.net.ssl.SSLSocketFactory defaultSocketFactory;
+
+    private static int lastVersion = -1; // 0xffffffff
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/ASCIICaseInsensitiveComparator.java b/ojluni/annotations/hiddenapi/sun/misc/ASCIICaseInsensitiveComparator.java
new file mode 100644
index 0000000..b632c1e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/ASCIICaseInsensitiveComparator.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ASCIICaseInsensitiveComparator implements java.util.Comparator<java.lang.String> {
+
+    public ASCIICaseInsensitiveComparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compare(java.lang.String s1, java.lang.String s2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static int lowerCaseHashCode(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isLower(int ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isUpper(int ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int toLower(int ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int toUpper(int ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+
+    static {
+        CASE_INSENSITIVE_ORDER = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/BASE64Decoder.java b/ojluni/annotations/hiddenapi/sun/misc/BASE64Decoder.java
new file mode 100644
index 0000000..2ce6dc8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/BASE64Decoder.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1995, 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class BASE64Decoder extends sun.misc.CharacterDecoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public BASE64Decoder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerAtom() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerLine() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void decodeAtom(
+            java.io.PushbackInputStream inStream, java.io.OutputStream outStream, int rem)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    byte[] decode_buffer;
+
+    private static final char[] pem_array;
+
+    static {
+        pem_array = new char[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static final byte[] pem_convert_array;
+
+    static {
+        pem_convert_array = new byte[0];
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/BASE64Encoder.java b/ojluni/annotations/hiddenapi/sun/misc/BASE64Encoder.java
new file mode 100644
index 0000000..8a9ef70
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/BASE64Encoder.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class BASE64Encoder extends sun.misc.CharacterEncoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public BASE64Encoder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerAtom() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerLine() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeAtom(java.io.OutputStream outStream, byte[] data, int offset, int len)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static final char[] pem_array;
+
+    static {
+        pem_array = new char[0];
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/CEFormatException.java b/ojluni/annotations/hiddenapi/sun/misc/CEFormatException.java
new file mode 100644
index 0000000..d351479
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/CEFormatException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1995, 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CEFormatException extends java.io.IOException {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CEFormatException(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final long serialVersionUID = -7139121221067081482L; // 0x9cecbf12f9d7f8f6L
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/CEStreamExhausted.java b/ojluni/annotations/hiddenapi/sun/misc/CEStreamExhausted.java
new file mode 100644
index 0000000..e696c67
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/CEStreamExhausted.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1995, 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CEStreamExhausted extends java.io.IOException {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CEStreamExhausted() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final long serialVersionUID = -5889118049525891904L; // 0xae45a655f9aafcc0L
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/CharacterDecoder.java b/ojluni/annotations/hiddenapi/sun/misc/CharacterDecoder.java
new file mode 100644
index 0000000..de6f942
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/CharacterDecoder.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1995, 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 sun.misc;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharacterDecoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CharacterDecoder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract int bytesPerAtom();
+
+    protected abstract int bytesPerLine();
+
+    protected void decodeBufferPrefix(
+            java.io.PushbackInputStream aStream, java.io.OutputStream bStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void decodeBufferSuffix(
+            java.io.PushbackInputStream aStream, java.io.OutputStream bStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int decodeLinePrefix(
+            java.io.PushbackInputStream aStream, java.io.OutputStream bStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void decodeLineSuffix(
+            java.io.PushbackInputStream aStream, java.io.OutputStream bStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void decodeAtom(
+            java.io.PushbackInputStream aStream, java.io.OutputStream bStream, int l)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int readFully(java.io.InputStream in, byte[] buffer, int offset, int len)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void decodeBuffer(java.io.InputStream aStream, java.io.OutputStream bStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] decodeBuffer(java.lang.String inputString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] decodeBuffer(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer decodeBufferToByteBuffer(java.lang.String inputString)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.ByteBuffer decodeBufferToByteBuffer(java.io.InputStream in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/CharacterEncoder.java b/ojluni/annotations/hiddenapi/sun/misc/CharacterEncoder.java
new file mode 100644
index 0000000..bbbf3f7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/CharacterEncoder.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharacterEncoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CharacterEncoder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract int bytesPerAtom();
+
+    protected abstract int bytesPerLine();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    protected void encodeBufferPrefix(java.io.OutputStream aStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeBufferSuffix(java.io.OutputStream aStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeLinePrefix(java.io.OutputStream aStream, int aLength)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeLineSuffix(java.io.OutputStream aStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void encodeAtom(
+            java.io.OutputStream aStream, byte[] someBytes, int anOffset, int aLength)
+            throws java.io.IOException;
+
+    protected int readFully(java.io.InputStream in, byte[] buffer) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.InputStream inStream, java.io.OutputStream outStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(byte[] aBuffer, java.io.OutputStream aStream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String encode(byte[] aBuffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] getBytes(java.nio.ByteBuffer bb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.nio.ByteBuffer aBuffer, java.io.OutputStream aStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String encode(java.nio.ByteBuffer aBuffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encodeBuffer(java.io.InputStream inStream, java.io.OutputStream outStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encodeBuffer(byte[] aBuffer, java.io.OutputStream aStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String encodeBuffer(byte[] aBuffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encodeBuffer(java.nio.ByteBuffer aBuffer, java.io.OutputStream aStream)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String encodeBuffer(java.nio.ByteBuffer aBuffer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    protected java.io.PrintStream pStream;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java b/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java
new file mode 100644
index 0000000..eb21393
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java
@@ -0,0 +1,73 @@
+/*
+ * 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 sun.misc;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Cleaner extends java.lang.ref.PhantomReference<java.lang.Object> {
+
+    private Cleaner(java.lang.Object referent, java.lang.Runnable thunk) {
+        super(null, null);
+        throw new RuntimeException("Stub!");
+    }
+
+    private static synchronized sun.misc.Cleaner add(sun.misc.Cleaner cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static synchronized boolean remove(sun.misc.Cleaner cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static sun.misc.Cleaner create(java.lang.Object ob, java.lang.Runnable thunk) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void clean() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.ref.ReferenceQueue<java.lang.Object> dummyQueue;
+
+    static {
+        dummyQueue = null;
+    }
+
+    private static sun.misc.Cleaner first;
+
+    private sun.misc.Cleaner next;
+
+    private sun.misc.Cleaner prev;
+
+    private final java.lang.Runnable thunk;
+
+    {
+        thunk = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/FloatingDecimal.java b/ojluni/annotations/hiddenapi/sun/misc/FloatingDecimal.java
new file mode 100644
index 0000000..0c210ac
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/FloatingDecimal.java
@@ -0,0 +1,506 @@
+/*
+ * 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 sun.misc;
+
+import java.util.regex.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FloatingDecimal {
+
+    public FloatingDecimal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toJavaFormatString(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toJavaFormatString(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void appendTo(double d, java.lang.Appendable buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void appendTo(float f, java.lang.Appendable buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static double parseDouble(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static float parseFloat(java.lang.String s) throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.misc.FloatingDecimal.BinaryToASCIIBuffer getBinaryToASCIIBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.misc.FloatingDecimal.BinaryToASCIIConverter getBinaryToASCIIConverter(
+            double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.misc.FloatingDecimal.BinaryToASCIIConverter getBinaryToASCIIConverter(
+            double d, boolean isCompatibleFormat) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.misc.FloatingDecimal.BinaryToASCIIConverter getBinaryToASCIIConverter(
+            float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.misc.FloatingDecimal.ASCIIToBinaryConverter readJavaFormatString(java.lang.String in)
+            throws java.lang.NumberFormatException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.misc.FloatingDecimal.ASCIIToBinaryConverter parseHexString(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static java.lang.String stripLeadingZeros(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static int getHexDigit(java.lang.String s, int position) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static boolean $assertionsDisabled;
+
+    static final sun.misc.FloatingDecimal.ASCIIToBinaryConverter A2BC_NEGATIVE_INFINITY;
+
+    static {
+        A2BC_NEGATIVE_INFINITY = null;
+    }
+
+    static final sun.misc.FloatingDecimal.ASCIIToBinaryConverter A2BC_NEGATIVE_ZERO;
+
+    static {
+        A2BC_NEGATIVE_ZERO = null;
+    }
+
+    static final sun.misc.FloatingDecimal.ASCIIToBinaryConverter A2BC_NOT_A_NUMBER;
+
+    static {
+        A2BC_NOT_A_NUMBER = null;
+    }
+
+    static final sun.misc.FloatingDecimal.ASCIIToBinaryConverter A2BC_POSITIVE_INFINITY;
+
+    static {
+        A2BC_POSITIVE_INFINITY = null;
+    }
+
+    static final sun.misc.FloatingDecimal.ASCIIToBinaryConverter A2BC_POSITIVE_ZERO;
+
+    static {
+        A2BC_POSITIVE_ZERO = null;
+    }
+
+    private static final sun.misc.FloatingDecimal.BinaryToASCIIConverter B2AC_NEGATIVE_INFINITY;
+
+    static {
+        B2AC_NEGATIVE_INFINITY = null;
+    }
+
+    private static final sun.misc.FloatingDecimal.BinaryToASCIIConverter B2AC_NEGATIVE_ZERO;
+
+    static {
+        B2AC_NEGATIVE_ZERO = null;
+    }
+
+    private static final sun.misc.FloatingDecimal.BinaryToASCIIConverter B2AC_NOT_A_NUMBER;
+
+    static {
+        B2AC_NOT_A_NUMBER = null;
+    }
+
+    private static final sun.misc.FloatingDecimal.BinaryToASCIIConverter B2AC_POSITIVE_INFINITY;
+
+    static {
+        B2AC_POSITIVE_INFINITY = null;
+    }
+
+    private static final sun.misc.FloatingDecimal.BinaryToASCIIConverter B2AC_POSITIVE_ZERO;
+
+    static {
+        B2AC_POSITIVE_ZERO = null;
+    }
+
+    static final int BIG_DECIMAL_EXPONENT = 324; // 0x144
+
+    static final long EXP_ONE = 4607182418800017408L; // 0x3ff0000000000000L
+
+    static final int EXP_SHIFT = 52; // 0x34
+
+    static final long FRACT_HOB = 4503599627370496L; // 0x10000000000000L
+
+    private static final int INFINITY_LENGTH;
+
+    static {
+        INFINITY_LENGTH = 0;
+    }
+
+    private static final java.lang.String INFINITY_REP = "Infinity";
+
+    static final int INT_DECIMAL_DIGITS = 9; // 0x9
+
+    static final int MAX_DECIMAL_DIGITS = 15; // 0xf
+
+    static final int MAX_DECIMAL_EXPONENT = 308; // 0x134
+
+    static final int MAX_NDIGITS = 1100; // 0x44c
+
+    static final int MAX_SMALL_BIN_EXP = 62; // 0x3e
+
+    static final int MIN_DECIMAL_EXPONENT = -324; // 0xfffffebc
+
+    static final int MIN_SMALL_BIN_EXP = -21; // 0xffffffeb
+
+    private static final int NAN_LENGTH;
+
+    static {
+        NAN_LENGTH = 0;
+    }
+
+    private static final java.lang.String NAN_REP = "NaN";
+
+    static final int SINGLE_EXP_SHIFT = 23; // 0x17
+
+    static final int SINGLE_FRACT_HOB = 8388608; // 0x800000
+
+    static final int SINGLE_MAX_DECIMAL_DIGITS = 7; // 0x7
+
+    static final int SINGLE_MAX_DECIMAL_EXPONENT = 38; // 0x26
+
+    static final int SINGLE_MAX_NDIGITS = 200; // 0xc8
+
+    static final int SINGLE_MIN_DECIMAL_EXPONENT = -45; // 0xffffffd3
+
+    private static final java.lang.ThreadLocal<sun.misc.FloatingDecimal.BinaryToASCIIBuffer>
+            threadLocalBinaryToASCIIBuffer;
+
+    static {
+        threadLocalBinaryToASCIIBuffer = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class ASCIIToBinaryBuffer implements sun.misc.FloatingDecimal.ASCIIToBinaryConverter {
+
+        ASCIIToBinaryBuffer(boolean negSign, int decExponent, char[] digits, int n) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public double doubleValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public float floatValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final double[] BIG_10_POW;
+
+        static {
+            BIG_10_POW = new double[0];
+        }
+
+        private static final int MAX_SMALL_TEN;
+
+        static {
+            MAX_SMALL_TEN = 0;
+        }
+
+        private static final int SINGLE_MAX_SMALL_TEN;
+
+        static {
+            SINGLE_MAX_SMALL_TEN = 0;
+        }
+
+        private static final float[] SINGLE_SMALL_10_POW;
+
+        static {
+            SINGLE_SMALL_10_POW = new float[0];
+        }
+
+        private static final double[] SMALL_10_POW;
+
+        static {
+            SMALL_10_POW = new double[0];
+        }
+
+        private static final double[] TINY_10_POW;
+
+        static {
+            TINY_10_POW = new double[0];
+        }
+
+        int decExponent;
+
+        char[] digits;
+
+        boolean isNegative;
+
+        int nDigits;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static interface ASCIIToBinaryConverter {
+
+        public double doubleValue();
+
+        public float floatValue();
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class BinaryToASCIIBuffer implements sun.misc.FloatingDecimal.BinaryToASCIIConverter {
+
+        BinaryToASCIIBuffer() {
+            throw new RuntimeException("Stub!");
+        }
+
+        BinaryToASCIIBuffer(boolean isNegative, char[] digits) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toJavaFormatString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void appendTo(java.lang.Appendable buf) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getDecimalExponent() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getDigits(char[] digits) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isNegative() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isExceptional() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean digitsRoundedUp() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean decimalDigitsExact() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void setSign(boolean isNegative) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void developLongDigits(int decExponent, long lvalue, int insignificantDigits) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void dtoa(
+                int binExp, long fractBits, int nSignificantBits, boolean isCompatibleFormat) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void roundup() {
+            throw new RuntimeException("Stub!");
+        }
+
+        static int estimateDecExp(long fractBits, int binExp) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static int insignificantDigits(int insignificant) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static int insignificantDigitsForPow2(int p2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int getChars(char[] result) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final int[] N_5_BITS;
+
+        static {
+            N_5_BITS = new int[0];
+        }
+
+        private final char[] buffer;
+
+        {
+            buffer = new char[0];
+        }
+
+        private int decExponent;
+
+        private boolean decimalDigitsRoundedUp = false;
+
+        private final char[] digits;
+
+        {
+            digits = new char[0];
+        }
+
+        private boolean exactDecimalConversion = false;
+
+        private int firstDigitIndex;
+
+        private static int[] insignificantDigitsNumber;
+
+        private boolean isNegative;
+
+        private int nDigits;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface BinaryToASCIIConverter {
+
+        public java.lang.String toJavaFormatString();
+
+        public void appendTo(java.lang.Appendable buf);
+
+        public int getDecimalExponent();
+
+        public int getDigits(char[] digits);
+
+        public boolean isNegative();
+
+        public boolean isExceptional();
+
+        public boolean digitsRoundedUp();
+
+        public boolean decimalDigitsExact();
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class ExceptionalBinaryToASCIIBuffer
+            implements sun.misc.FloatingDecimal.BinaryToASCIIConverter {
+
+        public ExceptionalBinaryToASCIIBuffer(java.lang.String image, boolean isNegative) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toJavaFormatString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void appendTo(java.lang.Appendable buf) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getDecimalExponent() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getDigits(char[] digits) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isNegative() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isExceptional() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean digitsRoundedUp() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean decimalDigitsExact() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.String image;
+
+        {
+            image = null;
+        }
+
+        private boolean isNegative;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class HexFloatPattern {
+
+        private HexFloatPattern() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final java.util.regex.Pattern VALUE;
+
+        static {
+            VALUE = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class PreparedASCIIToBinaryBuffer
+            implements sun.misc.FloatingDecimal.ASCIIToBinaryConverter {
+
+        public PreparedASCIIToBinaryBuffer(double doubleVal, float floatVal) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public double doubleValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public float floatValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final double doubleVal;
+
+        {
+            doubleVal = 0;
+        }
+
+        private final float floatVal;
+
+        {
+            floatVal = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/FormattedFloatingDecimal.java b/ojluni/annotations/hiddenapi/sun/misc/FormattedFloatingDecimal.java
new file mode 100644
index 0000000..b6766cf
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/FormattedFloatingDecimal.java
@@ -0,0 +1,110 @@
+/*
+ * 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FormattedFloatingDecimal {
+
+    private FormattedFloatingDecimal(
+            int precision,
+            sun.misc.FormattedFloatingDecimal.Form form,
+            sun.misc.FloatingDecimal.BinaryToASCIIConverter fdConverter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.misc.FormattedFloatingDecimal valueOf(
+            double d, int precision, sun.misc.FormattedFloatingDecimal.Form form) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static char[] getBuffer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getExponentRounded() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char[] getMantissa() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public char[] getExponent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int applyPrecision(int decExp, char[] digits, int nDigits, int prec) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void fillCompatible(
+            int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static char[] create(boolean isNegative, int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void fillDecimal(
+            int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void fillScientific(
+            int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static boolean $assertionsDisabled;
+
+    private int decExponentRounded;
+
+    private char[] exponent;
+
+    private char[] mantissa;
+
+    private static final java.lang.ThreadLocal<java.lang.Object> threadLocalCharBuffer;
+
+    static {
+        threadLocalCharBuffer = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum Form {
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        SCIENTIFIC,
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        COMPATIBLE,
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        DECIMAL_FLOAT,
+        GENERAL;
+
+        private Form() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/FpUtils.java b/ojluni/annotations/hiddenapi/sun/misc/FpUtils.java
new file mode 100644
index 0000000..38347bd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/FpUtils.java
@@ -0,0 +1,169 @@
+/*
+ * 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FpUtils {
+
+    private FpUtils() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static int getExponent(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static int getExponent(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static double rawCopySign(double magnitude, double sign) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float rawCopySign(float magnitude, float sign) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static boolean isFinite(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static boolean isFinite(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isInfinite(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isInfinite(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isNaN(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isNaN(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isUnordered(double arg1, double arg2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isUnordered(float arg1, float arg2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int ilogb(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int ilogb(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double scalb(double d, int scale_factor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float scalb(float f, int scale_factor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double nextAfter(double start, double direction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float nextAfter(float start, double direction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double nextUp(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float nextUp(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double nextDown(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double nextDown(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double copySign(double magnitude, double sign) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float copySign(float magnitude, float sign) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double ulp(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float ulp(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static double signum(double d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static float signum(float f) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static boolean $assertionsDisabled;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/HexDumpEncoder.java b/ojluni/annotations/hiddenapi/sun/misc/HexDumpEncoder.java
new file mode 100644
index 0000000..f278c74
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/HexDumpEncoder.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class HexDumpEncoder extends sun.misc.CharacterEncoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public HexDumpEncoder() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void hexDigit(java.io.PrintStream p, byte x) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerAtom() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected int bytesPerLine() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeBufferPrefix(java.io.OutputStream o) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeLinePrefix(java.io.OutputStream o, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeAtom(java.io.OutputStream o, byte[] buf, int off, int len)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encodeLineSuffix(java.io.OutputStream o) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int currentByte;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int offset;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private byte[] thisLine;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int thisLineLength;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/IOUtils.java b/ojluni/annotations/hiddenapi/sun/misc/IOUtils.java
new file mode 100644
index 0000000..90f7909
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/IOUtils.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+
+/** IOUtils: A collection of IO-related public static methods. */
+package sun.misc;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class IOUtils {
+
+    public IOUtils() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static byte[] readFully(java.io.InputStream is, int length, boolean readAll)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/JarIndex.java b/ojluni/annotations/hiddenapi/sun/misc/JarIndex.java
new file mode 100644
index 0000000..06187e1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/JarIndex.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class JarIndex {
+
+    public JarIndex() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public JarIndex(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public JarIndex(java.lang.String[] files) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.misc.JarIndex getJarIndex(java.util.jar.JarFile jar)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.misc.JarIndex getJarIndex(
+            java.util.jar.JarFile jar, sun.misc.MetaIndex metaIndex) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String[] getJarFiles() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void addToList(
+            java.lang.String key,
+            java.lang.String value,
+            java.util.HashMap<java.lang.String, java.util.LinkedList<java.lang.String>> t) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.LinkedList<java.lang.String> get(java.lang.String fileName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void add(java.lang.String fileName, java.lang.String jarName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void addMapping(java.lang.String jarItem, java.lang.String jarName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseJars(java.lang.String[] files) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void write(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void read(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void merge(sun.misc.JarIndex toIndex, java.lang.String path) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String INDEX_NAME = "META-INF/INDEX.LIST";
+
+    private java.util.HashMap<java.lang.String, java.util.LinkedList<java.lang.String>> indexMap;
+
+    private java.lang.String[] jarFiles;
+
+    private java.util.HashMap<java.lang.String, java.util.LinkedList<java.lang.String>> jarMap;
+
+    private static final boolean metaInfFilenames;
+
+    static {
+        metaInfFilenames = false;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/MessageUtils.java b/ojluni/annotations/hiddenapi/sun/misc/MessageUtils.java
new file mode 100644
index 0000000..bd61419
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/MessageUtils.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class MessageUtils {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public MessageUtils() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String subst(java.lang.String patt, java.lang.String arg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String subst(
+            java.lang.String patt, java.lang.String arg1, java.lang.String arg2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String subst(
+            java.lang.String patt,
+            java.lang.String arg1,
+            java.lang.String arg2,
+            java.lang.String arg3) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String subst(java.lang.String patt, java.lang.String[] args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String substProp(java.lang.String propName, java.lang.String arg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String substProp(
+            java.lang.String propName, java.lang.String arg1, java.lang.String arg2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String substProp(
+            java.lang.String propName,
+            java.lang.String arg1,
+            java.lang.String arg2,
+            java.lang.String arg3) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void err(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void out(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void where() {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/MetaIndex.java b/ojluni/annotations/hiddenapi/sun/misc/MetaIndex.java
new file mode 100644
index 0000000..b3ae0cc
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/MetaIndex.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005, 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class MetaIndex {
+
+    private MetaIndex(java.util.List<java.lang.String> entries, boolean isClassOnlyJar)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.misc.MetaIndex forJar(java.io.File jar) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static synchronized void registerDirectory(java.io.File dir) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean mayContain(java.lang.String entry) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Map<java.io.File, sun.misc.MetaIndex> getJarMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String[] contents;
+
+    private boolean isClassOnlyJar;
+
+    private static volatile java.util.Map<java.io.File, sun.misc.MetaIndex> jarMap;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/URLClassPath.java b/ojluni/annotations/hiddenapi/sun/misc/URLClassPath.java
new file mode 100644
index 0000000..7ca8bd9
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/URLClassPath.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class URLClassPath {
+
+    public URLClassPath(
+            java.net.URL[] urls,
+            java.net.URLStreamHandlerFactory factory,
+            java.security.AccessControlContext acc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URLClassPath(java.net.URL[] urls) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URLClassPath(java.net.URL[] urls, java.security.AccessControlContext acc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.List<java.io.IOException> closeLoaders() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void addURL(java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL[] getURLs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL findResource(java.lang.String name, boolean check) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.misc.Resource getResource(java.lang.String name, boolean check) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.net.URL> findResources(java.lang.String name, boolean check) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.misc.Resource getResource(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<sun.misc.Resource> getResources(
+            java.lang.String name, boolean check) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<sun.misc.Resource> getResources(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    synchronized void initLookupCache(java.lang.ClassLoader loader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void disableAllLookupCaches() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.net.URL[] getLookupCacheURLs(java.lang.ClassLoader loader) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int[] getLookupCacheForClassLoader(
+            java.lang.ClassLoader loader, java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean knownToNotExist0(
+            java.lang.ClassLoader loader, java.lang.String className) {
+        throw new RuntimeException("Stub!");
+    }
+
+    synchronized boolean knownToNotExist(java.lang.String className) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized int[] getLookupCache(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean ensureLoaderOpened(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized void validateLookupCache(int index, java.lang.String urlNoFragString) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized sun.misc.URLClassPath.Loader getNextLoader(int[] cache, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private synchronized sun.misc.URLClassPath.Loader getLoader(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.misc.URLClassPath.Loader getLoader(java.net.URL url) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void push(java.net.URL[] us) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URL[] pathToURLs(java.lang.String path) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URL checkURL(java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void check(java.net.URL url) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final boolean DEBUG;
+
+    static {
+        DEBUG = false;
+    }
+
+    private static final boolean DEBUG_LOOKUP_CACHE;
+
+    static {
+        DEBUG_LOOKUP_CACHE = false;
+    }
+
+    private static final boolean DISABLE_ACC_CHECKING;
+
+    static {
+        DISABLE_ACC_CHECKING = false;
+    }
+
+    private static final boolean DISABLE_JAR_CHECKING;
+
+    static {
+        DISABLE_JAR_CHECKING = false;
+    }
+
+    static final java.lang.String JAVA_VERSION;
+
+    static {
+        JAVA_VERSION = null;
+    }
+
+    static final java.lang.String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
+
+    private final java.security.AccessControlContext acc;
+
+    {
+        acc = null;
+    }
+
+    private boolean closed = false;
+
+    private java.net.URLStreamHandler jarHandler;
+
+    @UnsupportedAppUsage
+    java.util.HashMap<java.lang.String, sun.misc.URLClassPath.Loader> lmap;
+
+    @UnsupportedAppUsage
+    java.util.ArrayList<sun.misc.URLClassPath.Loader> loaders;
+
+    private static volatile boolean lookupCacheEnabled = false;
+
+    private java.lang.ClassLoader lookupCacheLoader;
+
+    private java.net.URL[] lookupCacheURLs;
+
+    private java.util.ArrayList<java.net.URL> path;
+
+    @UnsupportedAppUsage java.util.Stack<java.net.URL> urls;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class FileLoader extends sun.misc.URLClassPath.Loader {
+
+        FileLoader(java.net.URL url) throws java.io.IOException {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL findResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource getResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.io.File dir;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class JarLoader extends sun.misc.URLClassPath.Loader {
+
+        JarLoader(
+                java.net.URL url,
+                java.net.URLStreamHandler jarHandler,
+                java.util.HashMap<java.lang.String, sun.misc.URLClassPath.Loader> loaderMap,
+                java.security.AccessControlContext acc)
+                throws java.io.IOException {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        @UnsupportedAppUsage
+        java.util.jar.JarFile getJarFile() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private boolean isOptimizable(java.net.URL url) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void ensureOpen() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        static java.util.jar.JarFile checkJar(java.util.jar.JarFile jar)
+                throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.util.jar.JarFile getJarFile(java.net.URL url) throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.JarIndex getIndex() {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource checkResource(
+                java.lang.String name, boolean check, java.util.jar.JarEntry entry) {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean validIndex(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL findResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource getResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource getResource(
+                java.lang.String name, boolean check, java.util.Set<java.lang.String> visited) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL[] getClassPath() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void parseExtensionsDependencies() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.net.URL[] parseClassPath(java.net.URL base, java.lang.String value)
+                throws java.net.MalformedURLException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.security.AccessControlContext acc;
+
+        {
+            acc = null;
+        }
+
+        private boolean closed = false;
+
+        private final java.net.URL csu;
+
+        {
+            csu = null;
+        }
+
+        private java.net.URLStreamHandler handler;
+
+        private sun.misc.JarIndex index;
+
+        private java.util.jar.JarFile jar;
+
+        private final java.util.HashMap<java.lang.String, sun.misc.URLClassPath.Loader> lmap;
+
+        {
+            lmap = null;
+        }
+
+        private sun.misc.MetaIndex metaIndex;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Loader implements java.io.Closeable {
+
+        Loader(java.net.URL url) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL getBaseURL() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL findResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource getResource(java.lang.String name, boolean check) {
+            throw new RuntimeException("Stub!");
+        }
+
+        sun.misc.Resource getResource(java.lang.String name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void close() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.net.URL[] getClassPath() throws java.io.IOException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.net.URL base;
+
+        {
+            base = null;
+        }
+
+        private java.util.jar.JarFile jarfile;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java b/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java
new file mode 100644
index 0000000..54308e4
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java
@@ -0,0 +1,292 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VersionCodes;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Unsafe {
+
+    private Unsafe() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static sun.misc.Unsafe getUnsafe() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public long objectFieldOffset(java.lang.reflect.Field field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int arrayBaseOffset(java.lang.Class clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int arrayIndexScale(java.lang.Class clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.O)
+    private static native int getArrayBaseOffsetForComponentType(java.lang.Class component_class);
+
+    @UnsupportedAppUsage(maxTargetSdk = VersionCodes.O)
+    private static native int getArrayIndexScaleForComponentType(java.lang.Class component_class);
+
+    @UnsupportedAppUsage
+    public native boolean compareAndSwapInt(
+            java.lang.Object obj, long offset, int expectedValue, int newValue);
+
+    @UnsupportedAppUsage
+    public native boolean compareAndSwapLong(
+            java.lang.Object obj, long offset, long expectedValue, long newValue);
+
+    @UnsupportedAppUsage
+    public native boolean compareAndSwapObject(
+            java.lang.Object obj,
+            long offset,
+            java.lang.Object expectedValue,
+            java.lang.Object newValue);
+
+    @UnsupportedAppUsage
+    public native int getIntVolatile(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putIntVolatile(java.lang.Object obj, long offset, int newValue);
+
+    @UnsupportedAppUsage
+    public native long getLongVolatile(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putLongVolatile(java.lang.Object obj, long offset, long newValue);
+
+    @UnsupportedAppUsage
+    public native java.lang.Object getObjectVolatile(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putObjectVolatile(
+            java.lang.Object obj, long offset, java.lang.Object newValue);
+
+    @UnsupportedAppUsage
+    public native int getInt(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putInt(java.lang.Object obj, long offset, int newValue);
+
+    @UnsupportedAppUsage
+    public native void putOrderedInt(java.lang.Object obj, long offset, int newValue);
+
+    @UnsupportedAppUsage
+    public native long getLong(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putLong(java.lang.Object obj, long offset, long newValue);
+
+    @UnsupportedAppUsage
+    public native void putOrderedLong(java.lang.Object obj, long offset, long newValue);
+
+    @UnsupportedAppUsage
+    public native java.lang.Object getObject(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putObject(java.lang.Object obj, long offset, java.lang.Object newValue);
+
+    @UnsupportedAppUsage
+    public native void putOrderedObject(
+            java.lang.Object obj, long offset, java.lang.Object newValue);
+
+    @UnsupportedAppUsage
+    public native boolean getBoolean(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putBoolean(java.lang.Object obj, long offset, boolean newValue);
+
+    @UnsupportedAppUsage
+    public native byte getByte(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putByte(java.lang.Object obj, long offset, byte newValue);
+
+    @UnsupportedAppUsage
+    public native char getChar(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putChar(java.lang.Object obj, long offset, char newValue);
+
+    @UnsupportedAppUsage
+    public native short getShort(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putShort(java.lang.Object obj, long offset, short newValue);
+
+    @UnsupportedAppUsage
+    public native float getFloat(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putFloat(java.lang.Object obj, long offset, float newValue);
+
+    @UnsupportedAppUsage
+    public native double getDouble(java.lang.Object obj, long offset);
+
+    @UnsupportedAppUsage
+    public native void putDouble(java.lang.Object obj, long offset, double newValue);
+
+    @UnsupportedAppUsage
+    public void park(boolean absolute, long time) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void unpark(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public native java.lang.Object allocateInstance(java.lang.Class<?> c);
+
+    @UnsupportedAppUsage
+    public native int addressSize();
+
+    @UnsupportedAppUsage
+    public native int pageSize();
+
+    @UnsupportedAppUsage
+    public native long allocateMemory(long bytes);
+
+    @UnsupportedAppUsage
+    public native void freeMemory(long address);
+
+    @UnsupportedAppUsage
+    public native void setMemory(long address, long bytes, byte value);
+
+    @UnsupportedAppUsage
+    public native byte getByte(long address);
+
+    @UnsupportedAppUsage
+    public native void putByte(long address, byte x);
+
+    @UnsupportedAppUsage
+    public native short getShort(long address);
+
+    @UnsupportedAppUsage
+    public native void putShort(long address, short x);
+
+    @UnsupportedAppUsage
+    public native char getChar(long address);
+
+    @UnsupportedAppUsage
+    public native void putChar(long address, char x);
+
+    @UnsupportedAppUsage
+    public native int getInt(long address);
+
+    @UnsupportedAppUsage
+    public native void putInt(long address, int x);
+
+    @UnsupportedAppUsage
+    public native long getLong(long address);
+
+    @UnsupportedAppUsage
+    public native void putLong(long address, long x);
+
+    @UnsupportedAppUsage
+    public native float getFloat(long address);
+
+    @UnsupportedAppUsage
+    public native void putFloat(long address, float x);
+
+    @UnsupportedAppUsage
+    public native double getDouble(long address);
+
+    @UnsupportedAppUsage
+    public native void putDouble(long address, double x);
+
+    @UnsupportedAppUsage
+    public native void copyMemoryToPrimitiveArray(
+            long srcAddr, java.lang.Object dst, long dstOffset, long bytes);
+
+    @UnsupportedAppUsage
+    public native void copyMemoryFromPrimitiveArray(
+            java.lang.Object src, long srcOffset, long dstAddr, long bytes);
+
+    @UnsupportedAppUsage
+    public native void copyMemory(long srcAddr, long dstAddr, long bytes);
+
+    @UnsupportedAppUsage
+    public int getAndAddInt(java.lang.Object o, long offset, int delta) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public long getAndAddLong(java.lang.Object o, long offset, long delta) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public int getAndSetInt(java.lang.Object o, long offset, int newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public long getAndSetLong(java.lang.Object o, long offset, long newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.Object getAndSetObject(
+            java.lang.Object o, long offset, java.lang.Object newValue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public native void loadFence();
+
+    @UnsupportedAppUsage
+    public native void storeFence();
+
+    @UnsupportedAppUsage
+    public native void fullFence();
+
+    @UnsupportedAppUsage
+    public static final int INVALID_FIELD_OFFSET = -1; // 0xffffffff
+
+    @UnsupportedAppUsage private static final sun.misc.Unsafe THE_ONE;
+
+    static {
+        THE_ONE = null;
+    }
+
+    @UnsupportedAppUsage private static final sun.misc.Unsafe theUnsafe;
+
+    static {
+        theUnsafe = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/misc/VM.java b/ojluni/annotations/hiddenapi/sun/misc/VM.java
new file mode 100644
index 0000000..979818c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/misc/VM.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1996, 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 sun.misc;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class VM {
+
+    public VM() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static boolean threadsSuspended() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean allowThreadSuspension(java.lang.ThreadGroup g, boolean b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static boolean suspendThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static void unsuspendThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static void unsuspendSomeThreads() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static final int getState() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static void asChange(int as_old, int as_new) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static void asChange_otherthread(int as_old, int as_new) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void booted() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isBooted() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void awaitBooted() throws java.lang.InterruptedException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static long maxDirectMemory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isDirectMemoryPageAligned() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean allowArraySyntax() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getSavedProperty(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void saveAndRemoveProperties(java.util.Properties props) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void initializeOSEnvironment() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int getFinalRefCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int getPeakFinalRefCount() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void addFinalRefCount(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Thread.State toThreadState(int threadStatus) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int JVMTI_THREAD_STATE_ALIVE = 1; // 0x1
+
+    private static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 1024; // 0x400
+
+    private static final int JVMTI_THREAD_STATE_RUNNABLE = 4; // 0x4
+
+    private static final int JVMTI_THREAD_STATE_TERMINATED = 2; // 0x2
+
+    private static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 16; // 0x10
+
+    private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 32; // 0x20
+
+    @Deprecated public static final int STATE_GREEN = 1; // 0x1
+
+    @Deprecated public static final int STATE_RED = 3; // 0x3
+
+    @Deprecated public static final int STATE_YELLOW = 2; // 0x2
+
+    private static boolean allowArraySyntax;
+
+    private static volatile boolean booted = false;
+
+    private static boolean defaultAllowArraySyntax = false;
+
+    private static long directMemory = 67108864; // 0x4000000
+
+    private static volatile int finalRefCount = 0; // 0x0
+
+    private static final java.lang.Object lock;
+
+    static {
+        lock = null;
+    }
+
+    private static boolean pageAlignDirectMemory;
+
+    private static volatile int peakFinalRefCount = 0; // 0x0
+
+    private static final java.util.Properties savedProps;
+
+    static {
+        savedProps = null;
+    }
+
+    private static boolean suspended = false;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/net/ftp/FtpClient.java b/ojluni/annotations/hiddenapi/sun/net/ftp/FtpClient.java
new file mode 100644
index 0000000..c60accd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/net/ftp/FtpClient.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2009, 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 sun.net.ftp;
+
+import java.io.*;
+import java.net.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class FtpClient implements java.io.Closeable {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    protected FtpClient() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int defaultPort() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.net.ftp.FtpClient create() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.net.ftp.FtpClient create(java.net.InetSocketAddress dest)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.net.ftp.FtpClient create(java.lang.String dest)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract sun.net.ftp.FtpClient enablePassiveMode(boolean passive);
+
+    public abstract boolean isPassiveModeEnabled();
+
+    public abstract sun.net.ftp.FtpClient setConnectTimeout(int timeout);
+
+    public abstract int getConnectTimeout();
+
+    public abstract sun.net.ftp.FtpClient setReadTimeout(int timeout);
+
+    public abstract int getReadTimeout();
+
+    public abstract sun.net.ftp.FtpClient setProxy(java.net.Proxy p);
+
+    public abstract java.net.Proxy getProxy();
+
+    public abstract boolean isConnected();
+
+    public abstract sun.net.ftp.FtpClient connect(java.net.SocketAddress dest)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient connect(java.net.SocketAddress dest, int timeout)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.net.SocketAddress getServerAddress();
+
+    public abstract sun.net.ftp.FtpClient login(java.lang.String user, char[] password)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient login(
+            java.lang.String user, char[] password, java.lang.String account)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract void close() throws java.io.IOException;
+
+    public abstract boolean isLoggedIn();
+
+    public abstract sun.net.ftp.FtpClient changeDirectory(java.lang.String remoteDirectory)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient changeToParentDirectory()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.lang.String getWorkingDirectory()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient setRestartOffset(long offset);
+
+    public abstract sun.net.ftp.FtpClient getFile(java.lang.String name, java.io.OutputStream local)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.io.InputStream getFileStream(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public java.io.OutputStream putFileStream(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.io.OutputStream putFileStream(java.lang.String name, boolean unique)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public sun.net.ftp.FtpClient putFile(java.lang.String name, java.io.InputStream local)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract sun.net.ftp.FtpClient putFile(
+            java.lang.String name, java.io.InputStream local, boolean unique)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient appendFile(
+            java.lang.String name, java.io.InputStream local)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient rename(java.lang.String from, java.lang.String to)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient deleteFile(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient makeDirectory(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient removeDirectory(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient noop()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.lang.String getStatus(java.lang.String name)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.util.List<java.lang.String> getFeatures()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient abort()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient completePending()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient reInit()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient setType(sun.net.ftp.FtpClient.TransferType type)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public sun.net.ftp.FtpClient setBinaryType()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.net.ftp.FtpClient setAsciiType()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.io.InputStream list(java.lang.String path)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.io.InputStream nameList(java.lang.String path)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract long getSize(java.lang.String path)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.util.Date getLastModified(java.lang.String path)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient setDirParser(sun.net.ftp.FtpDirParser p);
+
+    public abstract java.util.Iterator<sun.net.ftp.FtpDirEntry> listFiles(java.lang.String path)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient useKerberos()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.lang.String getWelcomeMsg();
+
+    public abstract sun.net.ftp.FtpReplyCode getLastReplyCode();
+
+    public abstract java.lang.String getLastResponseString();
+
+    public abstract long getLastTransferSize();
+
+    public abstract java.lang.String getLastFileName();
+
+    public abstract sun.net.ftp.FtpClient startSecureSession()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient endSecureSession()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient allocate(long size)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient structureMount(java.lang.String struct)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.lang.String getSystem()
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract java.lang.String getHelp(java.lang.String cmd)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    public abstract sun.net.ftp.FtpClient siteCmd(java.lang.String cmd)
+            throws sun.net.ftp.FtpProtocolException, java.io.IOException;
+
+    private static final int FTP_PORT = 21; // 0x15
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static enum TransferType {
+        ASCII,
+        BINARY,
+        EBCDIC;
+
+        private TransferType() {
+            throw new RuntimeException("Stub!");
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java b/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java
new file mode 100644
index 0000000..710e3a8
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2004, 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 sun.net.util;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class IPAddressUtil {
+
+    public IPAddressUtil() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] textToNumericFormatV4(java.lang.String src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] textToNumericFormatV6(java.lang.String src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static boolean isIPv4LiteralAddress(java.lang.String src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static boolean isIPv6LiteralAddress(java.lang.String src) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] convertFromIPv4MappedAddress(byte[] addr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isIPv4MappedAddress(byte[] addr) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int INADDR16SZ = 16; // 0x10
+
+    private static final int INADDR4SZ = 4; // 0x4
+
+    private static final int INT16SZ = 2; // 0x2
+}
diff --git a/ojluni/annotations/hiddenapi/sun/net/www/MessageHeader.java b/ojluni/annotations/hiddenapi/sun/net/www/MessageHeader.java
new file mode 100644
index 0000000..c63d115
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/net/www/MessageHeader.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1995, 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.
+ */
+
+/*-
+ *      news stream opener
+ */
+
+package sun.net.www;
+
+import java.io.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class MessageHeader {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public MessageHeader() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public MessageHeader(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String getHeaderNamesInList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public synchronized java.lang.String findValue(java.lang.String k) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int getKey(java.lang.String k) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String getKey(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String getValue(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String findNextValue(java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean filterNTLMResponses(java.lang.String k) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<java.lang.String> multiValueIterator(java.lang.String k) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Map<java.lang.String, java.util.List<java.lang.String>>
+            getHeaders() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Map<java.lang.String, java.util.List<java.lang.String>>
+            getHeaders(java.lang.String[] excludeList) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Map<java.lang.String, java.util.List<java.lang.String>>
+            filterAndAddHeaders(
+                    java.lang.String[] excludeList,
+                    java.util.Map<java.lang.String, java.util.List<java.lang.String>> include) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public synchronized void print(java.io.PrintStream p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public synchronized void add(java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public synchronized void prepend(java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void set(int i, java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void grow() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void remove(java.lang.String k) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public synchronized void set(java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setIfNotSet(java.lang.String k, java.lang.String v) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String canonicalID(java.lang.String id) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void parseHeader(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void mergeHeader(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String[] keys;
+
+    private int nkeys;
+
+    private java.lang.String[] values;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    class HeaderIterator implements java.util.Iterator<java.lang.String> {
+
+        public HeaderIterator(java.lang.String k, java.lang.Object lock) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasNext() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String next() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove() {
+            throw new RuntimeException("Stub!");
+        }
+
+        boolean haveNext = false;
+
+        int index = 0; // 0x0
+
+        java.lang.String key;
+
+        java.lang.Object lock;
+
+        int next = -1; // 0xffffffff
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/net/www/ParseUtil.java b/ojluni/annotations/hiddenapi/sun/net/www/ParseUtil.java
new file mode 100644
index 0000000..d439a1f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/net/www/ParseUtil.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net.www;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ParseUtil {
+
+    public ParseUtil() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String encodePath(java.lang.String path) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.String encodePath(java.lang.String path, boolean flag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int escape(char[] cc, char c, int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static byte unescape(java.lang.String s, int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.String decode(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String canonizeString(java.lang.String file) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.net.URL fileToEncodedURL(java.io.File file)
+            throws java.net.MalformedURLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.net.URI toURI(java.net.URL url) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.net.URI createURI(
+            java.lang.String scheme,
+            java.lang.String authority,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String fragment)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String toString(
+            java.lang.String scheme,
+            java.lang.String opaquePart,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port,
+            java.lang.String path,
+            java.lang.String query,
+            java.lang.String fragment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendSchemeSpecificPart(
+            java.lang.StringBuffer sb,
+            java.lang.String opaquePart,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port,
+            java.lang.String path,
+            java.lang.String query) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendAuthority(
+            java.lang.StringBuffer sb,
+            java.lang.String authority,
+            java.lang.String userInfo,
+            java.lang.String host,
+            int port) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendFragment(java.lang.StringBuffer sb, java.lang.String fragment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String quote(java.lang.String s, long lowMask, long highMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isEscaped(java.lang.String s, int pos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendEncoded(java.lang.StringBuffer sb, char c) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void appendEscape(java.lang.StringBuffer sb, byte b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean match(char c, long lowMask, long highMask) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkPath(
+            java.lang.String s, java.lang.String scheme, java.lang.String path)
+            throws java.net.URISyntaxException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long lowMask(char first, char last) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long lowMask(java.lang.String chars) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long highMask(char first, char last) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static long highMask(java.lang.String chars) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long H_ALPHA;
+
+    static {
+        H_ALPHA = 0;
+    }
+
+    private static final long H_ALPHANUM;
+
+    static {
+        H_ALPHANUM = 0;
+    }
+
+    private static final long H_DASH;
+
+    static {
+        H_DASH = 0;
+    }
+
+    private static final long H_DIGIT = 0L; // 0x0L
+
+    private static final long H_ESCAPED = 0L; // 0x0L
+
+    private static final long H_HEX;
+
+    static {
+        H_HEX = 0;
+    }
+
+    private static final long H_LOWALPHA;
+
+    static {
+        H_LOWALPHA = 0;
+    }
+
+    private static final long H_MARK;
+
+    static {
+        H_MARK = 0;
+    }
+
+    private static final long H_PATH;
+
+    static {
+        H_PATH = 0;
+    }
+
+    private static final long H_PCHAR;
+
+    static {
+        H_PCHAR = 0;
+    }
+
+    private static final long H_REG_NAME;
+
+    static {
+        H_REG_NAME = 0;
+    }
+
+    private static final long H_RESERVED;
+
+    static {
+        H_RESERVED = 0;
+    }
+
+    private static final long H_SERVER;
+
+    static {
+        H_SERVER = 0;
+    }
+
+    private static final long H_UNRESERVED;
+
+    static {
+        H_UNRESERVED = 0;
+    }
+
+    private static final long H_UPALPHA;
+
+    static {
+        H_UPALPHA = 0;
+    }
+
+    private static final long H_URIC;
+
+    static {
+        H_URIC = 0;
+    }
+
+    private static final long H_USERINFO;
+
+    static {
+        H_USERINFO = 0;
+    }
+
+    private static final long L_ALPHA = 0L; // 0x0L
+
+    private static final long L_ALPHANUM;
+
+    static {
+        L_ALPHANUM = 0;
+    }
+
+    private static final long L_DASH;
+
+    static {
+        L_DASH = 0;
+    }
+
+    private static final long L_DIGIT;
+
+    static {
+        L_DIGIT = 0;
+    }
+
+    private static final long L_ESCAPED = 1L; // 0x1L
+
+    private static final long L_HEX;
+
+    static {
+        L_HEX = 0;
+    }
+
+    private static final long L_LOWALPHA = 0L; // 0x0L
+
+    private static final long L_MARK;
+
+    static {
+        L_MARK = 0;
+    }
+
+    private static final long L_PATH;
+
+    static {
+        L_PATH = 0;
+    }
+
+    private static final long L_PCHAR;
+
+    static {
+        L_PCHAR = 0;
+    }
+
+    private static final long L_REG_NAME;
+
+    static {
+        L_REG_NAME = 0;
+    }
+
+    private static final long L_RESERVED;
+
+    static {
+        L_RESERVED = 0;
+    }
+
+    private static final long L_SERVER;
+
+    static {
+        L_SERVER = 0;
+    }
+
+    private static final long L_UNRESERVED;
+
+    static {
+        L_UNRESERVED = 0;
+    }
+
+    private static final long L_UPALPHA = 0L; // 0x0L
+
+    private static final long L_URIC;
+
+    static {
+        L_URIC = 0;
+    }
+
+    private static final long L_USERINFO;
+
+    static {
+        L_USERINFO = 0;
+    }
+
+    static java.util.BitSet encodedInPath;
+
+    private static final char[] hexDigits;
+
+    static {
+        hexDigits = new char[0];
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java b/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java
new file mode 100644
index 0000000..7669272
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1995, 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 sun.net.www;
+
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class URLConnection extends java.net.URLConnection {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public URLConnection(java.net.URL u) {
+        super(null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.net.www.MessageHeader getProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void setProperties(sun.net.www.MessageHeader properties) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setRequestProperty(java.lang.String key, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void addRequestProperty(java.lang.String key, java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRequestProperty(java.lang.String key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Map<java.lang.String, java.util.List<java.lang.String>>
+            getRequestProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHeaderField(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHeaderFieldKey(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHeaderField(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getContentType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setContentType(java.lang.String type) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getContentLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setContentLength(int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean canCache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void close() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void setProxiedHost(java.lang.String host) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized boolean isProxiedHost(java.lang.String host) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int contentLength = -1; // 0xffffffff
+
+    private java.lang.String contentType;
+
+    protected sun.net.www.MessageHeader properties;
+
+    private static java.util.HashMap<java.lang.String, java.lang.Void> proxiedHosts;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/ch/DirectBuffer.java b/ojluni/annotations/hiddenapi/sun/nio/ch/DirectBuffer.java
new file mode 100644
index 0000000..e755c28
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/ch/DirectBuffer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2000, 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 sun.nio.ch;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface DirectBuffer {
+
+    @UnsupportedAppUsage
+    public long address();
+
+    public java.lang.Object attachment();
+
+    @UnsupportedAppUsage
+    public sun.misc.Cleaner cleaner();
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/ch/FileChannelImpl.java b/ojluni/annotations/hiddenapi/sun/nio/ch/FileChannelImpl.java
new file mode 100644
index 0000000..ca3f145
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/ch/FileChannelImpl.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.ch;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FileChannelImpl extends java.nio.channels.FileChannel {
+
+    private FileChannelImpl(
+            java.io.FileDescriptor fd,
+            java.lang.String path,
+            boolean readable,
+            boolean writable,
+            boolean append,
+            java.lang.Object parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.channels.FileChannel open(
+            java.io.FileDescriptor fd,
+            java.lang.String path,
+            boolean readable,
+            boolean writable,
+            java.lang.Object parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.channels.FileChannel open(
+            java.io.FileDescriptor fd,
+            java.lang.String path,
+            boolean readable,
+            boolean writable,
+            boolean append,
+            java.lang.Object parent) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void ensureOpen() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void implCloseChannel() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void finalize() throws java.lang.Throwable {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(java.nio.ByteBuffer dst) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long read(java.nio.ByteBuffer[] dsts, int offset, int length)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int write(java.nio.ByteBuffer src) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long write(java.nio.ByteBuffer[] srcs, int offset, int length)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long position() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileChannel position(long newPosition) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long size() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileChannel truncate(long newSize) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void force(boolean metaData) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferToDirectlyInternal(
+            long position,
+            int icount,
+            java.nio.channels.WritableByteChannel target,
+            java.io.FileDescriptor targetFD)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferToDirectly(
+            long position, int icount, java.nio.channels.WritableByteChannel target)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferToTrustedChannel(
+            long position, long count, java.nio.channels.WritableByteChannel target)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferToArbitraryChannel(
+            long position, int icount, java.nio.channels.WritableByteChannel target)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long transferTo(long position, long count, java.nio.channels.WritableByteChannel target)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferFromFileChannel(sun.nio.ch.FileChannelImpl src, long position, long count)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private long transferFromArbitraryChannel(
+            java.nio.channels.ReadableByteChannel src, long position, long count)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long transferFrom(java.nio.channels.ReadableByteChannel src, long position, long count)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int read(java.nio.ByteBuffer dst, long position) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int readInternal(java.nio.ByteBuffer dst, long position) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int write(java.nio.ByteBuffer src, long position) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int writeInternal(java.nio.ByteBuffer src, long position) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void unmap(java.nio.MappedByteBuffer bb) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.MappedByteBuffer map(
+            java.nio.channels.FileChannel.MapMode mode, long position, long size)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isSharedFileLockTable() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.nio.ch.FileLockTable fileLockTable() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileLock lock(long position, long size, boolean shared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.nio.channels.FileLock tryLock(long position, long size, boolean shared)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    void release(sun.nio.ch.FileLockImpl fli) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private native long map0(int prot, long position, long length) throws java.io.IOException;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static native int unmap0(long address, long length);
+
+    private native long transferTo0(
+            java.io.FileDescriptor src, long position, long count, java.io.FileDescriptor dst);
+
+    private native long position0(java.io.FileDescriptor fd, long offset);
+
+    private static native long initIDs();
+
+    private static final long MAPPED_TRANSFER_SIZE = 8388608L; // 0x800000L
+
+    private static final int MAP_PV = 2; // 0x2
+
+    private static final int MAP_RO = 0; // 0x0
+
+    private static final int MAP_RW = 1; // 0x1
+
+    private static final int TRANSFER_SIZE = 8192; // 0x2000
+
+    private static final long allocationGranularity;
+
+    static {
+        allocationGranularity = 0;
+    }
+
+    private final boolean append;
+
+    {
+        append = false;
+    }
+
+    public final java.io.FileDescriptor fd;
+
+    {
+        fd = null;
+    }
+
+    private volatile sun.nio.ch.FileLockTable fileLockTable;
+
+    private static volatile boolean fileSupported = true;
+
+    private final dalvik.system.CloseGuard guard;
+
+    {
+        guard = null;
+    }
+
+    private static boolean isSharedFileLockTable;
+
+    private final sun.nio.ch.FileDispatcher nd;
+
+    {
+        nd = null;
+    }
+
+    private final java.lang.Object parent;
+
+    {
+        parent = null;
+    }
+
+    private final java.lang.String path;
+
+    {
+        path = null;
+    }
+
+    private static volatile boolean pipeSupported = true;
+
+    private final java.lang.Object positionLock;
+
+    {
+        positionLock = null;
+    }
+
+    private static volatile boolean propertyChecked;
+
+    private final boolean readable;
+
+    {
+        readable = false;
+    }
+
+    private final sun.nio.ch.NativeThreadSet threads;
+
+    {
+        threads = null;
+    }
+
+    private static volatile boolean transferSupported = true;
+
+    private final boolean writable;
+
+    {
+        writable = false;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SimpleFileLockTable extends sun.nio.ch.FileLockTable {
+
+        public SimpleFileLockTable() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void checkList(long position, long size)
+                throws java.nio.channels.OverlappingFileLockException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void add(java.nio.channels.FileLock fl)
+                throws java.nio.channels.OverlappingFileLockException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void remove(java.nio.channels.FileLock fl) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<java.nio.channels.FileLock> removeAll() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void replace(java.nio.channels.FileLock fl1, java.nio.channels.FileLock fl2) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.util.List<java.nio.channels.FileLock> lockList;
+
+        {
+            lockList = null;
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class Unmapper implements java.lang.Runnable {
+
+        private Unmapper(long address, long size, int cap, java.io.FileDescriptor fd) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void run() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private volatile long address;
+
+        private final int cap;
+
+        {
+            cap = 0;
+        }
+
+        static volatile int count;
+
+        private final java.io.FileDescriptor fd;
+
+        {
+            fd = null;
+        }
+
+        private static final sun.nio.ch.NativeDispatcher nd;
+
+        static {
+            nd = null;
+        }
+
+        private final long size;
+
+        {
+            size = 0;
+        }
+
+        static volatile long totalCapacity;
+
+        static volatile long totalSize;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/ch/SelectorImpl.java b/ojluni/annotations/hiddenapi/sun/nio/ch/SelectorImpl.java
new file mode 100644
index 0000000..294cdee
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/ch/SelectorImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2000, 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 sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SelectorImpl extends java.nio.channels.spi.AbstractSelector {
+
+    protected SelectorImpl(java.nio.channels.spi.SelectorProvider sp) {
+        super(null);
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.nio.channels.SelectionKey> keys() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.nio.channels.SelectionKey> selectedKeys() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract int doSelect(long timeout) throws java.io.IOException;
+
+    private int lockAndDoSelect(long timeout) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int select(long timeout) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int select() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int selectNow() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void implCloseSelector() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void implClose() throws java.io.IOException;
+
+    public void putEventOps(sun.nio.ch.SelectionKeyImpl sk, int ops) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected final java.nio.channels.SelectionKey register(
+            java.nio.channels.spi.AbstractSelectableChannel ch,
+            int ops,
+            java.lang.Object attachment) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void implRegister(sun.nio.ch.SelectionKeyImpl ski);
+
+    void processDeregisterQueue() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract void implDereg(sun.nio.ch.SelectionKeyImpl ski) throws java.io.IOException;
+
+    public abstract java.nio.channels.Selector wakeup();
+
+    protected java.util.HashSet<java.nio.channels.SelectionKey> keys;
+
+    private java.util.Set<java.nio.channels.SelectionKey> publicKeys;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private java.util.Set<java.nio.channels.SelectionKey> publicSelectedKeys;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    protected java.util.Set<java.nio.channels.SelectionKey> selectedKeys;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/cs/HistoricallyNamedCharset.java b/ojluni/annotations/hiddenapi/sun/nio/cs/HistoricallyNamedCharset.java
new file mode 100644
index 0000000..ed066b4
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/cs/HistoricallyNamedCharset.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.cs;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface HistoricallyNamedCharset {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String historicalName();
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/cs/ThreadLocalCoders.java b/ojluni/annotations/hiddenapi/sun/nio/cs/ThreadLocalCoders.java
new file mode 100644
index 0000000..ef03631
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/cs/ThreadLocalCoders.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001, 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 sun.nio.cs;
+
+import java.nio.charset.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocalCoders {
+
+    public ThreadLocalCoders() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.nio.charset.CharsetDecoder decoderFor(java.lang.Object name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.nio.charset.CharsetEncoder encoderFor(java.lang.Object name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int CACHE_SIZE = 3; // 0x3
+
+    private static sun.nio.cs.ThreadLocalCoders.Cache decoderCache;
+
+    private static sun.nio.cs.ThreadLocalCoders.Cache encoderCache;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private abstract static class Cache {
+
+        Cache(int size) {
+            throw new RuntimeException("Stub!");
+        }
+
+        abstract java.lang.Object create(java.lang.Object name);
+
+        private void moveToFront(java.lang.Object[] oa, int i) {
+            throw new RuntimeException("Stub!");
+        }
+
+        abstract boolean hasName(java.lang.Object ob, java.lang.Object name);
+
+        java.lang.Object forName(java.lang.Object name) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.lang.ThreadLocal<java.lang.Object[]> cache;
+
+        private final int size;
+
+        {
+            size = 0;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java b/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java
new file mode 100644
index 0000000..78cf143
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface BasicFileAttributesHolder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.nio.file.attribute.BasicFileAttributes get();
+
+    public void invalidate();
+}
diff --git a/ojluni/annotations/hiddenapi/sun/reflect/Reflection.java b/ojluni/annotations/hiddenapi/sun/reflect/Reflection.java
new file mode 100644
index 0000000..ab0fb2a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/reflect/Reflection.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001, 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 sun.reflect;
+
+import java.lang.reflect.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Reflection {
+
+    public Reflection() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> getCallerClass() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static void ensureMemberAccess(
+            java.lang.Class<?> currentClass,
+            java.lang.Class<?> memberClass,
+            java.lang.Object target,
+            int modifiers)
+            throws java.lang.IllegalAccessException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean verifyMemberAccess(
+            java.lang.Class<?> currentClass,
+            java.lang.Class<?> memberClass,
+            java.lang.Object target,
+            int modifiers) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isSameClassPackage(java.lang.Class<?> c1, java.lang.Class<?> c2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isSameClassPackage(
+            java.lang.ClassLoader loader1,
+            java.lang.String name1,
+            java.lang.ClassLoader loader2,
+            java.lang.String name2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static boolean isSubclassOf(java.lang.Class<?> queryClass, java.lang.Class<?> ofClass) {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/reflect/misc/ReflectUtil.java b/ojluni/annotations/hiddenapi/sun/reflect/misc/ReflectUtil.java
new file mode 100644
index 0000000..3200def
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/reflect/misc/ReflectUtil.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 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 sun.reflect.misc;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class ReflectUtil {
+
+    private ReflectUtil() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> forName(java.lang.String name)
+            throws java.lang.ClassNotFoundException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Object newInstance(java.lang.Class<?> cls)
+            throws java.lang.IllegalAccessException, java.lang.InstantiationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void ensureMemberAccess(
+            java.lang.Class<?> currentClass,
+            java.lang.Class<?> memberClass,
+            java.lang.Object target,
+            int modifiers)
+            throws java.lang.IllegalAccessException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static boolean isSubclassOf(java.lang.Class<?> queryClass, java.lang.Class<?> ofClass) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static void checkPackageAccess(java.lang.Class<?> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static void checkPackageAccess(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static boolean isPackageAccessible(java.lang.Class<?> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isAncestor(java.lang.ClassLoader p, java.lang.ClassLoader cl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean needsPackageAccessCheck(
+            java.lang.ClassLoader from, java.lang.ClassLoader to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void checkProxyPackageAccess(java.lang.Class<?> clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void checkProxyPackageAccess(
+            java.lang.ClassLoader ccl, java.lang.Class<?>... interfaces) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isNonPublicProxyClass(java.lang.Class<?> cls) {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/action/GetBooleanAction.java b/ojluni/annotations/hiddenapi/sun/security/action/GetBooleanAction.java
new file mode 100644
index 0000000..36355d7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/action/GetBooleanAction.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.action;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GetBooleanAction implements java.security.PrivilegedAction<java.lang.Boolean> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GetBooleanAction(java.lang.String theProp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Boolean run() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String theProp;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/action/GetIntegerAction.java b/ojluni/annotations/hiddenapi/sun/security/action/GetIntegerAction.java
new file mode 100644
index 0000000..a0bc736
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/action/GetIntegerAction.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.action;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GetIntegerAction implements java.security.PrivilegedAction<java.lang.Integer> {
+
+    public GetIntegerAction(java.lang.String theProp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GetIntegerAction(java.lang.String theProp, int defaultVal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Integer run() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean defaultSet = false;
+
+    private int defaultVal;
+
+    private java.lang.String theProp;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/action/GetPropertyAction.java b/ojluni/annotations/hiddenapi/sun/security/action/GetPropertyAction.java
new file mode 100644
index 0000000..b83e1cd
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/action/GetPropertyAction.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.action;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GetPropertyAction implements java.security.PrivilegedAction<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GetPropertyAction(java.lang.String theProp) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GetPropertyAction(java.lang.String theProp, java.lang.String defaultVal) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String run() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String defaultVal;
+
+    private java.lang.String theProp;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java b/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java
new file mode 100644
index 0000000..e046dae
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java
@@ -0,0 +1,171 @@
+/*
+ * 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 sun.security.jca;
+
+import java.security.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GetInstance {
+
+    private GetInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Provider.Service getService(
+            java.lang.String type, java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Provider.Service getService(
+            java.lang.String type, java.lang.String algorithm, java.lang.String provider)
+            throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Provider.Service getService(
+            java.lang.String type, java.lang.String algorithm, java.security.Provider provider)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.security.Provider.Service> getServices(
+            java.lang.String type, java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public static java.util.List<java.security.Provider.Service> getServices(
+            java.lang.String type, java.util.List<java.lang.String> algorithms) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.security.Provider.Service> getServices(
+            java.util.List<sun.security.jca.ServiceId> ids) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type, java.lang.Class<?> clazz, java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type,
+            java.lang.Class<?> clazz,
+            java.lang.String algorithm,
+            java.lang.Object param)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type,
+            java.lang.Class<?> clazz,
+            java.lang.String algorithm,
+            java.lang.String provider)
+            throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type,
+            java.lang.Class<?> clazz,
+            java.lang.String algorithm,
+            java.lang.Object param,
+            java.lang.String provider)
+            throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type,
+            java.lang.Class<?> clazz,
+            java.lang.String algorithm,
+            java.security.Provider provider)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.lang.String type,
+            java.lang.Class<?> clazz,
+            java.lang.String algorithm,
+            java.lang.Object param,
+            java.security.Provider provider)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.security.Provider.Service s, java.lang.Class<?> clazz)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.GetInstance.Instance getInstance(
+            java.security.Provider.Service s, java.lang.Class<?> clazz, java.lang.Object param)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void checkSuperClass(
+            java.security.Provider.Service s,
+            java.lang.Class<?> subClass,
+            java.lang.Class<?> superClass)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static final class Instance {
+
+        private Instance(java.security.Provider provider, java.lang.Object impl) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.Object[] toArray() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage public final java.lang.Object impl;
+
+        {
+            impl = null;
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage public final java.security.Provider provider;
+
+        {
+            provider = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/JCAUtil.java b/ojluni/annotations/hiddenapi/sun/security/jca/JCAUtil.java
new file mode 100644
index 0000000..26d767f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/JCAUtil.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2003, 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 sun.security.jca;
+
+import java.lang.ref.*;
+import java.security.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class JCAUtil {
+
+    private JCAUtil() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int getTempArraySize(int totalSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.security.SecureRandom getSecureRandom() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int ARRAY_SIZE = 4096; // 0x1000
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class CachedSecureRandomHolder {
+
+        private CachedSecureRandomHolder() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public static java.security.SecureRandom instance;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java
new file mode 100644
index 0000000..60ed61e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.jca;
+
+import java.lang.reflect.*;
+import java.security.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+final class ProviderConfig {
+
+    ProviderConfig(java.lang.String className, java.lang.String argument) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ProviderConfig(java.lang.String className) {
+        throw new RuntimeException("Stub!");
+    }
+
+    ProviderConfig(java.security.Provider provider) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkSunPKCS11Solaris() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private boolean hasArgument() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean shouldLoad() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void disableLoad() {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isLoaded() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    synchronized java.security.Provider getProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.security.Provider doLoadProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.security.Provider initProvider(
+            java.lang.String className, java.lang.ClassLoader cl) throws java.lang.Exception {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String expand(java.lang.String value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private static final java.lang.Class[] CL_STRING;
+
+    static {
+        CL_STRING = new java.lang.Class[0];
+    }
+
+    private static final int MAX_LOAD_TRIES = 30; // 0x1e
+
+    private static final java.lang.String P11_SOL_ARG =
+            "${java.home}/lib/security/sunpkcs11-solaris.cfg";
+
+    private static final java.lang.String P11_SOL_NAME = "sun.security.pkcs11.SunPKCS11";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private final java.lang.String argument;
+
+    {
+        argument = null;
+    }
+
+    private final java.lang.String className;
+
+    {
+        className = null;
+    }
+
+    private static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private boolean isLoading;
+
+    private volatile java.security.Provider provider;
+
+    private int tries;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/ProviderList.java b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderList.java
new file mode 100644
index 0000000..7cd3d4e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderList.java
@@ -0,0 +1,233 @@
+/*
+ * 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 sun.security.jca;
+
+import java.security.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class ProviderList {
+
+    private ProviderList(sun.security.jca.ProviderConfig[] configs, boolean allLoaded) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private ProviderList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.security.jca.ProviderList fromSecurityProperties() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList add(
+            sun.security.jca.ProviderList providerList, java.security.Provider p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList insertAt(
+            sun.security.jca.ProviderList providerList, java.security.Provider p, int position) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList remove(
+            sun.security.jca.ProviderList providerList, java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList newList(java.security.Provider... providers) {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.jca.ProviderList getJarList(java.lang.String[] jarClassNames) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    java.security.Provider getProvider(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.security.Provider> providers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.jca.ProviderConfig getProviderConfig(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Provider getProvider(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getIndex(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int loadAll() {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.jca.ProviderList removeInvalid() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Provider[] toArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.security.Provider.Service getService(java.lang.String type, java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.security.Provider.Service> getServices(
+            java.lang.String type, java.lang.String algorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public java.util.List<java.security.Provider.Service> getServices(
+            java.lang.String type, java.util.List<java.lang.String> algorithms) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.security.Provider.Service> getServices(
+            java.util.List<sun.security.jca.ServiceId> ids) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final sun.security.jca.ProviderList EMPTY;
+
+    static {
+        EMPTY = null;
+    }
+
+    private static final java.security.Provider EMPTY_PROVIDER;
+
+    static {
+        EMPTY_PROVIDER = null;
+    }
+
+    private static final java.security.Provider[] P0;
+
+    static {
+        P0 = new java.security.Provider[0];
+    }
+
+    private static final sun.security.jca.ProviderConfig[] PC0;
+
+    static {
+        PC0 = new sun.security.jca.ProviderConfig[0];
+    }
+
+    private volatile boolean allLoaded;
+
+    private final sun.security.jca.ProviderConfig[] configs;
+
+    {
+        configs = new sun.security.jca.ProviderConfig[0];
+    }
+
+    static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private final java.util.List<java.security.Provider> userList;
+
+    {
+        userList = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private final class ServiceList extends java.util.AbstractList<java.security.Provider.Service> {
+
+        ServiceList(java.lang.String type, java.lang.String algorithm) {
+            throw new RuntimeException("Stub!");
+        }
+
+        ServiceList(java.util.List<sun.security.jca.ServiceId> ids) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void addService(java.security.Provider.Service s) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private java.security.Provider.Service tryGet(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.Provider.Service get(int index) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int size() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isEmpty() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Iterator<java.security.Provider.Service> iterator() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.lang.String algorithm;
+
+        {
+            algorithm = null;
+        }
+
+        private java.security.Provider.Service firstService;
+
+        private final java.util.List<sun.security.jca.ServiceId> ids;
+
+        {
+            ids = null;
+        }
+
+        private int providerIndex;
+
+        private java.util.List<java.security.Provider.Service> services;
+
+        private final java.lang.String type;
+
+        {
+            type = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java b/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java
new file mode 100644
index 0000000..da37d94
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java
@@ -0,0 +1,146 @@
+/*
+ * 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 sun.security.jca;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Providers {
+
+    private Providers() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.Provider getSunProvider() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.Object startJarVerification() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static void stopJarVerification(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.jca.ProviderList getProviderList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setProviderList(sun.security.jca.ProviderList newList) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList getFullProviderList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.security.jca.ProviderList getSystemProviderList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void setSystemProviderList(sun.security.jca.ProviderList list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.jca.ProviderList getThreadProviderList() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void changeThreadProviderList(sun.security.jca.ProviderList list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized sun.security.jca.ProviderList beginThreadProviderList(
+            sun.security.jca.ProviderList list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void endThreadProviderList(sun.security.jca.ProviderList list) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void setMaximumAllowableApiLevelForBcDeprecation(int targetApiLevel) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static int getMaximumAllowableApiLevelForBcDeprecation() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void checkBouncyCastleDeprecation(
+            java.lang.String provider, java.lang.String service, java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized void checkBouncyCastleDeprecation(
+            java.security.Provider provider, java.lang.String service, java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkBouncyCastleDeprecation(
+            java.lang.String service, java.lang.String algorithm)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String BACKUP_PROVIDER_CLASSNAME =
+            "sun.security.provider.VerificationProvider";
+
+    public static final int DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION =
+            27; // 0x1b
+
+    private static final java.util.Set<java.lang.String> DEPRECATED_ALGORITHMS;
+
+    static {
+        DEPRECATED_ALGORITHMS = null;
+    }
+
+    private static volatile java.security.Provider SYSTEM_BOUNCY_CASTLE_PROVIDER;
+
+    private static final java.lang.String[] jarVerificationProviders;
+
+    static {
+        jarVerificationProviders = new java.lang.String[0];
+    }
+
+    private static int maximumAllowableApiLevelForBcDeprecation = 27; // 0x1b
+
+    private static volatile sun.security.jca.ProviderList providerList;
+
+    private static final java.lang.ThreadLocal<sun.security.jca.ProviderList> threadLists;
+
+    static {
+        threadLists = null;
+    }
+
+    private static volatile int threadListsUsed;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/ContentInfo.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/ContentInfo.java
new file mode 100644
index 0000000..98a0a85
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/ContentInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1996, 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 sun.security.pkcs;
+
+import java.io.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ContentInfo {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ContentInfo(
+            sun.security.util.ObjectIdentifier contentType, sun.security.util.DerValue content) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ContentInfo(byte[] bytes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ContentInfo(sun.security.util.DerInputStream derin)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ContentInfo(sun.security.util.DerInputStream derin, boolean oldStyle)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.DerValue getContent() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.ObjectIdentifier getContentType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getData() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getContentBytes() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.util.ObjectIdentifier DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier DIGESTED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier ENCRYPTED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier ENVELOPED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID;
+
+    private static final int[] OLD_DATA;
+
+    static {
+        OLD_DATA = new int[0];
+    }
+
+    public static sun.security.util.ObjectIdentifier OLD_DATA_OID;
+
+    private static final int[] OLD_SDATA;
+
+    static {
+        OLD_SDATA = new int[0];
+    }
+
+    public static sun.security.util.ObjectIdentifier OLD_SIGNED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier PKCS7_OID;
+
+    public static sun.security.util.ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier SIGNED_DATA_OID;
+
+    public static sun.security.util.ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID;
+
+    sun.security.util.DerValue content;
+
+    sun.security.util.ObjectIdentifier contentType;
+
+    private static int[] crdata;
+
+    private static int[] data;
+
+    private static int[] ddata;
+
+    private static int[] edata;
+
+    private static int[] nsdata;
+
+    private static int[] pkcs7;
+
+    private static int[] sdata;
+
+    private static int[] sedata;
+
+    private static int[] tstInfo;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS7.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS7.java
new file mode 100644
index 0000000..0292827
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS7.java
@@ -0,0 +1,364 @@
+/*
+ * 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 sun.security.pkcs;
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import sun.security.timestamp.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKCS7 {
+
+    public PKCS7(java.io.InputStream in)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public PKCS7(sun.security.util.DerInputStream derin) throws sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS7(byte[] bytes) throws sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS7(
+            sun.security.x509.AlgorithmId[] digestAlgorithmIds,
+            sun.security.pkcs.ContentInfo contentInfo,
+            java.security.cert.X509Certificate[] certificates,
+            java.security.cert.X509CRL[] crls,
+            sun.security.pkcs.SignerInfo[] signerInfos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS7(
+            sun.security.x509.AlgorithmId[] digestAlgorithmIds,
+            sun.security.pkcs.ContentInfo contentInfo,
+            java.security.cert.X509Certificate[] certificates,
+            sun.security.pkcs.SignerInfo[] signerInfos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerInputStream derin)
+            throws sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerInputStream derin, boolean oldStyle)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseNetscapeCertChain(sun.security.util.DerValue val)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseSignedData(sun.security.util.DerValue val)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseOldSignedData(sun.security.util.DerValue val)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encodeSignedData(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encodeSignedData(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.pkcs.SignerInfo verify(sun.security.pkcs.SignerInfo info, byte[] bytes)
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.SignerInfo verify(
+            sun.security.pkcs.SignerInfo info, java.io.InputStream dataInputStream)
+            throws java.io.IOException, java.security.NoSuchAlgorithmException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.pkcs.SignerInfo[] verify(byte[] bytes)
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.SignerInfo[] verify()
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AlgorithmId[] getDigestAlgorithmIds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.pkcs.ContentInfo getContentInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.security.cert.X509Certificate[] getCertificates() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509CRL[] getCRLs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.pkcs.SignerInfo[] getSignerInfos() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509Certificate getCertificate(
+            java.math.BigInteger serial, sun.security.x509.X500Name issuerName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void populateCertIssuerNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isOldStyle() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.security.Principal[] certIssuerNames;
+
+    private java.security.cert.X509Certificate[] certificates;
+
+    private sun.security.pkcs.ContentInfo contentInfo;
+
+    private sun.security.util.ObjectIdentifier contentType;
+
+    private java.security.cert.X509CRL[] crls;
+
+    private sun.security.x509.AlgorithmId[] digestAlgorithmIds;
+
+    private boolean oldStyle = false;
+
+    private sun.security.pkcs.SignerInfo[] signerInfos;
+
+    private java.math.BigInteger version;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class VerbatimX509Certificate
+            extends sun.security.pkcs.PKCS7.WrappedX509Certificate {
+
+        public VerbatimX509Certificate(
+                java.security.cert.X509Certificate wrapped, byte[] encodedVerbatim) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getEncoded() throws java.security.cert.CertificateEncodingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private byte[] encodedVerbatim;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class WrappedX509Certificate extends java.security.cert.X509Certificate {
+
+        public WrappedX509Certificate(java.security.cert.X509Certificate wrapped) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.lang.String> getCriticalExtensionOIDs() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getExtensionValue(java.lang.String oid) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean hasUnsupportedCriticalExtension() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void checkValidity()
+                throws java.security.cert.CertificateExpiredException,
+                        java.security.cert.CertificateNotYetValidException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void checkValidity(java.util.Date date)
+                throws java.security.cert.CertificateExpiredException,
+                        java.security.cert.CertificateNotYetValidException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getVersion() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.math.BigInteger getSerialNumber() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.Principal getIssuerDN() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.Principal getSubjectDN() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Date getNotBefore() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Date getNotAfter() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getTBSCertificate() throws java.security.cert.CertificateEncodingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getSignature() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String getSigAlgName() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String getSigAlgOID() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getSigAlgParams() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean[] getIssuerUniqueID() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean[] getSubjectUniqueID() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean[] getKeyUsage() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int getBasicConstraints() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public byte[] getEncoded() throws java.security.cert.CertificateEncodingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void verify(java.security.PublicKey key)
+                throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                        java.security.NoSuchAlgorithmException,
+                        java.security.NoSuchProviderException, java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void verify(java.security.PublicKey key, java.lang.String sigProvider)
+                throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                        java.security.NoSuchAlgorithmException,
+                        java.security.NoSuchProviderException, java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.security.PublicKey getPublicKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.List<java.lang.String> getExtendedKeyUsage()
+                throws java.security.cert.CertificateParsingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<java.util.List<?>> getIssuerAlternativeNames()
+                throws java.security.cert.CertificateParsingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public javax.security.auth.x500.X500Principal getIssuerX500Principal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames()
+                throws java.security.cert.CertificateParsingException {
+            throw new RuntimeException("Stub!");
+        }
+
+        public javax.security.auth.x500.X500Principal getSubjectX500Principal() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void verify(java.security.PublicKey key, java.security.Provider sigProvider)
+                throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                        java.security.NoSuchAlgorithmException, java.security.SignatureException {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final java.security.cert.X509Certificate wrapped;
+
+        {
+            wrapped = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS8Key.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS8Key.java
new file mode 100644
index 0000000..fa84ed9
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS8Key.java
@@ -0,0 +1,131 @@
+/*
+ * 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 sun.security.pkcs;
+
+import java.io.*;
+import sun.security.util.*;
+import sun.security.x509.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKCS8Key implements java.security.PrivateKey {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS8Key() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private PKCS8Key(sun.security.x509.AlgorithmId algid, byte[] key)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.pkcs.PKCS8Key parse(sun.security.util.DerValue in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.PrivateKey parseKey(sun.security.util.DerValue in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void parseKeyBits() throws java.io.IOException, java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.security.PrivateKey buildPKCS8Key(sun.security.x509.AlgorithmId algid, byte[] key)
+            throws java.io.IOException, java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAlgorithm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AlgorithmId getAlgorithmId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized byte[] getEncoded() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getFormat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] encode() throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void decode(java.io.InputStream in) throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void decode(byte[] encodedKey) throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.Object writeReplace() throws java.io.ObjectStreamException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void encode(
+            sun.security.util.DerOutputStream out, sun.security.x509.AlgorithmId algid, byte[] key)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object object) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected sun.security.x509.AlgorithmId algid;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected byte[] encodedKey;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected byte[] key;
+
+    private static final long serialVersionUID = -3836890099307167124L; // 0xcac0a0c88c95426cL
+
+    public static final java.math.BigInteger version;
+
+    static {
+        version = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attribute.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attribute.java
new file mode 100644
index 0000000..40718c2
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attribute.java
@@ -0,0 +1,281 @@
+/*
+ * 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 sun.security.pkcs;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKCS9Attribute implements sun.security.util.DerEncoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attribute(sun.security.util.ObjectIdentifier oid, java.lang.Object value)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attribute(java.lang.String name, java.lang.Object value)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attribute(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(sun.security.util.ObjectIdentifier oid, java.lang.Object value)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isKnown() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Object getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSingleValued() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getOID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.util.ObjectIdentifier getOID(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getName(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int indexOf(java.lang.Object obj, java.lang.Object[] a, int start) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void throwSingleValuedException() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void throwTagException(java.lang.Byte tag) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.Class<?> BYTE_ARRAY_CLASS;
+
+    static {
+        BYTE_ARRAY_CLASS = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier CHALLENGE_PASSWORD_OID;
+
+    static {
+        CHALLENGE_PASSWORD_OID = null;
+    }
+
+    public static final java.lang.String CHALLENGE_PASSWORD_STR = "ChallengePassword";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier CONTENT_TYPE_OID;
+
+    static {
+        CONTENT_TYPE_OID = null;
+    }
+
+    public static final java.lang.String CONTENT_TYPE_STR = "ContentType";
+
+    public static final sun.security.util.ObjectIdentifier COUNTERSIGNATURE_OID;
+
+    static {
+        COUNTERSIGNATURE_OID = null;
+    }
+
+    public static final java.lang.String COUNTERSIGNATURE_STR = "Countersignature";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier EMAIL_ADDRESS_OID;
+
+    static {
+        EMAIL_ADDRESS_OID = null;
+    }
+
+    public static final java.lang.String EMAIL_ADDRESS_STR = "EmailAddress";
+
+    public static final sun.security.util.ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID;
+
+    static {
+        EXTENDED_CERTIFICATE_ATTRIBUTES_OID = null;
+    }
+
+    public static final java.lang.String EXTENDED_CERTIFICATE_ATTRIBUTES_STR =
+            "ExtendedCertificateAttributes";
+
+    public static final sun.security.util.ObjectIdentifier EXTENSION_REQUEST_OID;
+
+    static {
+        EXTENSION_REQUEST_OID = null;
+    }
+
+    public static final java.lang.String EXTENSION_REQUEST_STR = "ExtensionRequest";
+
+    public static final sun.security.util.ObjectIdentifier ISSUER_SERIALNUMBER_OID;
+
+    static {
+        ISSUER_SERIALNUMBER_OID = null;
+    }
+
+    public static final java.lang.String ISSUER_SERIALNUMBER_STR = "IssuerAndSerialNumber";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier MESSAGE_DIGEST_OID;
+
+    static {
+        MESSAGE_DIGEST_OID = null;
+    }
+
+    public static final java.lang.String MESSAGE_DIGEST_STR = "MessageDigest";
+
+    private static final java.util.Hashtable<java.lang.String, sun.security.util.ObjectIdentifier>
+            NAME_OID_TABLE;
+
+    static {
+        NAME_OID_TABLE = null;
+    }
+
+    private static final java.util.Hashtable<sun.security.util.ObjectIdentifier, java.lang.String>
+            OID_NAME_TABLE;
+
+    static {
+        OID_NAME_TABLE = null;
+    }
+
+    static final sun.security.util.ObjectIdentifier[] PKCS9_OIDS;
+
+    static {
+        PKCS9_OIDS = new sun.security.util.ObjectIdentifier[0];
+    }
+
+    private static final java.lang.Byte[][] PKCS9_VALUE_TAGS;
+
+    static {
+        PKCS9_VALUE_TAGS = new java.lang.Byte[0][];
+    }
+
+    private static final java.lang.String RSA_PROPRIETARY_STR = "RSAProprietary";
+
+    public static final sun.security.util.ObjectIdentifier SIGNATURE_TIMESTAMP_TOKEN_OID;
+
+    static {
+        SIGNATURE_TIMESTAMP_TOKEN_OID = null;
+    }
+
+    public static final java.lang.String SIGNATURE_TIMESTAMP_TOKEN_STR = "SignatureTimestampToken";
+
+    public static final sun.security.util.ObjectIdentifier SIGNING_CERTIFICATE_OID;
+
+    static {
+        SIGNING_CERTIFICATE_OID = null;
+    }
+
+    public static final java.lang.String SIGNING_CERTIFICATE_STR = "SigningCertificate";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SIGNING_TIME_OID;
+
+    static {
+        SIGNING_TIME_OID = null;
+    }
+
+    public static final java.lang.String SIGNING_TIME_STR = "SigningTime";
+
+    private static final boolean[] SINGLE_VALUED;
+
+    static {
+        SINGLE_VALUED = new boolean[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier SMIME_CAPABILITY_OID;
+
+    static {
+        SMIME_CAPABILITY_OID = null;
+    }
+
+    public static final java.lang.String SMIME_CAPABILITY_STR = "SMIMECapability";
+
+    private static final java.lang.String SMIME_SIGNING_DESC_STR = "SMIMESigningDesc";
+
+    public static final sun.security.util.ObjectIdentifier UNSTRUCTURED_ADDRESS_OID;
+
+    static {
+        UNSTRUCTURED_ADDRESS_OID = null;
+    }
+
+    public static final java.lang.String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress";
+
+    public static final sun.security.util.ObjectIdentifier UNSTRUCTURED_NAME_OID;
+
+    static {
+        UNSTRUCTURED_NAME_OID = null;
+    }
+
+    public static final java.lang.String UNSTRUCTURED_NAME_STR = "UnstructuredName";
+
+    private static final java.lang.Class<?>[] VALUE_CLASSES;
+
+    static {
+        VALUE_CLASSES = new java.lang.Class[0];
+    }
+
+    private static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private int index;
+
+    private sun.security.util.ObjectIdentifier oid;
+
+    private java.lang.Object value;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java
new file mode 100644
index 0000000..ac9faba
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.pkcs;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKCS9Attributes {
+
+    public PKCS9Attributes(
+            sun.security.util.ObjectIdentifier[] permittedAttributes,
+            sun.security.util.DerInputStream in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attributes(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attributes(sun.security.util.DerInputStream in, boolean ignoreUnsupportedAttributes)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public PKCS9Attributes(sun.security.pkcs.PKCS9Attribute[] attribs)
+            throws java.io.IOException, java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] decode(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(byte tag, java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] generateDerEncoding() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getDerEncoding() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.PKCS9Attribute getAttribute(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.pkcs.PKCS9Attribute getAttribute(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.PKCS9Attribute[] getAttributes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Object getAttributeValue(sun.security.util.ObjectIdentifier oid)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object getAttributeValue(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.security.util.DerEncoder[] castToDerEncoder(java.lang.Object[] objs) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.util.Hashtable<
+                    sun.security.util.ObjectIdentifier, sun.security.pkcs.PKCS9Attribute>
+            attributes;
+
+    {
+        attributes = null;
+    }
+
+    private final byte[] derEncoding;
+
+    {
+        derEncoding = new byte[0];
+    }
+
+    private boolean ignoreUnsupportedAttributes = false;
+
+    private final java.util.Hashtable<
+                    sun.security.util.ObjectIdentifier, sun.security.util.ObjectIdentifier>
+            permittedAttributes;
+
+    {
+        permittedAttributes = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/ParsingException.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/ParsingException.java
new file mode 100644
index 0000000..7b10115
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/ParsingException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1996, 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.
+ */
+
+/**
+ * Generic PKCS Parsing exception.
+ *
+ * @author Benjamin Renaud
+ */
+package sun.security.pkcs;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ParsingException extends java.io.IOException {
+
+    public ParsingException() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ParsingException(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long serialVersionUID = -6316569918966181883L; // 0xa8570920151a5005L
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java
new file mode 100644
index 0000000..03ebf6f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.pkcs;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SignerInfo implements sun.security.util.DerEncoder {
+
+    public SignerInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public SignerInfo(
+            sun.security.x509.X500Name issuerName,
+            java.math.BigInteger serial,
+            sun.security.x509.AlgorithmId digestAlgorithmId,
+            sun.security.x509.AlgorithmId digestEncryptionAlgorithmId,
+            byte[] encryptedDigest) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public SignerInfo(
+            sun.security.x509.X500Name issuerName,
+            java.math.BigInteger serial,
+            sun.security.x509.AlgorithmId digestAlgorithmId,
+            sun.security.pkcs.PKCS9Attributes authenticatedAttributes,
+            sun.security.x509.AlgorithmId digestEncryptionAlgorithmId,
+            byte[] encryptedDigest,
+            sun.security.pkcs.PKCS9Attributes unauthenticatedAttributes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SignerInfo(sun.security.util.DerInputStream derin)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SignerInfo(sun.security.util.DerInputStream derin, boolean oldStyle)
+            throws java.io.IOException, sun.security.pkcs.ParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.security.cert.X509Certificate getCertificate(sun.security.pkcs.PKCS7 block)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.util.ArrayList<java.security.cert.X509Certificate> getCertificateChain(
+            sun.security.pkcs.PKCS7 block) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.pkcs.SignerInfo verify(sun.security.pkcs.PKCS7 block, byte[] data)
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.pkcs.SignerInfo verify(
+            sun.security.pkcs.PKCS7 block, java.io.InputStream inputStream)
+            throws java.io.IOException, java.security.NoSuchAlgorithmException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.pkcs.SignerInfo verify(sun.security.pkcs.PKCS7 block)
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.X500Name getIssuerName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getCertificateSerialNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.AlgorithmId getDigestAlgorithmId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.PKCS9Attributes getAuthenticatedAttributes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.AlgorithmId getDigestEncryptionAlgorithmId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getEncryptedDigest() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.PKCS9Attributes getUnauthenticatedAttributes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.pkcs.PKCS7 getTsToken() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Timestamp getTimestamp()
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void verifyTimestamp(sun.security.timestamp.TimestampToken token)
+            throws java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.util.Set<java.security.CryptoPrimitive> DIGEST_PRIMITIVE_SET;
+
+    static {
+        DIGEST_PRIMITIVE_SET = null;
+    }
+
+    private static final sun.security.util.DisabledAlgorithmConstraints JAR_DISABLED_CHECK;
+
+    static {
+        JAR_DISABLED_CHECK = null;
+    }
+
+    private static final java.util.Set<java.security.CryptoPrimitive> SIG_PRIMITIVE_SET;
+
+    static {
+        SIG_PRIMITIVE_SET = null;
+    }
+
+    sun.security.pkcs.PKCS9Attributes authenticatedAttributes;
+
+    java.math.BigInteger certificateSerialNumber;
+
+    sun.security.x509.AlgorithmId digestAlgorithmId;
+
+    sun.security.x509.AlgorithmId digestEncryptionAlgorithmId;
+
+    byte[] encryptedDigest;
+
+    private boolean hasTimestamp = true;
+
+    sun.security.x509.X500Name issuerName;
+
+    java.security.Timestamp timestamp;
+
+    sun.security.pkcs.PKCS9Attributes unauthenticatedAttributes;
+
+    java.math.BigInteger version;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/provider/X509Factory.java b/ojluni/annotations/hiddenapi/sun/security/provider/X509Factory.java
new file mode 100644
index 0000000..499dddc
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/provider/X509Factory.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1998, 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 sun.security.provider;
+
+import java.security.cert.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509Factory {
+
+    public X509Factory() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static synchronized sun.security.x509.X509CertImpl intern(
+            java.security.cert.X509Certificate c) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static synchronized sun.security.x509.X509CRLImpl intern(java.security.cert.X509CRL c)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static synchronized <K, V> V getFromCache(
+            sun.security.util.Cache<K, V> cache, byte[] encoding) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static synchronized <V> void addToCache(
+            sun.security.util.Cache<java.lang.Object, V> cache, byte[] encoding, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int ENC_MAX_LENGTH = 4194304; // 0x400000
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static final sun.security.util.Cache<java.lang.Object, sun.security.x509.X509CertImpl>
+            certCache;
+
+    static {
+        certCache = null;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static final sun.security.util.Cache<java.lang.Object, sun.security.x509.X509CRLImpl>
+            crlCache;
+
+    static {
+        crlCache = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertPath.java b/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertPath.java
new file mode 100644
index 0000000..f3d432a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertPath.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2000, 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 sun.security.provider.certpath;
+
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CertPath extends java.security.cert.CertPath {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertPath(java.util.List<? extends java.security.cert.Certificate> certs)
+            throws java.security.cert.CertificateException {
+        super(null);
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertPath(java.io.InputStream is) throws java.security.cert.CertificateException {
+        super(null);
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertPath(java.io.InputStream is, java.lang.String encoding)
+            throws java.security.cert.CertificateException {
+        super(null);
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.security.cert.X509Certificate> parsePKIPATH(
+            java.io.InputStream is) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.List<java.security.cert.X509Certificate> parsePKCS7(
+            java.io.InputStream is) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static byte[] readAllBytes(java.io.InputStream is) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] encodePKIPATH() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] encodePKCS7() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded(java.lang.String encoding)
+            throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.util.Iterator<java.lang.String> getEncodingsStatic() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<java.lang.String> getEncodings() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<java.security.cert.X509Certificate> getCertificates() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String COUNT_ENCODING = "count";
+
+    private static final java.lang.String PKCS7_ENCODING = "PKCS7";
+
+    private static final java.lang.String PKIPATH_ENCODING = "PkiPath";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private java.util.List<java.security.cert.X509Certificate> certs;
+
+    private static final java.util.Collection<java.lang.String> encodingList;
+
+    static {
+        encodingList = null;
+    }
+
+    private static final long serialVersionUID = 4989800333263052980L; // 0x453f54f74c4520b4L
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertificatePair.java b/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertificatePair.java
new file mode 100644
index 0000000..3d5b410
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/provider/certpath/X509CertificatePair.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2000, 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 sun.security.provider.certpath;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CertificatePair {
+
+    public X509CertificatePair() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CertificatePair(
+            java.security.cert.X509Certificate forward, java.security.cert.X509Certificate reverse)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private X509CertificatePair(byte[] encoded) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static synchronized void clearCache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static synchronized sun.security.provider.certpath.X509CertificatePair
+            generateCertificatePair(byte[] encoded) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setForward(java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setReverse(java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509Certificate getForward() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509Certificate getReverse() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerValue val)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void emit(sun.security.util.DerOutputStream out)
+            throws java.security.cert.CertificateEncodingException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkPair() throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final byte TAG_FORWARD = 0; // 0x0
+
+    private static final byte TAG_REVERSE = 1; // 0x1
+
+    private static final sun.security.util.Cache<
+                    java.lang.Object, sun.security.provider.certpath.X509CertificatePair>
+            cache;
+
+    static {
+        cache = null;
+    }
+
+    private byte[] encoded;
+
+    private java.security.cert.X509Certificate forward;
+
+    private java.security.cert.X509Certificate reverse;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java b/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java
new file mode 100644
index 0000000..241935e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java
@@ -0,0 +1,81 @@
+/*
+ * 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 sun.security.timestamp;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class TimestampToken {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public TimestampToken(byte[] timestampTokenInfo) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.util.Date getDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.AlgorithmId getHashAlgorithm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getHashedMessage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.math.BigInteger getNonce() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPolicyID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getSerialNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(byte[] timestampTokenInfo) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Date genTime;
+
+    private sun.security.x509.AlgorithmId hashAlgorithm;
+
+    private byte[] hashedMessage;
+
+    private java.math.BigInteger nonce;
+
+    private sun.security.util.ObjectIdentifier policy;
+
+    private java.math.BigInteger serialNumber;
+
+    private int version;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/BitArray.java b/ojluni/annotations/hiddenapi/sun/security/util/BitArray.java
new file mode 100644
index 0000000..2eb98fe
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/BitArray.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class BitArray {
+
+    public BitArray(int length) throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public BitArray(int length, byte[] a) throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public BitArray(boolean[] bits) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private BitArray(sun.security.util.BitArray ba) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int subscript(int idx) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int position(int idx) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean get(int index) throws java.lang.ArrayIndexOutOfBoundsException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(int index, boolean value) throws java.lang.ArrayIndexOutOfBoundsException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int length() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] toByteArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] toBooleanArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.BitArray truncate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int BITS_PER_UNIT = 8; // 0x8
+
+    private static final int BYTES_PER_LINE = 8; // 0x8
+
+    private static final byte[][] NYBBLE;
+
+    static {
+        NYBBLE = new byte[0][];
+    }
+
+    private int length;
+
+    private byte[] repn;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/Cache.java b/ojluni/annotations/hiddenapi/sun/security/util/Cache.java
new file mode 100644
index 0000000..f5077e1
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/Cache.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2002, 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 sun.security.util;
+
+import java.lang.ref.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Cache<K, V> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    protected Cache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract int size();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract void clear();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract void put(K key, V value);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract V get(java.lang.Object key);
+
+    public abstract void remove(java.lang.Object key);
+
+    public abstract void setCapacity(int size);
+
+    public abstract void setTimeout(int timeout);
+
+    public abstract void accept(sun.security.util.Cache.CacheVisitor<K, V> visitor);
+
+    public static <K, V> sun.security.util.Cache<K, V> newSoftMemoryCache(int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> sun.security.util.Cache<K, V> newSoftMemoryCache(int size, int timeout) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static <K, V> sun.security.util.Cache<K, V> newHardMemoryCache(int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> sun.security.util.Cache<K, V> newNullCache() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static <K, V> sun.security.util.Cache<K, V> newHardMemoryCache(int size, int timeout) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static interface CacheVisitor<K, V> {
+
+        public void visit(java.util.Map<K, V> map);
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class EqualByteArray {
+
+        public EqualByteArray(byte[] b) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object obj) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private final byte[] b;
+
+        {
+            b = new byte[0];
+        }
+
+        private volatile int hash;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/Debug.java b/ojluni/annotations/hiddenapi/sun/security/util/Debug.java
new file mode 100644
index 0000000..e511d0d
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/Debug.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1998, 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 sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Debug {
+
+    public Debug() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.util.Debug getInstance(java.lang.String option) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.util.Debug getInstance(
+            java.lang.String option, java.lang.String prefix) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isOn(java.lang.String option) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void println(java.lang.String message) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void println() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.String toHexString(java.math.BigInteger b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String marshal(java.lang.String args) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String toString(byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String args;
+
+    private static final char[] hexDigits;
+
+    static {
+        hexDigits = new char[0];
+    }
+
+    private java.lang.String prefix;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerIndefLenConverter.java b/ojluni/annotations/hiddenapi/sun/security/util/DerIndefLenConverter.java
new file mode 100644
index 0000000..af6e282
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerIndefLenConverter.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1998, 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 sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class DerIndefLenConverter {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    DerIndefLenConverter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isEOC(int tag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isLongForm(int lengthByte) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static boolean isIndefinite(int lengthByte) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void parseTag() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void writeTag() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private int parseLength() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void writeLengthAndValue() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeLength(int curLen) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] getLengthBytes(int curLen) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getNumOfLenBytes(int len) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void parseValue(int curLen) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeValue(int curLen) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    byte[] convert(byte[] indefData) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int CLASS_MASK = 192; // 0xc0
+
+    private static final int FORM_MASK = 32; // 0x20
+
+    private static final int LEN_LONG = 128; // 0x80
+
+    private static final int LEN_MASK = 127; // 0x7f
+
+    private static final int SKIP_EOC_BYTES = 2; // 0x2
+
+    private static final int TAG_MASK = 31; // 0x1f
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private byte[] data;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int dataPos;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int dataSize;
+
+    private int index;
+
+    private java.util.ArrayList<java.lang.Object> ndefsList;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private byte[] newData;
+
+    private int newDataPos;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private int numOfTotalLenBytes = 0; // 0x0
+
+    private int unresolved = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java b/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java
new file mode 100644
index 0000000..a8348e3
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DerInputStream {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerInputStream(byte[] data) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DerInputStream(byte[] data, int offset, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DerInputStream(byte[] data, int offset, int len, boolean allowIndefiniteLength)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    DerInputStream(sun.security.util.DerInputBuffer buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(byte[] data, int offset, int len, boolean allowIndefiniteLength)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerInputStream subStream(int len, boolean do_skip)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] toByteArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int getInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.math.BigInteger getBigInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getPositiveBigInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getEnumerated() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getBitString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.BitArray getUnalignedBitString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getOctetString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void getBytes(byte[] val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void getNull() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getOID() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.DerValue[] getSequence(
+            int startLen, boolean originalEncodedFormRetained) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerValue[] getSequence(int startLen) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerValue[] getSet(int startLen) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerValue[] getSet(int startLen, boolean implicit)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.DerValue[] getSet(
+            int startLen, boolean implicit, boolean originalEncodedFormRetained)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected sun.security.util.DerValue[] readVector(int startLen) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected sun.security.util.DerValue[] readVector(
+            int startLen, boolean originalEncodedFormRetained) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerValue getDerValue() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getUTF8String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPrintableString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getT61String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getIA5String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getBMPString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getGeneralString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String readString(
+            byte stringTag, java.lang.String stringName, java.lang.String enc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.util.Date getUTCTime() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getGeneralizedTime() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int peekByte() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    int getLength() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int getLength(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int getLength(int lenByte, java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void mark(int value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void reset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int available() {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.util.DerInputBuffer buffer;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage public byte tag;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java b/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java
new file mode 100644
index 0000000..77e5e05
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1996, 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.
+ */
+
+package sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DerOutputStream extends java.io.ByteArrayOutputStream
+        implements sun.security.util.DerEncoder {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerOutputStream(int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerOutputStream() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void write(byte tag, byte[] buf) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void write(byte tag, sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void writeImplicit(byte tag, sun.security.util.DerOutputStream value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putDerValue(sun.security.util.DerValue val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putBoolean(boolean val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putEnumerated(int i) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putInteger(java.math.BigInteger i) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putInteger(java.lang.Integer i) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putInteger(int i) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void putIntegerContents(int i) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putBitString(byte[] bits) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putUnalignedBitString(sun.security.util.BitArray ba) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putTruncatedUnalignedBitString(sun.security.util.BitArray ba)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putOctetString(byte[] octets) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putNull() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putOID(sun.security.util.ObjectIdentifier oid) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putSequence(sun.security.util.DerValue[] seq) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putSet(sun.security.util.DerValue[] set) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putOrderedSetOf(byte tag, sun.security.util.DerEncoder[] set)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putOrderedSet(byte tag, sun.security.util.DerEncoder[] set)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void putOrderedSet(
+            byte tag, sun.security.util.DerEncoder[] set, java.util.Comparator<byte[]> order)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putUTF8String(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putPrintableString(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putT61String(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putIA5String(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putBMPString(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putGeneralString(java.lang.String s) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeString(java.lang.String s, byte stringTag, java.lang.String enc)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void putUTCTime(java.util.Date d) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putGeneralizedTime(java.util.Date d) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void putTime(java.util.Date d, byte tag) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putLength(int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void putTag(byte tagClass, boolean form, byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.security.util.ByteArrayLexOrder lexOrder;
+
+    private static sun.security.util.ByteArrayTagOrder tagOrder;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java b/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java
new file mode 100644
index 0000000..d034f44
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DerValue {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerValue(java.lang.String value) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public DerValue(byte stringTag, java.lang.String value) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerValue(byte tag, byte[] data) {
+        throw new RuntimeException("Stub!");
+    }
+
+    DerValue(sun.security.util.DerInputBuffer in, boolean originalEncodedFormRetained)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerValue(byte[] buf) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerValue(byte[] buf, int offset, int len) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public DerValue(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isUniversal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isApplication() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean isContextSpecific() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean isContextSpecific(byte cntxtTag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isPrivate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean isConstructed() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isConstructed(byte constructedTag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.DerInputStream init(byte stringTag, java.lang.String value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.DerInputStream init(boolean fullyBuffered, java.io.InputStream in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public final sun.security.util.DerInputStream getData() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final byte getTag() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean getBoolean() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getOID() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] append(byte[] a, byte[] b) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getOctetString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.math.BigInteger getBigInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.math.BigInteger getPositiveBigInteger() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getEnumerated() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getBitString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.BitArray getUnalignedBitString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getAsString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getBitString(boolean tagImplicit) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.BitArray getUnalignedBitString(boolean tagImplicit)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getDataBytes() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getPrintableString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getT61String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getIA5String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getBMPString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getUTF8String() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getGeneralString() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getUTCTime() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getGeneralizedTime() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(sun.security.util.DerValue other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean doEquals(sun.security.util.DerValue d1, sun.security.util.DerValue d2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getOriginalEncodedForm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] toByteArray() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.DerInputStream toDerInputStream() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int length() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static boolean isPrintableStringChar(char ch) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static byte createTag(byte tagClass, boolean form, byte val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void resetTag(byte tag) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final byte TAG_APPLICATION = 64; // 0x40
+
+    public static final byte TAG_CONTEXT = -128; // 0xffffff80
+
+    public static final byte TAG_PRIVATE = -64; // 0xffffffc0
+
+    public static final byte TAG_UNIVERSAL = 0; // 0x0
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected sun.security.util.DerInputBuffer buffer;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public final sun.security.util.DerInputStream data;
+
+    {
+        data = null;
+    }
+
+    private int length;
+
+    private byte[] originalEncodedForm;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage public byte tag;
+
+    public static final byte tag_BMPString = 30; // 0x1e
+
+    public static final byte tag_BitString = 3; // 0x3
+
+    public static final byte tag_Boolean = 1; // 0x1
+
+    public static final byte tag_Enumerated = 10; // 0xa
+
+    public static final byte tag_GeneralString = 27; // 0x1b
+
+    public static final byte tag_GeneralizedTime = 24; // 0x18
+
+    public static final byte tag_IA5String = 22; // 0x16
+
+    public static final byte tag_Integer = 2; // 0x2
+
+    public static final byte tag_Null = 5; // 0x5
+
+    public static final byte tag_ObjectId = 6; // 0x6
+
+    public static final byte tag_OctetString = 4; // 0x4
+
+    public static final byte tag_PrintableString = 19; // 0x13
+
+    public static final byte tag_Sequence = 48; // 0x30
+
+    public static final byte tag_SequenceOf = 48; // 0x30
+
+    public static final byte tag_Set = 49; // 0x31
+
+    public static final byte tag_SetOf = 49; // 0x31
+
+    public static final byte tag_T61String = 20; // 0x14
+
+    public static final byte tag_UTF8String = 12; // 0xc
+
+    public static final byte tag_UniversalString = 28; // 0x1c
+
+    public static final byte tag_UtcTime = 23; // 0x17
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java b/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java
new file mode 100644
index 0000000..ff473fb
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.util;
+
+import java.security.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ManifestDigester {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ManifestDigester(byte[] bytes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean findSection(int offset, sun.security.util.ManifestDigester.Position pos) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isNameAttr(byte[] bytes, int start) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ManifestDigester.Entry get(java.lang.String name, boolean oldStyle) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] manifestDigest(java.security.MessageDigest md) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String MF_MAIN_ATTRS = "Manifest-Main-Attributes";
+
+    private java.util.HashMap<java.lang.String, sun.security.util.ManifestDigester.Entry> entries;
+
+    private byte[] rawBytes;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Entry {
+
+        public Entry(int offset, int length, int lengthWithBlankLine, byte[] rawBytes) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public byte[] digest(java.security.MessageDigest md) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private void doOldStyle(
+                java.security.MessageDigest md, byte[] bytes, int offset, int length) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public byte[] digestWorkaround(java.security.MessageDigest md) {
+            throw new RuntimeException("Stub!");
+        }
+
+        int length;
+
+        int lengthWithBlankLine;
+
+        int offset;
+
+        boolean oldStyle;
+
+        byte[] rawBytes;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class Position {
+
+        Position() {
+            throw new RuntimeException("Stub!");
+        }
+
+        int endOfFirstLine;
+
+        int endOfSection;
+
+        int startOfNext;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/MemoryCache.java b/ojluni/annotations/hiddenapi/sun/security/util/MemoryCache.java
new file mode 100644
index 0000000..0bea0a2
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/MemoryCache.java
@@ -0,0 +1,175 @@
+/*
+ * 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 sun.security.util;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class MemoryCache<K, V> extends sun.security.util.Cache<K, V> {
+
+    public MemoryCache(boolean soft, int maxSize) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public MemoryCache(boolean soft, int maxSize, int lifetime) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void emptyQueue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void expungeExpiredEntries() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void clear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void put(K key, V value) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized V get(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void remove(java.lang.Object key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setCapacity(int size) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void setTimeout(int timeout) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void accept(sun.security.util.Cache.CacheVisitor<K, V> visitor) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Map<K, V> getCachedEntries() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected sun.security.util.MemoryCache.CacheEntry<K, V> newEntry(
+            K key, V value, long expirationTime, java.lang.ref.ReferenceQueue<V> queue) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final boolean DEBUG = false;
+
+    private static final float LOAD_FACTOR = 0.75f;
+
+    private final java.util.Map<K, sun.security.util.MemoryCache.CacheEntry<K, V>> cacheMap;
+
+    {
+        cacheMap = null;
+    }
+
+    private long lifetime;
+
+    private int maxSize;
+
+    private final java.lang.ref.ReferenceQueue<V> queue;
+
+    {
+        queue = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static interface CacheEntry<K, V> {
+
+        public boolean isValid(long currentTime);
+
+        public void invalidate();
+
+        public K getKey();
+
+        public V getValue();
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class HardCacheEntry<K, V>
+            implements sun.security.util.MemoryCache.CacheEntry<K, V> {
+
+        @UnsupportedAppUsage
+        HardCacheEntry(K key, V value, long expirationTime) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public K getKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isValid(long currentTime) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void invalidate() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private long expirationTime;
+
+        private K key;
+
+        private V value;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class SoftCacheEntry<K, V> extends java.lang.ref.SoftReference<V>
+            implements sun.security.util.MemoryCache.CacheEntry<K, V> {
+
+        @UnsupportedAppUsage
+        SoftCacheEntry(K key, V value, long expirationTime, java.lang.ref.ReferenceQueue<V> queue) {
+            super(null);
+            throw new RuntimeException("Stub!");
+        }
+
+        public K getKey() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public V getValue() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean isValid(long currentTime) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public void invalidate() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private long expirationTime;
+
+        private K key;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/ObjectIdentifier.java b/ojluni/annotations/hiddenapi/sun/security/util/ObjectIdentifier.java
new file mode 100644
index 0000000..1c17bed
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/ObjectIdentifier.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class ObjectIdentifier implements java.io.Serializable {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ObjectIdentifier(java.lang.String oid) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public ObjectIdentifier(int[] values) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public ObjectIdentifier(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    ObjectIdentifier(sun.security.util.DerInputBuffer buf) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream is)
+            throws java.lang.ClassNotFoundException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream os) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(int[] components, int length) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.util.ObjectIdentifier newInternal(int[] values) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean equals(sun.security.util.ObjectIdentifier other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int[] toIntArray() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static byte[] pack(byte[] in, int ioffset, int ilength, int iw, int ow) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int pack7Oid(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int pack8(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int pack7Oid(int input, byte[] out, int ooffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int pack7Oid(java.math.BigInteger input, byte[] out, int ooffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void check(byte[] encoding) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkCount(int count) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkFirstComponent(int first) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkFirstComponent(java.math.BigInteger first) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkSecondComponent(int first, int second) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkSecondComponent(int first, java.math.BigInteger second)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkOtherComponent(int i, int num) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void checkOtherComponent(int i, java.math.BigInteger num)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int componentLen = -1; // 0xffffffff
+
+    private java.lang.Object components;
+
+    private transient boolean componentsCalculated = false;
+
+    private byte[] encoding;
+
+    private static final long serialVersionUID = 8697030238860181294L; // 0x78b20eec64177f2eL
+
+    private transient volatile java.lang.String stringForm;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    static class HugeOidNotSupportedByOldJDK implements java.io.Serializable {
+
+        HugeOidNotSupportedByOldJDK() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = 1L; // 0x1L
+
+        static sun.security.util.ObjectIdentifier.HugeOidNotSupportedByOldJDK theOne;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java b/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java
new file mode 100644
index 0000000..f763de7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PropertyExpander {
+
+    public PropertyExpander() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.String expand(java.lang.String value)
+            throws sun.security.util.PropertyExpander.ExpandException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String expand(java.lang.String value, boolean encodeURL)
+            throws sun.security.util.PropertyExpander.ExpandException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class ExpandException extends java.security.GeneralSecurityException {
+
+        public ExpandException(java.lang.String msg) {
+            throw new RuntimeException("Stub!");
+        }
+
+        private static final long serialVersionUID = -7941948581406161702L; // 0x91c887d7ecde44daL
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java b/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java
new file mode 100644
index 0000000..eef01dc
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ResourcesMgr {
+
+    public ResourcesMgr() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.String getString(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getString(java.lang.String s, java.lang.String altBundleName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.ResourceBundle altBundle;
+
+    private static java.util.ResourceBundle bundle;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/SecurityConstants.java b/ojluni/annotations/hiddenapi/sun/security/util/SecurityConstants.java
new file mode 100644
index 0000000..33d67c6
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/SecurityConstants.java
@@ -0,0 +1,185 @@
+/*
+ * 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 sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class SecurityConstants {
+
+    private SecurityConstants() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.security.AllPermission ALL_PERMISSION;
+
+    static {
+        ALL_PERMISSION = null;
+    }
+
+    public static final java.lang.RuntimePermission CHECK_MEMBER_ACCESS_PERMISSION;
+
+    static {
+        CHECK_MEMBER_ACCESS_PERMISSION = null;
+    }
+
+    public static final java.security.SecurityPermission CREATE_ACC_PERMISSION;
+
+    static {
+        CREATE_ACC_PERMISSION = null;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final java.lang.RuntimePermission CREATE_CLASSLOADER_PERMISSION;
+
+    static {
+        CREATE_CLASSLOADER_PERMISSION = null;
+    }
+
+    public static final java.lang.String FILE_DELETE_ACTION = "delete";
+
+    public static final java.lang.String FILE_EXECUTE_ACTION = "execute";
+
+    public static final java.lang.String FILE_READLINK_ACTION = "readlink";
+
+    public static final java.lang.String FILE_READ_ACTION = "read";
+
+    public static final java.lang.String FILE_WRITE_ACTION = "write";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final java.lang.RuntimePermission GET_CLASSLOADER_PERMISSION;
+
+    static {
+        GET_CLASSLOADER_PERMISSION = null;
+    }
+
+    public static final java.security.SecurityPermission GET_COMBINER_PERMISSION;
+
+    static {
+        GET_COMBINER_PERMISSION = null;
+    }
+
+    public static final java.net.NetPermission GET_COOKIEHANDLER_PERMISSION;
+
+    static {
+        GET_COOKIEHANDLER_PERMISSION = null;
+    }
+
+    public static final java.lang.RuntimePermission GET_PD_PERMISSION;
+
+    static {
+        GET_PD_PERMISSION = null;
+    }
+
+    public static final java.security.SecurityPermission GET_POLICY_PERMISSION;
+
+    static {
+        GET_POLICY_PERMISSION = null;
+    }
+
+    public static final java.net.NetPermission GET_PROXYSELECTOR_PERMISSION;
+
+    static {
+        GET_PROXYSELECTOR_PERMISSION = null;
+    }
+
+    public static final java.net.NetPermission GET_RESPONSECACHE_PERMISSION;
+
+    static {
+        GET_RESPONSECACHE_PERMISSION = null;
+    }
+
+    public static final java.lang.RuntimePermission GET_STACK_TRACE_PERMISSION;
+
+    static {
+        GET_STACK_TRACE_PERMISSION = null;
+    }
+
+    public static final java.net.SocketPermission LOCAL_LISTEN_PERMISSION;
+
+    static {
+        LOCAL_LISTEN_PERMISSION = null;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final java.lang.RuntimePermission MODIFY_THREADGROUP_PERMISSION;
+
+    static {
+        MODIFY_THREADGROUP_PERMISSION = null;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final java.lang.RuntimePermission MODIFY_THREAD_PERMISSION;
+
+    static {
+        MODIFY_THREAD_PERMISSION = null;
+    }
+
+    public static final java.lang.String PROPERTY_READ_ACTION = "read";
+
+    public static final java.lang.String PROPERTY_RW_ACTION = "read,write";
+
+    public static final java.lang.String PROPERTY_WRITE_ACTION = "write";
+
+    public static final java.net.NetPermission SET_COOKIEHANDLER_PERMISSION;
+
+    static {
+        SET_COOKIEHANDLER_PERMISSION = null;
+    }
+
+    public static final java.net.NetPermission SET_PROXYSELECTOR_PERMISSION;
+
+    static {
+        SET_PROXYSELECTOR_PERMISSION = null;
+    }
+
+    public static final java.net.NetPermission SET_RESPONSECACHE_PERMISSION;
+
+    static {
+        SET_RESPONSECACHE_PERMISSION = null;
+    }
+
+    public static final java.lang.String SOCKET_ACCEPT_ACTION = "accept";
+
+    public static final java.lang.String SOCKET_CONNECT_ACCEPT_ACTION = "connect,accept";
+
+    public static final java.lang.String SOCKET_CONNECT_ACTION = "connect";
+
+    public static final java.lang.String SOCKET_LISTEN_ACTION = "listen";
+
+    public static final java.lang.String SOCKET_RESOLVE_ACTION = "resolve";
+
+    public static final java.net.NetPermission SPECIFY_HANDLER_PERMISSION;
+
+    static {
+        SPECIFY_HANDLER_PERMISSION = null;
+    }
+
+    public static final java.lang.RuntimePermission STOP_THREAD_PERMISSION;
+
+    static {
+        STOP_THREAD_PERMISSION = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/SignatureFileVerifier.java b/ojluni/annotations/hiddenapi/sun/security/util/SignatureFileVerifier.java
new file mode 100644
index 0000000..bce34ad
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/util/SignatureFileVerifier.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SignatureFileVerifier {
+
+    public SignatureFileVerifier(
+            java.util.ArrayList<java.security.CodeSigner[]> signerCache,
+            sun.security.util.ManifestDigester md,
+            java.lang.String name,
+            byte[] rawBytes)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean needSignatureFileBytes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean needSignatureFile(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setSignatureFile(byte[] sfBytes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static boolean isBlockOrSF(java.lang.String s) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isSigningRelated(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.security.MessageDigest getDigest(java.lang.String algorithm)
+            throws java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void process(
+            java.util.Hashtable<java.lang.String, java.security.CodeSigner[]> signers,
+            java.util.List<java.lang.Object> manifestDigests)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.util.jar.JarException, java.security.NoSuchAlgorithmException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void processImpl(
+            java.util.Hashtable<java.lang.String, java.security.CodeSigner[]> signers,
+            java.util.List<java.lang.Object> manifestDigests)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.util.jar.JarException, java.security.NoSuchAlgorithmException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean verifyManifestHash(
+            java.util.jar.Manifest sf,
+            sun.security.util.ManifestDigester md,
+            java.util.List<java.lang.Object> manifestDigests)
+            throws java.io.IOException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean verifyManifestMainAttrs(
+            java.util.jar.Manifest sf, sun.security.util.ManifestDigester md)
+            throws java.io.IOException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean verifySection(
+            java.util.jar.Attributes sfAttr,
+            java.lang.String name,
+            sun.security.util.ManifestDigester md)
+            throws java.io.IOException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.security.CodeSigner[] getSigners(
+            sun.security.pkcs.SignerInfo[] infos, sun.security.pkcs.PKCS7 block)
+            throws java.security.cert.CertificateException, java.io.IOException,
+                    java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String toHex(byte[] data) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean contains(java.security.CodeSigner[] set, java.security.CodeSigner signer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean isSubSet(java.security.CodeSigner[] subset, java.security.CodeSigner[] set) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean matches(
+            java.security.CodeSigner[] signers,
+            java.security.CodeSigner[] oldSigners,
+            java.security.CodeSigner[] newSigners) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void updateSigners(
+            java.security.CodeSigner[] newSigners,
+            java.util.Hashtable<java.lang.String, java.security.CodeSigner[]> signers,
+            java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String ATTR_DIGEST;
+
+    static {
+        ATTR_DIGEST = null;
+    }
+
+    private static final java.util.Set<java.security.CryptoPrimitive> DIGEST_PRIMITIVE_SET;
+
+    static {
+        DIGEST_PRIMITIVE_SET = null;
+    }
+
+    private static final sun.security.util.DisabledAlgorithmConstraints JAR_DISABLED_CHECK;
+
+    static {
+        JAR_DISABLED_CHECK = null;
+    }
+
+    private sun.security.pkcs.PKCS7 block;
+
+    private java.security.cert.CertificateFactory certificateFactory;
+
+    private java.util.HashMap<java.lang.String, java.security.MessageDigest> createdDigests;
+
+    private static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private static final char[] hexc;
+
+    static {
+        hexc = new char[0];
+    }
+
+    private sun.security.util.ManifestDigester md;
+
+    private java.lang.String name;
+
+    private byte[] sfBytes;
+
+    private java.util.ArrayList<java.security.CodeSigner[]> signerCache;
+
+    private boolean workaround = false;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AVA.java b/ojluni/annotations/hiddenapi/sun/security/x509/AVA.java
new file mode 100644
index 0000000..e2e18ca
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AVA.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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 sun.security.x509;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AVA implements sun.security.util.DerEncoder {
+
+    @UnsupportedAppUsage
+    public AVA(sun.security.util.ObjectIdentifier type, sun.security.util.DerValue val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(java.io.Reader in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(java.io.Reader in, java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(java.io.Reader in, int format) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(java.io.Reader in, int format, java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(sun.security.util.DerValue derval) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    AVA(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getObjectIdentifier() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public sun.security.util.DerValue getDerValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.String getValueString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.security.util.DerValue parseHexString(java.io.Reader in, int format)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.DerValue parseQuotedString(
+            java.io.Reader in, java.lang.StringBuilder temp) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.DerValue parseString(
+            java.io.Reader in, int c, int format, java.lang.StringBuilder temp)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.Byte getEmbeddedHexPair(int c1, java.io.Reader in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.lang.String getEmbeddedHexString(java.util.List<java.lang.Byte> hexList)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isTerminator(int ch, int format) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int readChar(java.io.Reader in, java.lang.String errMsg)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean trailingSpace(java.io.Reader in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toKeyword(
+            int format, java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC1779String() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC1779String(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC2253String() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC2253String(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.String toRFC2253CanonicalString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean isDerString(sun.security.util.DerValue value, boolean canonical) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    boolean hasRFC2253Keyword() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toKeywordValueString(java.lang.String keyword) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int DEFAULT = 1; // 0x1
+
+    private static final boolean PRESERVE_OLD_DC_ENCODING;
+
+    static {
+        PRESERVE_OLD_DC_ENCODING = false;
+    }
+
+    static final int RFC1779 = 2; // 0x2
+
+    static final int RFC2253 = 3; // 0x3
+
+    private static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private static final java.lang.String escapedDefault = ",+<>;\"";
+
+    private static final java.lang.String hexDigits = "0123456789ABCDEF";
+
+    final sun.security.util.ObjectIdentifier oid;
+
+    {
+        oid = null;
+    }
+
+    private static final java.lang.String specialChars1779 = ",=\n+<>#;\\\"";
+
+    private static final java.lang.String specialChars2253 = ",=+<>#;\\\"";
+
+    private static final java.lang.String specialCharsDefault = ",=\n+<>#;\\\" ";
+
+    final sun.security.util.DerValue value;
+
+    {
+        value = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AVAComparator.java b/ojluni/annotations/hiddenapi/sun/security/x509/AVAComparator.java
new file mode 100644
index 0000000..21494c3
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AVAComparator.java
@@ -0,0 +1,42 @@
+/*
+ * 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 sun.security.x509;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class AVAComparator implements java.util.Comparator<sun.security.x509.AVA> {
+
+    private AVAComparator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.util.Comparator<sun.security.x509.AVA> getInstance() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compare(sun.security.x509.AVA a1, sun.security.x509.AVA a2) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private static final java.util.Comparator<sun.security.x509.AVA> INSTANCE;
+
+    static {
+        INSTANCE = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AVAKeyword.java b/ojluni/annotations/hiddenapi/sun/security/x509/AVAKeyword.java
new file mode 100644
index 0000000..78d379f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AVAKeyword.java
@@ -0,0 +1,85 @@
+/*
+ * 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 sun.security.x509;
+
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class AVAKeyword {
+
+    private AVAKeyword(
+            java.lang.String keyword,
+            sun.security.util.ObjectIdentifier oid,
+            boolean rfc1779Compliant,
+            boolean rfc2253Compliant) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    private boolean isCompliant(int standard) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    static sun.security.util.ObjectIdentifier getOID(
+            java.lang.String keyword,
+            int standard,
+            java.util.Map<java.lang.String, java.lang.String> extraKeywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String getKeyword(sun.security.util.ObjectIdentifier oid, int standard) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.lang.String getKeyword(
+            sun.security.util.ObjectIdentifier oid,
+            int standard,
+            java.util.Map<java.lang.String, java.lang.String> extraOidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static boolean hasKeyword(sun.security.util.ObjectIdentifier oid, int standard) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage private java.lang.String keyword;
+
+    @UnsupportedAppUsage
+    private static final java.util.Map<java.lang.String, sun.security.x509.AVAKeyword> keywordMap;
+
+    static {
+        keywordMap = null;
+    }
+
+    @UnsupportedAppUsage private sun.security.util.ObjectIdentifier oid;
+
+    @UnsupportedAppUsage
+    private static final java.util.Map<
+                    sun.security.util.ObjectIdentifier, sun.security.x509.AVAKeyword>
+            oidMap;
+
+    static {
+        oidMap = null;
+    }
+
+    private boolean rfc1779Compliant;
+
+    private boolean rfc2253Compliant;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AccessDescription.java b/ojluni/annotations/hiddenapi/sun/security/x509/AccessDescription.java
new file mode 100644
index 0000000..5f3d77f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AccessDescription.java
@@ -0,0 +1,99 @@
+/*
+ * 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class AccessDescription {
+
+    public AccessDescription(
+            sun.security.util.ObjectIdentifier accessMethod,
+            sun.security.x509.GeneralName accessLocation) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public AccessDescription(sun.security.util.DerValue derValue) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getAccessMethod() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.GeneralName getAccessLocation() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final sun.security.util.ObjectIdentifier Ad_CAISSUERS_Id;
+
+    static {
+        Ad_CAISSUERS_Id = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier Ad_CAREPOSITORY_Id;
+
+    static {
+        Ad_CAREPOSITORY_Id = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier Ad_OCSP_Id;
+
+    static {
+        Ad_OCSP_Id = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier Ad_TIMESTAMPING_Id;
+
+    static {
+        Ad_TIMESTAMPING_Id = null;
+    }
+
+    private sun.security.x509.GeneralName accessLocation;
+
+    private sun.security.util.ObjectIdentifier accessMethod;
+
+    private int myhash = -1; // 0xffffffff
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java b/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java
new file mode 100644
index 0000000..3f9214b
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java
@@ -0,0 +1,547 @@
+/*
+ * 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 sun.security.x509;
+
+import dalvik.annotation.compat.UnsupportedAppUsage;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AlgorithmId implements java.io.Serializable, sun.security.util.DerEncoder {
+
+    @Deprecated
+    @UnsupportedAppUsage
+    public AlgorithmId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public AlgorithmId(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public AlgorithmId(
+            sun.security.util.ObjectIdentifier oid, java.security.AlgorithmParameters algparams) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private AlgorithmId(sun.security.util.ObjectIdentifier oid, sun.security.util.DerValue params)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void decodeParams() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public final void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public final byte[] encode() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public final sun.security.util.ObjectIdentifier getOID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public java.security.AlgorithmParameters getParameters() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public byte[] getEncodedParams() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public boolean equals(sun.security.x509.AlgorithmId other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final boolean equals(sun.security.util.ObjectIdentifier id) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected java.lang.String paramsToString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static sun.security.x509.AlgorithmId parse(sun.security.util.DerValue val)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage
+    public static sun.security.x509.AlgorithmId getAlgorithmId(java.lang.String algname)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static sun.security.x509.AlgorithmId get(java.lang.String algname)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.AlgorithmId get(java.security.AlgorithmParameters algparams)
+            throws java.security.NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.security.util.ObjectIdentifier algOID(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void reinitializeMappingTableLocked() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static sun.security.util.ObjectIdentifier oid(int... values) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String makeSigAlg(java.lang.String digAlg, java.lang.String encAlg) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static java.lang.String getEncAlgFromSigAlg(java.lang.String signatureAlgorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @UnsupportedAppUsage
+    public static java.lang.String getDigAlgFromSigAlg(java.lang.String signatureAlgorithm) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final sun.security.util.ObjectIdentifier AES_oid;
+
+    static {
+        AES_oid = null;
+    }
+
+    private static final int[] DH_PKIX_data;
+
+    static {
+        DH_PKIX_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier DH_PKIX_oid;
+
+    static {
+        DH_PKIX_oid = null;
+    }
+
+    private static final int[] DH_data;
+
+    static {
+        DH_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier DH_oid;
+
+    static {
+        DH_oid = null;
+    }
+
+    private static final int[] DSA_OIW_data;
+
+    static {
+        DSA_OIW_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier DSA_OIW_oid;
+
+    static {
+        DSA_OIW_oid = null;
+    }
+
+    private static final int[] DSA_PKIX_data;
+
+    static {
+        DSA_PKIX_data = new int[0];
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier DSA_oid;
+
+    static {
+        DSA_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier ECDH_oid;
+
+    static {
+        ECDH_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier EC_oid;
+
+    static {
+        EC_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier MD2_oid;
+
+    static {
+        MD2_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier MD5_oid;
+
+    static {
+        MD5_oid = null;
+    }
+
+    private static final int[] RSAEncryption_data;
+
+    static {
+        RSAEncryption_data = new int[0];
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier RSAEncryption_oid;
+
+    static {
+        RSAEncryption_oid = null;
+    }
+
+    private static final int[] RSA_data;
+
+    static {
+        RSA_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier RSA_oid;
+
+    static {
+        RSA_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier SHA224_oid;
+
+    static {
+        SHA224_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SHA256_oid;
+
+    static {
+        SHA256_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SHA384_oid;
+
+    static {
+        SHA384_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SHA512_oid;
+
+    static {
+        SHA512_oid = null;
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SHA_oid;
+
+    static {
+        SHA_oid = null;
+    }
+
+    private java.security.AlgorithmParameters algParams;
+
+    private sun.security.util.ObjectIdentifier algid;
+
+    private boolean constructedFromDer = true;
+
+    private static final int[] dsaWithSHA1_PKIX_data;
+
+    static {
+        dsaWithSHA1_PKIX_data = new int[0];
+    }
+
+    private static int initOidTableVersion = -1; // 0xffffffff
+
+    private static final int[] md2WithRSAEncryption_data;
+
+    static {
+        md2WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier md2WithRSAEncryption_oid;
+
+    static {
+        md2WithRSAEncryption_oid = null;
+    }
+
+    private static final int[] md5WithRSAEncryption_data;
+
+    static {
+        md5WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier md5WithRSAEncryption_oid;
+
+    static {
+        md5WithRSAEncryption_oid = null;
+    }
+
+    private static final java.util.Map<sun.security.util.ObjectIdentifier, java.lang.String>
+            nameTable;
+
+    static {
+        nameTable = null;
+    }
+
+    private static final java.util.Map<java.lang.String, sun.security.util.ObjectIdentifier>
+            oidTable;
+
+    static {
+        oidTable = null;
+    }
+
+    @UnsupportedAppUsage
+    protected sun.security.util.DerValue params;
+
+    public static final sun.security.util.ObjectIdentifier pbeWithMD5AndDES_oid;
+
+    static {
+        pbeWithMD5AndDES_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier pbeWithMD5AndRC2_oid;
+
+    static {
+        pbeWithMD5AndRC2_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier pbeWithSHA1AndDES_oid;
+
+    static {
+        pbeWithSHA1AndDES_oid = null;
+    }
+
+    public static sun.security.util.ObjectIdentifier pbeWithSHA1AndDESede_oid;
+
+    public static sun.security.util.ObjectIdentifier pbeWithSHA1AndRC2_40_oid;
+
+    public static final sun.security.util.ObjectIdentifier pbeWithSHA1AndRC2_oid;
+
+    static {
+        pbeWithSHA1AndRC2_oid = null;
+    }
+
+    private static final long serialVersionUID = 7205873507486557157L; // 0x640067c6d62263e5L
+
+    private static final int[] sha1WithDSA_OIW_data;
+
+    static {
+        sha1WithDSA_OIW_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha1WithDSA_OIW_oid;
+
+    static {
+        sha1WithDSA_OIW_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha1WithDSA_oid;
+
+    static {
+        sha1WithDSA_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha1WithECDSA_oid;
+
+    static {
+        sha1WithECDSA_oid = null;
+    }
+
+    private static final int[] sha1WithRSAEncryption_OIW_data;
+
+    static {
+        sha1WithRSAEncryption_OIW_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha1WithRSAEncryption_OIW_oid;
+
+    static {
+        sha1WithRSAEncryption_OIW_oid = null;
+    }
+
+    private static final int[] sha1WithRSAEncryption_data;
+
+    static {
+        sha1WithRSAEncryption_data = new int[0];
+    }
+
+    @UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier sha1WithRSAEncryption_oid;
+
+    static {
+        sha1WithRSAEncryption_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha224WithDSA_oid;
+
+    static {
+        sha224WithDSA_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha224WithECDSA_oid;
+
+    static {
+        sha224WithECDSA_oid = null;
+    }
+
+    private static final int[] sha224WithRSAEncryption_data;
+
+    static {
+        sha224WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha224WithRSAEncryption_oid;
+
+    static {
+        sha224WithRSAEncryption_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha256WithDSA_oid;
+
+    static {
+        sha256WithDSA_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha256WithECDSA_oid;
+
+    static {
+        sha256WithECDSA_oid = null;
+    }
+
+    private static final int[] sha256WithRSAEncryption_data;
+
+    static {
+        sha256WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha256WithRSAEncryption_oid;
+
+    static {
+        sha256WithRSAEncryption_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha384WithECDSA_oid;
+
+    static {
+        sha384WithECDSA_oid = null;
+    }
+
+    private static final int[] sha384WithRSAEncryption_data;
+
+    static {
+        sha384WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha384WithRSAEncryption_oid;
+
+    static {
+        sha384WithRSAEncryption_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha512WithECDSA_oid;
+
+    static {
+        sha512WithECDSA_oid = null;
+    }
+
+    private static final int[] sha512WithRSAEncryption_data;
+
+    static {
+        sha512WithRSAEncryption_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier sha512WithRSAEncryption_oid;
+
+    static {
+        sha512WithRSAEncryption_oid = null;
+    }
+
+    private static final int[] shaWithDSA_OIW_data;
+
+    static {
+        shaWithDSA_OIW_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier shaWithDSA_OIW_oid;
+
+    static {
+        shaWithDSA_OIW_oid = null;
+    }
+
+    public static final sun.security.util.ObjectIdentifier specifiedWithECDSA_oid;
+
+    static {
+        specifiedWithECDSA_oid = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AttributeNameEnumeration.java b/ojluni/annotations/hiddenapi/sun/security/x509/AttributeNameEnumeration.java
new file mode 100644
index 0000000..c3728d7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AttributeNameEnumeration.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997, 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.
+ */
+
+package sun.security.x509;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AttributeNameEnumeration extends java.util.Vector<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public AttributeNameEnumeration() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long serialVersionUID = -6067440240757099134L; // 0xabcc1f3f69c33582L
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CRLDistributionPointsExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/CRLDistributionPointsExtension.java
new file mode 100644
index 0000000..84063ed
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CRLDistributionPointsExtension.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2002, 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 sun.security.x509;
+
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CRLDistributionPointsExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public CRLDistributionPointsExtension(
+            java.util.List<sun.security.x509.DistributionPoint> distributionPoints)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CRLDistributionPointsExtension(
+            boolean isCritical,
+            java.util.List<sun.security.x509.DistributionPoint> distributionPoints)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CRLDistributionPointsExtension(
+            sun.security.util.ObjectIdentifier extensionId,
+            boolean isCritical,
+            java.util.List<sun.security.x509.DistributionPoint> distributionPoints,
+            java.lang.String extensionName)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CRLDistributionPointsExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CRLDistributionPointsExtension(
+            sun.security.util.ObjectIdentifier extensionId,
+            java.lang.Boolean critical,
+            java.lang.Object value,
+            java.lang.String extensionName)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encode(
+            java.io.OutputStream out,
+            sun.security.util.ObjectIdentifier extensionId,
+            boolean isCritical)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<sun.security.x509.DistributionPoint> get(java.lang.String name)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.extensions.CRLDistributionPoints";
+
+    public static final java.lang.String NAME = "CRLDistributionPoints";
+
+    public static final java.lang.String POINTS = "points";
+
+    private java.util.List<sun.security.x509.DistributionPoint> distributionPoints;
+
+    private java.lang.String extensionName;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java
new file mode 100644
index 0000000..00d0ee0
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CRLNumberExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public CRLNumberExtension(int crlNum) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CRLNumberExtension(java.math.BigInteger crlNum) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CRLNumberExtension(
+            sun.security.util.ObjectIdentifier extensionId,
+            boolean isCritical,
+            java.math.BigInteger crlNum,
+            java.lang.String extensionName,
+            java.lang.String extensionLabel)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CRLNumberExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CRLNumberExtension(
+            sun.security.util.ObjectIdentifier extensionId,
+            java.lang.Boolean critical,
+            java.lang.Object value,
+            java.lang.String extensionName,
+            java.lang.String extensionLabel)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.math.BigInteger get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void encode(
+            java.io.OutputStream out,
+            sun.security.util.ObjectIdentifier extensionId,
+            boolean isCritical)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String LABEL = "CRL Number";
+
+    public static final java.lang.String NAME = "CRLNumber";
+
+    public static final java.lang.String NUMBER = "value";
+
+    private java.math.BigInteger crlNumber;
+
+    private java.lang.String extensionLabel;
+
+    private java.lang.String extensionName;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateAlgorithmId.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateAlgorithmId.java
new file mode 100644
index 0000000..5a3bc38
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateAlgorithmId.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateAlgorithmId implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateAlgorithmId(sun.security.x509.AlgorithmId algId) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateAlgorithmId(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateAlgorithmId(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AlgorithmId get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String ALGORITHM = "algorithm";
+
+    public static final java.lang.String IDENT = "x509.info.algorithmID";
+
+    public static final java.lang.String NAME = "algorithmID";
+
+    private sun.security.x509.AlgorithmId algId;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java
new file mode 100644
index 0000000..cad6f74
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateExtensions
+        implements sun.security.x509.CertAttrSet<sun.security.x509.Extension> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateExtensions(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void init(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseExtension(sun.security.x509.Extension ext) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(java.io.OutputStream out, boolean isCertReq)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.Extension get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.x509.Extension getExtension(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getNameByOid(sun.security.util.ObjectIdentifier oid)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<sun.security.x509.Extension> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Collection<sun.security.x509.Extension> getAllExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Map<java.lang.String, sun.security.x509.Extension> getUnparseableExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasUnsupportedCriticalExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.extensions";
+
+    public static final java.lang.String NAME = "extensions";
+
+    private static java.lang.Class[] PARAMS;
+
+    private static final sun.security.util.Debug debug;
+
+    static {
+        debug = null;
+    }
+
+    private java.util.Map<java.lang.String, sun.security.x509.Extension> map;
+
+    private java.util.Map<java.lang.String, sun.security.x509.Extension> unparseableExtensions;
+
+    private boolean unsupportedCritExt = false;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateIssuerName.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateIssuerName.java
new file mode 100644
index 0000000..22380db
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateIssuerName.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateIssuerName implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateIssuerName(sun.security.x509.X500Name name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateIssuerName(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateIssuerName(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String DN_NAME = "dname";
+
+    public static final java.lang.String DN_PRINCIPAL = "x500principal";
+
+    public static final java.lang.String IDENT = "x509.info.issuer";
+
+    public static final java.lang.String NAME = "issuer";
+
+    private sun.security.x509.X500Name dnName;
+
+    private javax.security.auth.x500.X500Principal dnPrincipal;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSerialNumber.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSerialNumber.java
new file mode 100644
index 0000000..131b445
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSerialNumber.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateSerialNumber implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateSerialNumber(java.math.BigInteger num) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateSerialNumber(int num) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateSerialNumber(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateSerialNumber(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateSerialNumber(sun.security.util.DerValue val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.SerialNumber get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.serialNumber";
+
+    public static final java.lang.String NAME = "serialNumber";
+
+    public static final java.lang.String NUMBER = "number";
+
+    private sun.security.x509.SerialNumber serial;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSubjectName.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSubjectName.java
new file mode 100644
index 0000000..f5ff910
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateSubjectName.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateSubjectName implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateSubjectName(sun.security.x509.X500Name name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateSubjectName(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateSubjectName(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Object get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String DN_NAME = "dname";
+
+    public static final java.lang.String DN_PRINCIPAL = "x500principal";
+
+    public static final java.lang.String IDENT = "x509.info.subject";
+
+    public static final java.lang.String NAME = "subject";
+
+    private sun.security.x509.X500Name dnName;
+
+    private javax.security.auth.x500.X500Principal dnPrincipal;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateValidity.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateValidity.java
new file mode 100644
index 0000000..bb5d599
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateValidity.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.security.cert.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateValidity implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public CertificateValidity() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateValidity(java.util.Date notBefore, java.util.Date notAfter) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateValidity(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Date getNotBefore() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.util.Date getNotAfter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void construct(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void valid()
+            throws java.security.cert.CertificateExpiredException,
+                    java.security.cert.CertificateNotYetValidException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void valid(java.util.Date now)
+            throws java.security.cert.CertificateExpiredException,
+                    java.security.cert.CertificateNotYetValidException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.validity";
+
+    public static final java.lang.String NAME = "validity";
+
+    public static final java.lang.String NOT_AFTER = "notAfter";
+
+    public static final java.lang.String NOT_BEFORE = "notBefore";
+
+    private static final long YR_2050 = 2524636800000L; // 0x24bd0146400L
+
+    private java.util.Date notAfter;
+
+    private java.util.Date notBefore;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateVersion.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateVersion.java
new file mode 100644
index 0000000..85ad759
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateVersion.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateVersion implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public CertificateVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateVersion(int version) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateVersion(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateVersion(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateVersion(sun.security.util.DerValue val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void construct(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Integer get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compare(int vers) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.version";
+
+    public static final java.lang.String NAME = "version";
+
+    public static final int V1 = 0; // 0x0
+
+    public static final int V2 = 1; // 0x1
+
+    public static final int V3 = 2; // 0x2
+
+    public static final java.lang.String VERSION = "number";
+
+    int version = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateX509Key.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateX509Key.java
new file mode 100644
index 0000000..6f45057
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateX509Key.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CertificateX509Key implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public CertificateX509Key(java.security.PublicKey key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateX509Key(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public CertificateX509Key(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.PublicKey get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.key";
+
+    public static final java.lang.String KEY = "value";
+
+    public static final java.lang.String NAME = "key";
+
+    private java.security.PublicKey key;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/Extension.java b/ojluni/annotations/hiddenapi/sun/security/x509/Extension.java
new file mode 100644
index 0000000..f4acc6c
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/Extension.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Extension implements java.security.cert.Extension {
+
+    public Extension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Extension(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public Extension(
+            sun.security.util.ObjectIdentifier extensionId, boolean critical, byte[] extensionValue)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public Extension(sun.security.x509.Extension ext) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.Extension newExtension(
+            sun.security.util.ObjectIdentifier extensionId,
+            boolean critical,
+            byte[] rawExtensionValue)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isCritical() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.util.ObjectIdentifier getExtensionId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getExtensionValue() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean critical = false;
+
+    protected sun.security.util.ObjectIdentifier extensionId;
+
+    protected byte[] extensionValue;
+
+    private static final int hashMagic = 31; // 0x1f
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/GeneralName.java b/ojluni/annotations/hiddenapi/sun/security/x509/GeneralName.java
new file mode 100644
index 0000000..c7eb02e
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/GeneralName.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GeneralName {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GeneralName(sun.security.x509.GeneralNameInterface name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public GeneralName(sun.security.util.DerValue encName) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public GeneralName(sun.security.util.DerValue encName, boolean nameConstraint)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.GeneralNameInterface getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.x509.GeneralNameInterface name;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/GeneralNames.java b/ojluni/annotations/hiddenapi/sun/security/x509/GeneralNames.java
new file mode 100644
index 0000000..fdac69f
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/GeneralNames.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997, 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.
+ */
+
+package sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class GeneralNames {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GeneralNames(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public GeneralNames() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.GeneralNames add(sun.security.x509.GeneralName name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.GeneralName get(int index) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Iterator<sun.security.x509.GeneralName> iterator() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<sun.security.x509.GeneralName> names() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.util.List<sun.security.x509.GeneralName> names;
+
+    {
+        names = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/KeyIdentifier.java b/ojluni/annotations/hiddenapi/sun/security/x509/KeyIdentifier.java
new file mode 100644
index 0000000..8faa83a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/KeyIdentifier.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class KeyIdentifier {
+
+    public KeyIdentifier(byte[] octetString) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public KeyIdentifier(sun.security.util.DerValue val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public KeyIdentifier(java.security.PublicKey pubKey) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getIdentifier() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private byte[] octetString;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java
new file mode 100644
index 0000000..e9addc9
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java
@@ -0,0 +1,124 @@
+/*
+ * 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class KeyUsageExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public KeyUsageExtension(byte[] bitString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public KeyUsageExtension(boolean[] bitString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public KeyUsageExtension(sun.security.util.BitArray bitString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public KeyUsageExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public KeyUsageExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isSet(int position) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void set(int position, boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Boolean get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getBits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String CRL_SIGN = "crl_sign";
+
+    public static final java.lang.String DATA_ENCIPHERMENT = "data_encipherment";
+
+    public static final java.lang.String DECIPHER_ONLY = "decipher_only";
+
+    public static final java.lang.String DIGITAL_SIGNATURE = "digital_signature";
+
+    public static final java.lang.String ENCIPHER_ONLY = "encipher_only";
+
+    public static final java.lang.String IDENT = "x509.info.extensions.KeyUsage";
+
+    public static final java.lang.String KEY_AGREEMENT = "key_agreement";
+
+    public static final java.lang.String KEY_CERTSIGN = "key_certsign";
+
+    public static final java.lang.String KEY_ENCIPHERMENT = "key_encipherment";
+
+    public static final java.lang.String NAME = "KeyUsage";
+
+    public static final java.lang.String NON_REPUDIATION = "non_repudiation";
+
+    private boolean[] bitString;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java
new file mode 100644
index 0000000..88e4f11
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1998, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class NetscapeCertTypeExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public NetscapeCertTypeExtension(byte[] bitString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public NetscapeCertTypeExtension(boolean[] bitString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public NetscapeCertTypeExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public NetscapeCertTypeExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static int getPosition(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isSet(int position) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void set(int position, boolean val) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Boolean get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getKeyUsageMappedBits() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int[] CertType_data;
+
+    static {
+        CertType_data = new int[0];
+    }
+
+    public static final java.lang.String IDENT = "x509.info.extensions.NetscapeCertType";
+
+    public static final java.lang.String NAME = "NetscapeCertType";
+
+    public static sun.security.util.ObjectIdentifier NetscapeCertType_Id;
+
+    public static final java.lang.String OBJECT_SIGNING = "object_signing";
+
+    public static final java.lang.String OBJECT_SIGNING_CA = "object_signing_ca";
+
+    public static final java.lang.String SSL_CA = "ssl_ca";
+
+    public static final java.lang.String SSL_CLIENT = "ssl_client";
+
+    public static final java.lang.String SSL_SERVER = "ssl_server";
+
+    public static final java.lang.String S_MIME = "s_mime";
+
+    public static final java.lang.String S_MIME_CA = "s_mime_ca";
+
+    private boolean[] bitString;
+
+    private static final java.util.Vector<java.lang.String> mAttributeNames;
+
+    static {
+        mAttributeNames = null;
+    }
+
+    private static sun.security.x509.NetscapeCertTypeExtension.MapEntry[] mMapData;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class MapEntry {
+
+        MapEntry(java.lang.String name, int position) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.String mName;
+
+        int mPosition;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/OIDMap.java b/ojluni/annotations/hiddenapi/sun/security/x509/OIDMap.java
new file mode 100644
index 0000000..8186c23
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/OIDMap.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class OIDMap {
+
+    private OIDMap() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void addInternal(
+            java.lang.String name, sun.security.util.ObjectIdentifier oid, java.lang.Class clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void addAttribute(
+            java.lang.String name, java.lang.String oid, java.lang.Class<?> clazz)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getName(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.util.ObjectIdentifier getOID(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.Class<?> getClass(java.lang.String name)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.lang.Class<?> getClass(sun.security.util.ObjectIdentifier oid)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final java.lang.String AUTH_INFO_ACCESS =
+            "x509.info.extensions.AuthorityInfoAccess";
+
+    private static final java.lang.String AUTH_KEY_IDENTIFIER =
+            "x509.info.extensions.AuthorityKeyIdentifier";
+
+    private static final java.lang.String BASIC_CONSTRAINTS =
+            "x509.info.extensions.BasicConstraints";
+
+    private static final java.lang.String CERT_ISSUER = "x509.info.extensions.CertificateIssuer";
+
+    private static final java.lang.String CERT_POLICIES =
+            "x509.info.extensions.CertificatePolicies";
+
+    private static final java.lang.String CRL_DIST_POINTS =
+            "x509.info.extensions.CRLDistributionPoints";
+
+    private static final java.lang.String CRL_NUMBER = "x509.info.extensions.CRLNumber";
+
+    private static final java.lang.String CRL_REASON = "x509.info.extensions.CRLReasonCode";
+
+    private static final java.lang.String DELTA_CRL_INDICATOR =
+            "x509.info.extensions.DeltaCRLIndicator";
+
+    private static final java.lang.String EXT_KEY_USAGE = "x509.info.extensions.ExtendedKeyUsage";
+
+    private static final java.lang.String FRESHEST_CRL = "x509.info.extensions.FreshestCRL";
+
+    private static final java.lang.String INHIBIT_ANY_POLICY =
+            "x509.info.extensions.InhibitAnyPolicy";
+
+    private static final java.lang.String ISSUER_ALT_NAME =
+            "x509.info.extensions.IssuerAlternativeName";
+
+    private static final java.lang.String ISSUING_DIST_POINT =
+            "x509.info.extensions.IssuingDistributionPoint";
+
+    private static final java.lang.String KEY_USAGE = "x509.info.extensions.KeyUsage";
+
+    private static final java.lang.String NAME_CONSTRAINTS = "x509.info.extensions.NameConstraints";
+
+    private static final java.lang.String NETSCAPE_CERT = "x509.info.extensions.NetscapeCertType";
+
+    private static final int[] NetscapeCertType_data;
+
+    static {
+        NetscapeCertType_data = new int[0];
+    }
+
+    private static final java.lang.String OCSPNOCHECK = "x509.info.extensions.OCSPNoCheck";
+
+    private static final java.lang.String POLICY_CONSTRAINTS =
+            "x509.info.extensions.PolicyConstraints";
+
+    private static final java.lang.String POLICY_MAPPINGS = "x509.info.extensions.PolicyMappings";
+
+    private static final java.lang.String PRIVATE_KEY_USAGE =
+            "x509.info.extensions.PrivateKeyUsage";
+
+    private static final java.lang.String ROOT = "x509.info.extensions";
+
+    private static final java.lang.String SUBJECT_INFO_ACCESS =
+            "x509.info.extensions.SubjectInfoAccess";
+
+    private static final java.lang.String SUB_ALT_NAME =
+            "x509.info.extensions.SubjectAlternativeName";
+
+    private static final java.lang.String SUB_KEY_IDENTIFIER =
+            "x509.info.extensions.SubjectKeyIdentifier";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static final java.util.Map<java.lang.String, sun.security.x509.OIDMap.OIDInfo> nameMap;
+
+    static {
+        nameMap = null;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private static final java.util.Map<
+                    sun.security.util.ObjectIdentifier, sun.security.x509.OIDMap.OIDInfo>
+            oidMap;
+
+    static {
+        oidMap = null;
+    }
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static class OIDInfo {
+
+        OIDInfo(
+                java.lang.String name,
+                sun.security.util.ObjectIdentifier oid,
+                java.lang.Class<?> clazz) {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.lang.Class<?> getClazz() throws java.security.cert.CertificateException {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage private volatile java.lang.Class<?> clazz;
+
+        final java.lang.String name;
+
+        {
+            name = null;
+        }
+
+        final sun.security.util.ObjectIdentifier oid;
+
+        {
+            oid = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/PKIXExtensions.java b/ojluni/annotations/hiddenapi/sun/security/x509/PKIXExtensions.java
new file mode 100644
index 0000000..de3027a
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/PKIXExtensions.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import java.io.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKIXExtensions {
+
+    public PKIXExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final sun.security.util.ObjectIdentifier AuthInfoAccess_Id;
+
+    static {
+        AuthInfoAccess_Id = null;
+    }
+
+    private static final int[] AuthInfoAccess_data;
+
+    static {
+        AuthInfoAccess_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier AuthorityKey_Id;
+
+    static {
+        AuthorityKey_Id = null;
+    }
+
+    private static final int[] AuthorityKey_data;
+
+    static {
+        AuthorityKey_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier BasicConstraints_Id;
+
+    static {
+        BasicConstraints_Id = null;
+    }
+
+    private static final int[] BasicConstraints_data;
+
+    static {
+        BasicConstraints_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier CRLDistributionPoints_Id;
+
+    static {
+        CRLDistributionPoints_Id = null;
+    }
+
+    private static final int[] CRLDistributionPoints_data;
+
+    static {
+        CRLDistributionPoints_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier CRLNumber_Id;
+
+    static {
+        CRLNumber_Id = null;
+    }
+
+    private static final int[] CRLNumber_data;
+
+    static {
+        CRLNumber_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier CertificateIssuer_Id;
+
+    static {
+        CertificateIssuer_Id = null;
+    }
+
+    private static final int[] CertificateIssuer_data;
+
+    static {
+        CertificateIssuer_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier CertificatePolicies_Id;
+
+    static {
+        CertificatePolicies_Id = null;
+    }
+
+    private static final int[] CertificatePolicies_data;
+
+    static {
+        CertificatePolicies_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier DeltaCRLIndicator_Id;
+
+    static {
+        DeltaCRLIndicator_Id = null;
+    }
+
+    private static final int[] DeltaCRLIndicator_data;
+
+    static {
+        DeltaCRLIndicator_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier ExtendedKeyUsage_Id;
+
+    static {
+        ExtendedKeyUsage_Id = null;
+    }
+
+    private static final int[] ExtendedKeyUsage_data;
+
+    static {
+        ExtendedKeyUsage_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier FreshestCRL_Id;
+
+    static {
+        FreshestCRL_Id = null;
+    }
+
+    private static final int[] FreshestCRL_data;
+
+    static {
+        FreshestCRL_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier HoldInstructionCode_Id;
+
+    static {
+        HoldInstructionCode_Id = null;
+    }
+
+    private static final int[] HoldInstructionCode_data;
+
+    static {
+        HoldInstructionCode_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier InhibitAnyPolicy_Id;
+
+    static {
+        InhibitAnyPolicy_Id = null;
+    }
+
+    private static final int[] InhibitAnyPolicy_data;
+
+    static {
+        InhibitAnyPolicy_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier InvalidityDate_Id;
+
+    static {
+        InvalidityDate_Id = null;
+    }
+
+    private static final int[] InvalidityDate_data;
+
+    static {
+        InvalidityDate_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier IssuerAlternativeName_Id;
+
+    static {
+        IssuerAlternativeName_Id = null;
+    }
+
+    private static final int[] IssuerAlternativeName_data;
+
+    static {
+        IssuerAlternativeName_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier IssuingDistributionPoint_Id;
+
+    static {
+        IssuingDistributionPoint_Id = null;
+    }
+
+    private static final int[] IssuingDistributionPoint_data;
+
+    static {
+        IssuingDistributionPoint_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier KeyUsage_Id;
+
+    static {
+        KeyUsage_Id = null;
+    }
+
+    private static final int[] KeyUsage_data;
+
+    static {
+        KeyUsage_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier NameConstraints_Id;
+
+    static {
+        NameConstraints_Id = null;
+    }
+
+    private static final int[] NameConstraints_data;
+
+    static {
+        NameConstraints_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier OCSPNoCheck_Id;
+
+    static {
+        OCSPNoCheck_Id = null;
+    }
+
+    private static final int[] OCSPNoCheck_data;
+
+    static {
+        OCSPNoCheck_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier PolicyConstraints_Id;
+
+    static {
+        PolicyConstraints_Id = null;
+    }
+
+    private static final int[] PolicyConstraints_data;
+
+    static {
+        PolicyConstraints_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier PolicyMappings_Id;
+
+    static {
+        PolicyMappings_Id = null;
+    }
+
+    private static final int[] PolicyMappings_data;
+
+    static {
+        PolicyMappings_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier PrivateKeyUsage_Id;
+
+    static {
+        PrivateKeyUsage_Id = null;
+    }
+
+    private static final int[] PrivateKeyUsage_data;
+
+    static {
+        PrivateKeyUsage_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier ReasonCode_Id;
+
+    static {
+        ReasonCode_Id = null;
+    }
+
+    private static final int[] ReasonCode_data;
+
+    static {
+        ReasonCode_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier SubjectAlternativeName_Id;
+
+    static {
+        SubjectAlternativeName_Id = null;
+    }
+
+    private static final int[] SubjectAlternativeName_data;
+
+    static {
+        SubjectAlternativeName_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier SubjectDirectoryAttributes_Id;
+
+    static {
+        SubjectDirectoryAttributes_Id = null;
+    }
+
+    private static final int[] SubjectDirectoryAttributes_data;
+
+    static {
+        SubjectDirectoryAttributes_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier SubjectInfoAccess_Id;
+
+    static {
+        SubjectInfoAccess_Id = null;
+    }
+
+    private static final int[] SubjectInfoAccess_data;
+
+    static {
+        SubjectInfoAccess_data = new int[0];
+    }
+
+    public static final sun.security.util.ObjectIdentifier SubjectKey_Id;
+
+    static {
+        SubjectKey_Id = null;
+    }
+
+    private static final int[] SubjectKey_data;
+
+    static {
+        SubjectKey_data = new int[0];
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/RDN.java b/ojluni/annotations/hiddenapi/sun/security/x509/RDN.java
new file mode 100644
index 0000000..c2d2018
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/RDN.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2002, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class RDN {
+
+    public RDN(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public RDN(java.lang.String name, java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    RDN(java.lang.String name, java.lang.String format) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    RDN(
+            java.lang.String name,
+            java.lang.String format,
+            java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    RDN(sun.security.util.DerValue rdn) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    RDN(int i) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public RDN(sun.security.x509.AVA ava) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public RDN(sun.security.x509.AVA[] avas) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<sun.security.x509.AVA> avas() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.util.DerValue findAttribute(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC1779String() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC1779String(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC2253String() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC2253String(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toRFC2253String(boolean canonical) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String toRFC2253StringInternal(
+            boolean canonical, java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final sun.security.x509.AVA[] assertion;
+
+    {
+        assertion = new sun.security.x509.AVA[0];
+    }
+
+    private volatile java.util.List<sun.security.x509.AVA> avaList;
+
+    private volatile java.lang.String canonicalString;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/SerialNumber.java b/ojluni/annotations/hiddenapi/sun/security/x509/SerialNumber.java
new file mode 100644
index 0000000..1c14ef3
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/SerialNumber.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SerialNumber {
+
+    public SerialNumber(java.math.BigInteger num) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SerialNumber(int num) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SerialNumber(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public SerialNumber(sun.security.util.DerValue val) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SerialNumber(java.io.InputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void construct(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.math.BigInteger serialNum;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java
new file mode 100644
index 0000000..44aa6ab
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SubjectAlternativeNameExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    public SubjectAlternativeNameExtension(sun.security.x509.GeneralNames names)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SubjectAlternativeNameExtension(
+            java.lang.Boolean critical, sun.security.x509.GeneralNames names)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SubjectAlternativeNameExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SubjectAlternativeNameExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.GeneralNames get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.extensions.SubjectAlternativeName";
+
+    public static final java.lang.String NAME = "SubjectAlternativeName";
+
+    public static final java.lang.String SUBJECT_NAME = "subject_name";
+
+    sun.security.x509.GeneralNames names;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/SubjectKeyIdentifierExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectKeyIdentifierExtension.java
new file mode 100644
index 0000000..2a85bd5
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectKeyIdentifierExtension.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SubjectKeyIdentifierExtension extends sun.security.x509.Extension
+        implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public SubjectKeyIdentifierExtension(byte[] octetString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public SubjectKeyIdentifierExtension(java.lang.Boolean critical, java.lang.Object value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void encodeThis() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.KeyIdentifier get(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String IDENT = "x509.info.extensions.SubjectKeyIdentifier";
+
+    public static final java.lang.String KEY_ID = "key_id";
+
+    public static final java.lang.String NAME = "SubjectKeyIdentifier";
+
+    private sun.security.x509.KeyIdentifier id;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/URIName.java b/ojluni/annotations/hiddenapi/sun/security/x509/URIName.java
new file mode 100644
index 0000000..5030158
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/URIName.java
@@ -0,0 +1,108 @@
+/*
+ * 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 sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class URIName implements sun.security.x509.GeneralNameInterface {
+
+    public URIName(sun.security.util.DerValue derValue) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public URIName(java.lang.String name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    URIName(java.net.URI uri, java.lang.String host, sun.security.x509.DNSName hostDNS) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.URIName nameConstraint(sun.security.util.DerValue value)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.net.URI getURI() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getScheme() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getHost() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object getHostObject() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int constrains(sun.security.x509.GeneralNameInterface inputName)
+            throws java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int subtreeDepth() throws java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String host;
+
+    private sun.security.x509.DNSName hostDNS;
+
+    private sun.security.x509.IPAddressName hostIP;
+
+    private java.net.URI uri;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/UniqueIdentity.java b/ojluni/annotations/hiddenapi/sun/security/x509/UniqueIdentity.java
new file mode 100644
index 0000000..b43e762
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/UniqueIdentity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.x509;
+
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class UniqueIdentity {
+
+    public UniqueIdentity(sun.security.util.BitArray id) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public UniqueIdentity(byte[] id) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public UniqueIdentity(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public UniqueIdentity(sun.security.util.DerValue derVal) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out, byte tag) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.BitArray id;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java b/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java
new file mode 100644
index 0000000..4c697ab
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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 sun.security.x509;
+
+import java.lang.reflect.*;
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X500Name implements sun.security.x509.GeneralNameInterface, java.security.Principal {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(java.lang.String dname) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X500Name(
+            java.lang.String dname, java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(java.lang.String dname, java.lang.String format) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(
+            java.lang.String commonName,
+            java.lang.String organizationUnit,
+            java.lang.String organizationName,
+            java.lang.String country)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(
+            java.lang.String commonName,
+            java.lang.String organizationUnit,
+            java.lang.String organizationName,
+            java.lang.String localityName,
+            java.lang.String stateName,
+            java.lang.String country)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X500Name(sun.security.x509.RDN[] rdnArray) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(sun.security.util.DerValue value) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X500Name(byte[] name) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.List<sun.security.x509.RDN> rdns() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int size() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.util.List<sun.security.x509.AVA> allAvas() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int avaSize() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean isEmpty() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String getString(sun.security.util.DerValue attribute)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getType() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getCountry() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getOrganization() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getOrganizationalUnit() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getCommonName() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getLocality() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getState() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDomain() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDNQualifier() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSurname() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getGivenName() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getInitials() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getGeneration() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getIP() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRFC1779Name() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRFC1779Name(java.util.Map<java.lang.String, java.lang.String> oidMap)
+            throws java.lang.IllegalArgumentException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRFC2253Name() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRFC2253Name(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String generateRFC2253DN(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getRFC2253CanonicalName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.security.util.DerValue findAttribute(sun.security.util.ObjectIdentifier attribute) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.util.DerValue findMostSpecificAttribute(
+            sun.security.util.ObjectIdentifier attribute) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseDER(sun.security.util.DerInputStream in) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @Deprecated
+    public void emit(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncodedInternal() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseDN(
+            java.lang.String input, java.util.Map<java.lang.String, java.lang.String> keywordMap)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void checkNoNewLinesNorTabsAtBeginningOfDN(java.lang.String input) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parseRFC2253DN(java.lang.String dnString) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static int countQuotes(java.lang.String string, int from, int to) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static boolean escaped(int rdnEnd, int searchOffset, java.lang.String dnString) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void generateDN() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.String generateRFC1779DN(
+            java.util.Map<java.lang.String, java.lang.String> oidMap) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.security.util.ObjectIdentifier intern(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int constrains(sun.security.x509.GeneralNameInterface inputName)
+            throws java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean isWithinSubtree(sun.security.x509.X500Name other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int subtreeDepth() throws java.lang.UnsupportedOperationException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.X500Name commonAncestor(sun.security.x509.X500Name other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public javax.security.auth.x500.X500Principal asX500Principal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.security.x509.X500Name asX500Name(javax.security.auth.x500.X500Principal p) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final int[] DNQUALIFIER_DATA;
+
+    static {
+        DNQUALIFIER_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier DNQUALIFIER_OID;
+
+    static {
+        DNQUALIFIER_OID = null;
+    }
+
+    private static final int[] DOMAIN_COMPONENT_DATA;
+
+    static {
+        DOMAIN_COMPONENT_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier DOMAIN_COMPONENT_OID;
+
+    static {
+        DOMAIN_COMPONENT_OID = null;
+    }
+
+    private static final int[] GENERATIONQUALIFIER_DATA;
+
+    static {
+        GENERATIONQUALIFIER_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier GENERATIONQUALIFIER_OID;
+
+    static {
+        GENERATIONQUALIFIER_OID = null;
+    }
+
+    private static final int[] GIVENNAME_DATA;
+
+    static {
+        GIVENNAME_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier GIVENNAME_OID;
+
+    static {
+        GIVENNAME_OID = null;
+    }
+
+    private static final int[] INITIALS_DATA;
+
+    static {
+        INITIALS_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier INITIALS_OID;
+
+    static {
+        INITIALS_OID = null;
+    }
+
+    private static final int[] SERIALNUMBER_DATA;
+
+    static {
+        SERIALNUMBER_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SERIALNUMBER_OID;
+
+    static {
+        SERIALNUMBER_OID = null;
+    }
+
+    private static final int[] SURNAME_DATA;
+
+    static {
+        SURNAME_DATA = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier SURNAME_OID;
+
+    static {
+        SURNAME_OID = null;
+    }
+
+    private volatile java.util.List<sun.security.x509.AVA> allAvaList;
+
+    private java.lang.String canonicalDn;
+
+    private static final int[] commonName_data;
+
+    static {
+        commonName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier commonName_oid;
+
+    static {
+        commonName_oid = null;
+    }
+
+    private static final int[] countryName_data;
+
+    static {
+        countryName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier countryName_oid;
+
+    static {
+        countryName_oid = null;
+    }
+
+    private java.lang.String dn;
+
+    private byte[] encoded;
+
+    private static final java.util.Map<
+                    sun.security.util.ObjectIdentifier, sun.security.util.ObjectIdentifier>
+            internedOIDs;
+
+    static {
+        internedOIDs = null;
+    }
+
+    private static final int[] ipAddress_data;
+
+    static {
+        ipAddress_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier ipAddress_oid;
+
+    static {
+        ipAddress_oid = null;
+    }
+
+    private static final int[] localityName_data;
+
+    static {
+        localityName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier localityName_oid;
+
+    static {
+        localityName_oid = null;
+    }
+
+    private sun.security.x509.RDN[] names;
+
+    private static final int[] orgName_data;
+
+    static {
+        orgName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier orgName_oid;
+
+    static {
+        orgName_oid = null;
+    }
+
+    private static final int[] orgUnitName_data;
+
+    static {
+        orgUnitName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier orgUnitName_oid;
+
+    static {
+        orgUnitName_oid = null;
+    }
+
+    private static final java.lang.reflect.Constructor<javax.security.auth.x500.X500Principal>
+            principalConstructor;
+
+    static {
+        principalConstructor = null;
+    }
+
+    private static final java.lang.reflect.Field principalField;
+
+    static {
+        principalField = null;
+    }
+
+    private volatile java.util.List<sun.security.x509.RDN> rdnList;
+
+    private java.lang.String rfc1779Dn;
+
+    private java.lang.String rfc2253Dn;
+
+    private static final int[] stateName_data;
+
+    static {
+        stateName_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier stateName_oid;
+
+    static {
+        stateName_oid = null;
+    }
+
+    private static final int[] streetAddress_data;
+
+    static {
+        streetAddress_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier streetAddress_oid;
+
+    static {
+        streetAddress_oid = null;
+    }
+
+    private static final int[] title_data;
+
+    static {
+        title_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier title_oid;
+
+    static {
+        title_oid = null;
+    }
+
+    private static final int[] userid_data;
+
+    static {
+        userid_data = new int[0];
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final sun.security.util.ObjectIdentifier userid_oid;
+
+    static {
+        userid_oid = null;
+    }
+
+    private javax.security.auth.x500.X500Principal x500Principal;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLEntryImpl.java b/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLEntryImpl.java
new file mode 100644
index 0000000..066a4ad
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLEntryImpl.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CRLEntryImpl extends java.security.cert.X509CRLEntry
+        implements java.lang.Comparable<sun.security.x509.X509CRLEntryImpl> {
+
+    public X509CRLEntryImpl(java.math.BigInteger num, java.util.Date date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLEntryImpl(
+            java.math.BigInteger num,
+            java.util.Date date,
+            sun.security.x509.CRLExtensions crlEntryExts) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLEntryImpl(byte[] revokedCert) throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLEntryImpl(sun.security.util.DerValue derValue)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(sun.security.util.DerOutputStream outStrm)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private byte[] getEncoded0() throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public javax.security.auth.x500.X500Principal getCertificateIssuer() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setCertificateIssuer(
+            javax.security.auth.x500.X500Principal crlIssuer,
+            javax.security.auth.x500.X500Principal certIssuer) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getSerialNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getRevocationDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.CRLReason getRevocationReason() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.security.cert.CRLReason getRevocationReason(
+            java.security.cert.X509CRLEntry crlEntry) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Integer getReasonCode() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasUnsupportedCriticalExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getExtensionValue(java.lang.String oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.security.x509.Extension getExtension(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerValue derVal)
+            throws java.security.cert.CRLException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.X509CRLEntryImpl toImpl(java.security.cert.X509CRLEntry entry)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    sun.security.x509.CertificateIssuerExtension getCertificateIssuerExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Map<java.lang.String, java.security.cert.Extension> getExtensions() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int compareTo(sun.security.x509.X509CRLEntryImpl that) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long YR_2050 = 2524636800000L; // 0x24bd0146400L
+
+    private javax.security.auth.x500.X500Principal certIssuer;
+
+    private sun.security.x509.CRLExtensions extensions;
+
+    private static final boolean isExplicit = false;
+
+    private java.util.Date revocationDate;
+
+    private byte[] revokedCert;
+
+    private sun.security.x509.SerialNumber serialNumber;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLImpl.java b/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLImpl.java
new file mode 100644
index 0000000..7f353de
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X509CRLImpl.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CRLImpl extends java.security.cert.X509CRL
+        implements sun.security.util.DerEncoder {
+
+    private X509CRLImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CRLImpl(byte[] crlData) throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CRLImpl(sun.security.util.DerValue val) throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CRLImpl(java.io.InputStream inStrm) throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLImpl(
+            sun.security.x509.X500Name issuer, java.util.Date thisDate, java.util.Date nextDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLImpl(
+            sun.security.x509.X500Name issuer,
+            java.util.Date thisDate,
+            java.util.Date nextDate,
+            java.security.cert.X509CRLEntry[] badCerts)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CRLImpl(
+            sun.security.x509.X500Name issuer,
+            java.util.Date thisDate,
+            java.util.Date nextDate,
+            java.security.cert.X509CRLEntry[] badCerts,
+            sun.security.x509.CRLExtensions crlExts)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getEncodedInternal() throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encodeInfo(java.io.OutputStream out) throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void verify(java.security.PublicKey key)
+            throws java.security.cert.CRLException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void verify(java.security.PublicKey key, java.lang.String sigProvider)
+            throws java.security.cert.CRLException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void verify(java.security.PublicKey key, java.security.Provider sigProvider)
+            throws java.security.cert.CRLException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sign(java.security.PrivateKey key, java.lang.String algorithm)
+            throws java.security.cert.CRLException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sign(
+            java.security.PrivateKey key, java.lang.String algorithm, java.lang.String provider)
+            throws java.security.cert.CRLException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isRevoked(java.security.cert.Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Principal getIssuerDN() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public javax.security.auth.x500.X500Principal getIssuerX500Principal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getThisUpdate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getNextUpdate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509CRLEntry getRevokedCertificate(
+            java.math.BigInteger serialNumber) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.cert.X509CRLEntry getRevokedCertificate(
+            java.security.cert.X509Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.security.cert.X509CRLEntry> getRevokedCertificates() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getTBSCertList() throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getSignature() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSigAlgName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSigAlgOID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getSigAlgParams() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AlgorithmId getSigAlgId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.KeyIdentifier getAuthKeyId() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AuthorityKeyIdentifierExtension getAuthKeyIdExtension()
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.CRLNumberExtension getCRLNumberExtension() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getCRLNumber() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.DeltaCRLIndicatorExtension getDeltaCRLIndicatorExtension()
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getBaseCRLNumber() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.IssuerAlternativeNameExtension getIssuerAltNameExtension()
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.IssuingDistributionPointExtension
+            getIssuingDistributionPointExtension() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasUnsupportedCriticalExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getExtensionValue(java.lang.String oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object getExtension(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerValue val)
+            throws java.security.cert.CRLException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static javax.security.auth.x500.X500Principal getIssuerX500Principal(
+            java.security.cert.X509CRL crl) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] getEncodedInternal(java.security.cert.X509CRL crl)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.X509CRLImpl toImpl(java.security.cert.X509CRL crl)
+            throws java.security.cert.CRLException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private javax.security.auth.x500.X500Principal getCertIssuer(
+            sun.security.x509.X509CRLEntryImpl entry,
+            javax.security.auth.x500.X500Principal prevCertIssuer)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static final long YR_2050 = 2524636800000L; // 0x24bd0146400L
+
+    private sun.security.x509.CRLExtensions extensions;
+
+    private sun.security.x509.AlgorithmId infoSigAlgId;
+
+    private static final boolean isExplicit = true;
+
+    private sun.security.x509.X500Name issuer;
+
+    private javax.security.auth.x500.X500Principal issuerPrincipal;
+
+    private java.util.Date nextUpdate;
+
+    private boolean readOnly = false;
+
+    private java.util.List<java.security.cert.X509CRLEntry> revokedList;
+
+    private java.util.Map<
+                    sun.security.x509.X509CRLImpl.X509IssuerSerial, java.security.cert.X509CRLEntry>
+            revokedMap;
+
+    private sun.security.x509.AlgorithmId sigAlgId;
+
+    private byte[] signature;
+
+    private byte[] signedCRL;
+
+    private byte[] tbsCertList;
+
+    private java.util.Date thisUpdate;
+
+    private java.lang.String verifiedProvider;
+
+    private java.security.PublicKey verifiedPublicKey;
+
+    private int version;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    private static final class X509IssuerSerial
+            implements java.lang.Comparable<sun.security.x509.X509CRLImpl.X509IssuerSerial> {
+
+        X509IssuerSerial(
+                javax.security.auth.x500.X500Principal issuer, java.math.BigInteger serial) {
+            throw new RuntimeException("Stub!");
+        }
+
+        X509IssuerSerial(java.security.cert.X509Certificate cert) {
+            throw new RuntimeException("Stub!");
+        }
+
+        javax.security.auth.x500.X500Principal getIssuer() {
+            throw new RuntimeException("Stub!");
+        }
+
+        java.math.BigInteger getSerial() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public boolean equals(java.lang.Object o) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int hashCode() {
+            throw new RuntimeException("Stub!");
+        }
+
+        public int compareTo(sun.security.x509.X509CRLImpl.X509IssuerSerial another) {
+            throw new RuntimeException("Stub!");
+        }
+
+        volatile int hashcode = 0; // 0x0
+
+        final javax.security.auth.x500.X500Principal issuer;
+
+        {
+            issuer = null;
+        }
+
+        final java.math.BigInteger serial;
+
+        {
+            serial = null;
+        }
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X509CertImpl.java b/ojluni/annotations/hiddenapi/sun/security/x509/X509CertImpl.java
new file mode 100644
index 0000000..9333689
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X509CertImpl.java
@@ -0,0 +1,490 @@
+/*
+ * 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 sun.security.x509;
+
+import java.security.*;
+import java.security.cert.*;
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CertImpl extends java.security.cert.X509Certificate
+        implements sun.security.util.DerEncoder {
+
+    public X509CertImpl() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertImpl(byte[] certData) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertImpl(sun.security.x509.X509CertInfo certInfo) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertImpl(sun.security.util.DerValue derVal)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CertImpl(sun.security.util.DerValue derVal, byte[] encoded)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out)
+            throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void derEncode(java.io.OutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public byte[] getEncodedInternal() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void verify(java.security.PublicKey key)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void verify(java.security.PublicKey key, java.lang.String sigProvider)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized void verify(java.security.PublicKey key, java.security.Provider sigProvider)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static void verify(
+            java.security.cert.X509Certificate cert,
+            java.security.PublicKey key,
+            java.security.Provider sigProvider)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void sign(java.security.PrivateKey key, java.lang.String algorithm)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void sign(
+            java.security.PrivateKey key, java.lang.String algorithm, java.lang.String provider)
+            throws java.security.cert.CertificateException, java.security.InvalidKeyException,
+                    java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
+                    java.security.SignatureException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void checkValidity()
+            throws java.security.cert.CertificateExpiredException,
+                    java.security.cert.CertificateNotYetValidException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void checkValidity(java.util.Date date)
+            throws java.security.cert.CertificateExpiredException,
+                    java.security.cert.CertificateNotYetValidException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Object get(java.lang.String name)
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void set(java.lang.String name, java.lang.Object obj)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.PublicKey getPublicKey() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getVersion() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.math.BigInteger getSerialNumber() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.SerialNumber getSerialNumberObject() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Principal getSubjectDN() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public javax.security.auth.x500.X500Principal getSubjectX500Principal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.security.Principal getIssuerDN() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public javax.security.auth.x500.X500Principal getIssuerX500Principal() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getNotBefore() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Date getNotAfter() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getTBSCertificate() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getSignature() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSigAlgName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getSigAlgOID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getSigAlgParams() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getIssuerUniqueID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getSubjectUniqueID() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.KeyIdentifier getAuthKeyId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.KeyIdentifier getSubjectKeyId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AuthorityKeyIdentifierExtension getAuthorityKeyIdentifierExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.BasicConstraintsExtension getBasicConstraintsExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.CertificatePoliciesExtension getCertificatePoliciesExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.ExtendedKeyUsageExtension getExtendedKeyUsageExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.IssuerAlternativeNameExtension getIssuerAlternativeNameExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.NameConstraintsExtension getNameConstraintsExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.PolicyConstraintsExtension getPolicyConstraintsExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.PolicyMappingsExtension getPolicyMappingsExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.PrivateKeyUsageExtension getPrivateKeyUsageExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.SubjectAlternativeNameExtension getSubjectAlternativeNameExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.SubjectKeyIdentifierExtension getSubjectKeyIdentifierExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.CRLDistributionPointsExtension getCRLDistributionPointsExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean hasUnsupportedCriticalExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.Extension getExtension(sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.Extension getUnparseableExtension(
+            sun.security.util.ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getExtensionValue(java.lang.String oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean[] getKeyUsage() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.List<java.lang.String> getExtendedKeyUsage()
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.List<java.lang.String> getExtendedKeyUsage(
+            java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getBasicConstraints() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Collection<java.util.List<?>> makeAltNames(
+            sun.security.x509.GeneralNames names) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static java.util.Collection<java.util.List<?>> cloneAltNames(
+            java.util.Collection<java.util.List<?>> altNames) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Collection<java.util.List<?>> getSubjectAlternativeNames()
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Collection<java.util.List<?>> getSubjectAlternativeNames(
+            java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public synchronized java.util.Collection<java.util.List<?>> getIssuerAlternativeNames()
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Collection<java.util.List<?>> getIssuerAlternativeNames(
+            java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AuthorityInfoAccessExtension getAuthorityInfoAccessExtension() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void parse(sun.security.util.DerValue val)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerValue val, byte[] originalEncodedForm)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static javax.security.auth.x500.X500Principal getX500Principal(
+            java.security.cert.X509Certificate cert, boolean getIssuer) throws java.lang.Exception {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static javax.security.auth.x500.X500Principal getSubjectX500Principal(
+            java.security.cert.X509Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static javax.security.auth.x500.X500Principal getIssuerX500Principal(
+            java.security.cert.X509Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static byte[] getEncodedInternal(java.security.cert.Certificate cert)
+            throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static sun.security.x509.X509CertImpl toImpl(java.security.cert.X509Certificate cert)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isSelfIssued(java.security.cert.X509Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static boolean isSelfSigned(
+            java.security.cert.X509Certificate cert, java.lang.String sigProvider) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.lang.String getFingerprint(
+            java.lang.String algorithm, java.security.cert.X509Certificate cert) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private static void byte2hex(byte b, java.lang.StringBuffer buf) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String ALG_ID = "algorithm";
+
+    private static final java.lang.String AUTH_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.1";
+
+    private static final java.lang.String BASIC_CONSTRAINT_OID = "2.5.29.19";
+
+    private static final java.lang.String DOT = ".";
+
+    private static final java.lang.String EXTENDED_KEY_USAGE_OID = "2.5.29.37";
+
+    public static final java.lang.String INFO = "info";
+
+    private static final java.lang.String ISSUER_ALT_NAME_OID = "2.5.29.18";
+
+    public static final java.lang.String ISSUER_DN = "x509.info.issuer.dname";
+
+    private static final java.lang.String KEY_USAGE_OID = "2.5.29.15";
+
+    public static final java.lang.String NAME = "x509";
+
+    private static final int NUM_STANDARD_KEY_USAGE = 9; // 0x9
+
+    public static final java.lang.String PUBLIC_KEY = "x509.info.key.value";
+
+    public static final java.lang.String SERIAL_ID = "x509.info.serialNumber.number";
+
+    public static final java.lang.String SIG = "x509.signature";
+
+    public static final java.lang.String SIGNATURE = "signature";
+
+    public static final java.lang.String SIGNED_CERT = "signed_cert";
+
+    public static final java.lang.String SIG_ALG = "x509.algorithm";
+
+    private static final java.lang.String SUBJECT_ALT_NAME_OID = "2.5.29.17";
+
+    public static final java.lang.String SUBJECT_DN = "x509.info.subject.dname";
+
+    public static final java.lang.String VERSION = "x509.info.version.number";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected sun.security.x509.AlgorithmId algId;
+
+    private java.util.Set<sun.security.x509.AccessDescription> authInfoAccess;
+
+    private java.util.List<java.lang.String> extKeyUsage;
+
+    private java.util.concurrent.ConcurrentHashMap<java.lang.String, java.lang.String> fingerprints;
+
+    protected sun.security.x509.X509CertInfo info;
+
+    private java.util.Collection<java.util.List<?>> issuerAlternativeNames;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private boolean readOnly = false;
+
+    private static final long serialVersionUID = -3457612960190864406L; // 0xd0041754f90963eaL
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected byte[] signature;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage private byte[] signedCert;
+
+    private java.util.Collection<java.util.List<?>> subjectAlternativeNames;
+
+    private boolean verificationResult;
+
+    private java.lang.String verifiedProvider;
+
+    private java.security.PublicKey verifiedPublicKey;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X509CertInfo.java b/ojluni/annotations/hiddenapi/sun/security/x509/X509CertInfo.java
new file mode 100644
index 0000000..21b4d61
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X509CertInfo.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1997, 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 sun.security.x509;
+
+import java.security.cert.*;
+import java.util.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509CertInfo implements sun.security.x509.CertAttrSet<java.lang.String> {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertInfo() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509CertInfo(byte[] cert) throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public X509CertInfo(sun.security.util.DerValue derVal)
+            throws java.security.cert.CertificateParsingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void encode(java.io.OutputStream out)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.Enumeration<java.lang.String> getElements() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncodedInfo() throws java.security.cert.CertificateEncodingException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(sun.security.x509.X509CertInfo other) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public void set(java.lang.String name, java.lang.Object val)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void delete(java.lang.String name)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.Object get(java.lang.String name)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private java.lang.Object getX500Name(java.lang.String name, boolean getIssuer)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void parse(sun.security.util.DerValue val)
+            throws java.security.cert.CertificateParsingException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void verifyCert(
+            sun.security.x509.X500Name subject, sun.security.x509.CertificateExtensions extensions)
+            throws java.security.cert.CertificateParsingException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void emit(sun.security.util.DerOutputStream out)
+            throws java.security.cert.CertificateException, java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int attributeMap(java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setVersion(java.lang.Object val) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setSerialNumber(java.lang.Object val)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setAlgorithmId(java.lang.Object val)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setIssuer(java.lang.Object val) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setValidity(java.lang.Object val) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setSubject(java.lang.Object val) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setKey(java.lang.Object val) throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setIssuerUniqueId(java.lang.Object val)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setSubjectUniqueId(java.lang.Object val)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void setExtensions(java.lang.Object val)
+            throws java.security.cert.CertificateException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.String ALGORITHM_ID = "algorithmID";
+
+    private static final int ATTR_ALGORITHM = 3; // 0x3
+
+    private static final int ATTR_EXTENSIONS = 10; // 0xa
+
+    private static final int ATTR_ISSUER = 4; // 0x4
+
+    private static final int ATTR_ISSUER_ID = 8; // 0x8
+
+    private static final int ATTR_KEY = 7; // 0x7
+
+    private static final int ATTR_SERIAL = 2; // 0x2
+
+    private static final int ATTR_SUBJECT = 6; // 0x6
+
+    private static final int ATTR_SUBJECT_ID = 9; // 0x9
+
+    private static final int ATTR_VALIDITY = 5; // 0x5
+
+    private static final int ATTR_VERSION = 1; // 0x1
+
+    public static final java.lang.String DN_NAME = "dname";
+
+    public static final java.lang.String EXTENSIONS = "extensions";
+
+    public static final java.lang.String IDENT = "x509.info";
+
+    public static final java.lang.String ISSUER = "issuer";
+
+    public static final java.lang.String ISSUER_ID = "issuerID";
+
+    public static final java.lang.String KEY = "key";
+
+    public static final java.lang.String NAME = "info";
+
+    public static final java.lang.String SERIAL_NUMBER = "serialNumber";
+
+    public static final java.lang.String SUBJECT = "subject";
+
+    public static final java.lang.String SUBJECT_ID = "subjectID";
+
+    public static final java.lang.String VALIDITY = "validity";
+
+    public static final java.lang.String VERSION = "version";
+
+    protected sun.security.x509.CertificateAlgorithmId algId;
+
+    protected sun.security.x509.CertificateExtensions extensions;
+
+    protected sun.security.x509.CertificateValidity interval;
+
+    protected sun.security.x509.X500Name issuer;
+
+    protected sun.security.x509.UniqueIdentity issuerUniqueId;
+
+    private static final java.util.Map<java.lang.String, java.lang.Integer> map;
+
+    static {
+        map = null;
+    }
+
+    protected sun.security.x509.CertificateX509Key pubKey;
+
+    private byte[] rawCertInfo;
+
+    protected sun.security.x509.CertificateSerialNumber serialNum;
+
+    protected sun.security.x509.X500Name subject;
+
+    protected sun.security.x509.UniqueIdentity subjectUniqueId;
+
+    protected sun.security.x509.CertificateVersion version;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X509Key.java b/ojluni/annotations/hiddenapi/sun/security/x509/X509Key.java
new file mode 100644
index 0000000..2a830d7
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X509Key.java
@@ -0,0 +1,143 @@
+/*
+ * 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 sun.security.x509;
+
+import java.io.*;
+import sun.security.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class X509Key implements java.security.PublicKey {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public X509Key() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private X509Key(sun.security.x509.AlgorithmId algid, sun.security.util.BitArray key)
+            throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setKey(sun.security.util.BitArray key) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected sun.security.util.BitArray getKey() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static java.security.PublicKey parse(sun.security.util.DerValue in)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void parseKeyBits() throws java.io.IOException, java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    static java.security.PublicKey buildX509Key(
+            sun.security.x509.AlgorithmId algid, sun.security.util.BitArray key)
+            throws java.io.IOException, java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getAlgorithm() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.security.x509.AlgorithmId getAlgorithmId() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public final void encode(sun.security.util.DerOutputStream out) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncoded() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] getEncodedInternal() throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getFormat() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public byte[] encode() throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void decode(java.io.InputStream in) throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void decode(byte[] encodedKey) throws java.security.InvalidKeyException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    static void encode(
+            sun.security.util.DerOutputStream out,
+            sun.security.x509.AlgorithmId algid,
+            sun.security.util.BitArray key)
+            throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected sun.security.x509.AlgorithmId algid;
+
+    private sun.security.util.BitArray bitStringKey;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage protected byte[] encodedKey;
+
+    @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage protected byte[] key;
+
+    private static final long serialVersionUID = -5359250853002055002L; // 0xb5a01dbe649a72a6L
+
+    @Deprecated @dalvik.annotation.compat.UnsupportedAppUsage private int unusedBits = 0; // 0x0
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java
new file mode 100644
index 0000000..dd8fd2b
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class AbstractCalendar extends sun.util.calendar.CalendarSystem {
+
+    protected AbstractCalendar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.Era getEra(java.lang.String eraName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.Era[] getEras() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setEra(sun.util.calendar.CalendarDate date, java.lang.String eraName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setEras(sun.util.calendar.Era[] eras) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate getCalendarDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate getCalendarDate(long millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate getCalendarDate(long millis, java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate getCalendarDate(
+            long millis, sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTime(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected long getTimeOfDay(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public long getTimeOfDayValue(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setTimeOfDay(
+            sun.util.calendar.CalendarDate cdate, int fraction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getWeekLength() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract boolean isLeapYear(sun.util.calendar.CalendarDate date);
+
+    public sun.util.calendar.CalendarDate getNthDayOfWeek(
+            int nth, int dayOfWeek, sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static long getDayOfWeekDateBefore(long fixedDate, int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static long getDayOfWeekDateAfter(long fixedDate, int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static long getDayOfWeekDateOnOrBefore(long fixedDate, int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected abstract long getFixedDate(sun.util.calendar.CalendarDate date);
+
+    protected abstract void getCalendarDateFromFixedDate(
+            sun.util.calendar.CalendarDate date, long fixedDate);
+
+    public boolean validateTime(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    int normalizeTime(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int DAY_IN_MILLIS = 86400000; // 0x5265c00
+
+    static final int EPOCH_OFFSET = 719163; // 0xaf93b
+
+    static final int HOUR_IN_MILLIS = 3600000; // 0x36ee80
+
+    static final int MINUTE_IN_MILLIS = 60000; // 0xea60
+
+    static final int SECOND_IN_MILLIS = 1000; // 0x3e8
+
+    private sun.util.calendar.Era[] eras;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java
new file mode 100644
index 0000000..8c8f122
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java
@@ -0,0 +1,220 @@
+/*
+ * 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 sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class BaseCalendar extends sun.util.calendar.AbstractCalendar {
+
+    public BaseCalendar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean validate(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean normalize(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void normalizeMonth(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getYearLength(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getYearLengthInMonths(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMonthLength(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private int getMonthLength(int year, int month) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getDayOfYear(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final long getDayOfYear(int year, int month, int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getFixedDate(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getFixedDate(
+            int year, int month, int dayOfMonth, sun.util.calendar.BaseCalendar.Date cache) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void getCalendarDateFromFixedDate(sun.util.calendar.CalendarDate date, long fixedDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfWeek(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int getDayOfWeekFromFixedDate(long fixedDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getYearFromFixedDate(long fixedDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    final int getGregorianYearFromFixedDate(long fixedDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected boolean isLeapYear(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    boolean isLeapYear(int normalizedYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static final int[] ACCUMULATED_DAYS_IN_MONTH;
+
+    static {
+        ACCUMULATED_DAYS_IN_MONTH = new int[0];
+    }
+
+    static final int[] ACCUMULATED_DAYS_IN_MONTH_LEAP;
+
+    static {
+        ACCUMULATED_DAYS_IN_MONTH_LEAP = new int[0];
+    }
+
+    public static final int APRIL = 4; // 0x4
+
+    public static final int AUGUST = 8; // 0x8
+
+    private static final int BASE_YEAR = 1970; // 0x7b2
+
+    static final int[] DAYS_IN_MONTH;
+
+    static {
+        DAYS_IN_MONTH = new int[0];
+    }
+
+    public static final int DECEMBER = 12; // 0xc
+
+    public static final int FEBRUARY = 2; // 0x2
+
+    private static final int[] FIXED_DATES;
+
+    static {
+        FIXED_DATES = new int[0];
+    }
+
+    public static final int FRIDAY = 6; // 0x6
+
+    public static final int JANUARY = 1; // 0x1
+
+    public static final int JULY = 7; // 0x7
+
+    public static final int JUNE = 6; // 0x6
+
+    public static final int MARCH = 3; // 0x3
+
+    public static final int MAY = 5; // 0x5
+
+    public static final int MONDAY = 2; // 0x2
+
+    public static final int NOVEMBER = 11; // 0xb
+
+    public static final int OCTOBER = 10; // 0xa
+
+    public static final int SATURDAY = 7; // 0x7
+
+    public static final int SEPTEMBER = 9; // 0x9
+
+    public static final int SUNDAY = 1; // 0x1
+
+    public static final int THURSDAY = 5; // 0x5
+
+    public static final int TUESDAY = 3; // 0x3
+
+    public static final int WEDNESDAY = 4; // 0x4
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public abstract static class Date extends sun.util.calendar.CalendarDate {
+
+        protected Date() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected Date(java.util.TimeZone zone) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public sun.util.calendar.BaseCalendar.Date setNormalizedDate(
+                int normalizedYear, int month, int dayOfMonth) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public abstract int getNormalizedYear();
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public abstract void setNormalizedYear(int normalizedYear);
+
+        protected final boolean hit(int year) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected final boolean hit(long fixedDate) {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected int getCachedYear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected long getCachedJan1() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected void setCache(int year, long jan1, int len) {
+            throw new RuntimeException("Stub!");
+        }
+
+        long cachedFixedDateJan1 = 731581L; // 0xb29bdL
+
+        long cachedFixedDateNextJan1;
+
+        int cachedYear = 2004; // 0x7d4
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java
new file mode 100644
index 0000000..f63c574
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2000, 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 sun.util.calendar;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CalendarDate implements java.lang.Cloneable {
+
+    protected CalendarDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected CalendarDate(java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.Era getEra() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setEra(sun.util.calendar.Era era) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int getYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setYear(int year) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addYear(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLeapYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setLeapYear(boolean leapYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int getMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setMonth(int month) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMonth(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public int getDayOfMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setDayOfMonth(int date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addDayOfMonth(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfWeek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getHours() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setHours(int hours) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addHours(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinutes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setMinutes(int minutes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMinutes(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getSeconds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setSeconds(int seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addSeconds(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMillis() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setMillis(int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMillis(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public long getTimeOfDay() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate setDate(int year, int month, int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addDate(int year, int month, int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setTimeOfDay(
+            int hours, int minutes, int seconds, int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addTimeOfDay(
+            int hours, int minutes, int seconds, int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setTimeOfDay(long fraction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isNormalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isStandardTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setStandardTime(boolean standardTime) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isDaylightTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setLocale(java.util.Locale loc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.TimeZone getZone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setZone(java.util.TimeZone zoneinfo) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSameDate(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setDayOfWeek(int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setNormalized(boolean normalized) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getZoneOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setZoneOffset(int offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDaylightSaving() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setDaylightSaving(int daylightSaving) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int FIELD_UNDEFINED = -2147483648; // 0x80000000
+
+    public static final long TIME_UNDEFINED = -9223372036854775808L; // 0x8000000000000000L
+
+    private int dayOfMonth;
+
+    private int dayOfWeek = -2147483648; // 0x80000000
+
+    private int daylightSaving;
+
+    private sun.util.calendar.Era era;
+
+    private boolean forceStandardTime;
+
+    private long fraction;
+
+    private int hours;
+
+    private boolean leapYear;
+
+    private java.util.Locale locale;
+
+    private int millis;
+
+    private int minutes;
+
+    private int month;
+
+    private boolean normalized;
+
+    private int seconds;
+
+    private int year;
+
+    private int zoneOffset;
+
+    private java.util.TimeZone zoneinfo;
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java
new file mode 100644
index 0000000..bddd682
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.calendar;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CalendarSystem {
+
+    public CalendarSystem() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.util.calendar.Gregorian getGregorianCalendar() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static sun.util.calendar.CalendarSystem forName(java.lang.String calendarName) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static java.util.Properties getCalendarProperties() throws java.io.IOException {
+        throw new RuntimeException("Stub!");
+    }
+
+    public abstract java.lang.String getName();
+
+    public abstract sun.util.calendar.CalendarDate getCalendarDate();
+
+    public abstract sun.util.calendar.CalendarDate getCalendarDate(long millis);
+
+    public abstract sun.util.calendar.CalendarDate getCalendarDate(
+            long millis, sun.util.calendar.CalendarDate date);
+
+    public abstract sun.util.calendar.CalendarDate getCalendarDate(
+            long millis, java.util.TimeZone zone);
+
+    public abstract sun.util.calendar.CalendarDate newCalendarDate();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract sun.util.calendar.CalendarDate newCalendarDate(java.util.TimeZone zone);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract long getTime(sun.util.calendar.CalendarDate date);
+
+    public abstract int getYearLength(sun.util.calendar.CalendarDate date);
+
+    public abstract int getYearLengthInMonths(sun.util.calendar.CalendarDate date);
+
+    public abstract int getMonthLength(sun.util.calendar.CalendarDate date);
+
+    public abstract int getWeekLength();
+
+    public abstract sun.util.calendar.Era getEra(java.lang.String eraName);
+
+    public abstract sun.util.calendar.Era[] getEras();
+
+    public abstract void setEra(sun.util.calendar.CalendarDate date, java.lang.String eraName);
+
+    public abstract sun.util.calendar.CalendarDate getNthDayOfWeek(
+            int nth, int dayOfWeek, sun.util.calendar.CalendarDate date);
+
+    public abstract sun.util.calendar.CalendarDate setTimeOfDay(
+            sun.util.calendar.CalendarDate date, int timeOfDay);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public abstract boolean validate(sun.util.calendar.CalendarDate date);
+
+    public abstract boolean normalize(sun.util.calendar.CalendarDate date);
+
+    private static final sun.util.calendar.Gregorian GREGORIAN_INSTANCE;
+
+    static {
+        GREGORIAN_INSTANCE = null;
+    }
+
+    private static final java.util.concurrent.ConcurrentMap<
+                    java.lang.String, sun.util.calendar.CalendarSystem>
+            calendars;
+
+    static {
+        calendars = null;
+    }
+
+    private static final java.util.Map<java.lang.String, java.lang.Class<?>> names;
+
+    static {
+        names = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java
new file mode 100644
index 0000000..9ecd8dc
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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.
+ */
+
+package sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CalendarUtils {
+
+    public CalendarUtils() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final boolean isGregorianLeapYear(int gregorianYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final boolean isJulianLeapYear(int normalizedJulianYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final long floorDivide(long n, long d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final int floorDivide(int n, int d) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int floorDivide(int n, int d, int[] r) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int floorDivide(long n, int d, int[] r) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final long mod(long x, long y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static final int mod(int x, int y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final int amod(int x, int y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final long amod(long x, long y) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.StringBuilder sprintf0d(
+            java.lang.StringBuilder sb, int value, int width) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public static final java.lang.StringBuffer sprintf0d(
+            java.lang.StringBuffer sb, int value, int width) {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java b/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java
new file mode 100644
index 0000000..28e5095
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Era {
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public Era(java.lang.String name, java.lang.String abbr, long since, boolean localTime) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDisplayName(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public java.lang.String getAbbreviation() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getDiaplayAbbreviation(java.util.Locale locale) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getSince(java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.CalendarDate getSinceDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLocalTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object o) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final java.lang.String abbr;
+
+    {
+        abbr = null;
+    }
+
+    private int hash = 0; // 0x0
+
+    private final boolean localTime;
+
+    {
+        localTime = false;
+    }
+
+    private final java.lang.String name;
+
+    {
+        name = null;
+    }
+
+    private final long since;
+
+    {
+        since = 0;
+    }
+
+    private final sun.util.calendar.CalendarDate sinceDate;
+
+    {
+        sinceDate = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java b/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java
new file mode 100644
index 0000000..825e9d6
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+class ImmutableGregorianDate extends sun.util.calendar.BaseCalendar.Date {
+
+    ImmutableGregorianDate(sun.util.calendar.BaseCalendar.Date date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.Era getEra() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setEra(sun.util.calendar.Era era) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setYear(int year) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addYear(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLeapYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    void setLeapYear(boolean leapYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setMonth(int month) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMonth(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfMonth() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setDayOfMonth(int date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addDayOfMonth(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDayOfWeek() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getHours() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setHours(int hours) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addHours(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMinutes() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setMinutes(int minutes) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMinutes(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getSeconds() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setSeconds(int seconds) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addSeconds(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getMillis() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setMillis(int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addMillis(int n) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public long getTimeOfDay() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setDate(int year, int month, int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addDate(int year, int month, int dayOfMonth) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setTimeOfDay(
+            int hours, int minutes, int seconds, int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate addTimeOfDay(
+            int hours, int minutes, int seconds, int millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setTimeOfDay(long fraction) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isNormalized() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isStandardTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setStandardTime(boolean standardTime) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isDaylightTime() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setLocale(java.util.Locale loc) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.util.TimeZone getZone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.CalendarDate setZone(java.util.TimeZone zoneinfo) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isSameDate(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean equals(java.lang.Object obj) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int hashCode() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.Object clone() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String toString() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setDayOfWeek(int dayOfWeek) {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setNormalized(boolean normalized) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getZoneOffset() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setZoneOffset(int offset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getDaylightSaving() {
+        throw new RuntimeException("Stub!");
+    }
+
+    protected void setDaylightSaving(int daylightSaving) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public int getNormalizedYear() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void setNormalizedYear(int normalizedYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private void unsupported() {
+        throw new RuntimeException("Stub!");
+    }
+
+    private final sun.util.calendar.BaseCalendar.Date date;
+
+    {
+        date = null;
+    }
+}
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java
new file mode 100644
index 0000000..95267d0
--- /dev/null
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2005, 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 sun.util.calendar;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LocalGregorianCalendar extends sun.util.calendar.BaseCalendar {
+
+    private LocalGregorianCalendar(java.lang.String name, sun.util.calendar.Era[] eras) {
+        throw new RuntimeException("Stub!");
+    }
+
+    static sun.util.calendar.LocalGregorianCalendar getLocalGregorianCalendar(
+            java.lang.String name) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public java.lang.String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.LocalGregorianCalendar.Date getCalendarDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.LocalGregorianCalendar.Date getCalendarDate(long millis) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.LocalGregorianCalendar.Date getCalendarDate(
+            long millis, java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.LocalGregorianCalendar.Date getCalendarDate(
+            long millis, sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.util.calendar.LocalGregorianCalendar.Date adjustYear(
+            sun.util.calendar.LocalGregorianCalendar.Date ldate, long millis, int zoneOffset) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public sun.util.calendar.LocalGregorianCalendar.Date newCalendarDate() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public sun.util.calendar.LocalGregorianCalendar.Date newCalendarDate(java.util.TimeZone zone) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean validate(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private boolean validateEra(sun.util.calendar.Era era) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public boolean normalize(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void normalizeMonth(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    void normalizeYear(sun.util.calendar.CalendarDate date) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLeapYear(int gregorianYear) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public boolean isLeapYear(sun.util.calendar.Era era, int year) {
+        throw new RuntimeException("Stub!");
+    }
+
+    public void getCalendarDateFromFixedDate(sun.util.calendar.CalendarDate date, long fixedDate) {
+        throw new RuntimeException("Stub!");
+    }
+
+    private sun.util.calendar.Era[] eras;
+
+    private java.lang.String name;
+
+    @SuppressWarnings({"unchecked", "deprecation", "all"})
+    public static class Date extends sun.util.calendar.BaseCalendar.Date {
+
+        protected Date() {
+            throw new RuntimeException("Stub!");
+        }
+
+        protected Date(java.util.TimeZone zone) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public sun.util.calendar.LocalGregorianCalendar.Date setEra(sun.util.calendar.Era era) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public sun.util.calendar.LocalGregorianCalendar.Date addYear(int localYear) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public sun.util.calendar.LocalGregorianCalendar.Date setYear(int localYear) {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public int getNormalizedYear() {
+            throw new RuntimeException("Stub!");
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        public void setNormalizedYear(int normalizedYear) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setLocalEra(sun.util.calendar.Era era) {
+            throw new RuntimeException("Stub!");
+        }
+
+        void setLocalYear(int year) {
+            throw new RuntimeException("Stub!");
+        }
+
+        public java.lang.String toString() {
+            throw new RuntimeException("Stub!");
+        }
+
+        private int gregorianYear = -2147483648; // 0x80000000
+    }
+}
diff --git a/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java b/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java
new file mode 100644
index 0000000..89006c1
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1995, 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.io;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class FileDescriptor {
+
+public FileDescriptor() { throw new RuntimeException("Stub!"); }
+
+public boolean valid() { throw new RuntimeException("Stub!"); }
+
+public native void sync() throws java.io.SyncFailedException;
+
+@libcore.api.CorePlatformApi
+public int getInt$() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public void setInt$(int fd) { throw new RuntimeException("Stub!"); }
+
+public long getOwnerId$() { throw new RuntimeException("Stub!"); }
+
+public void setOwnerId$(long newOwnerId) { throw new RuntimeException("Stub!"); }
+
+public java.io.FileDescriptor release$() { throw new RuntimeException("Stub!"); }
+
+public boolean isSocket$() { throw new RuntimeException("Stub!"); }
+
+public static final long NO_OWNER = 0L; // 0x0L
+
+public static final java.io.FileDescriptor err;
+static { err = null; }
+
+public static final java.io.FileDescriptor in;
+static { in = null; }
+
+public static final java.io.FileDescriptor out;
+static { out = null; }
+}
+
diff --git a/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java b/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java
new file mode 100644
index 0000000..11013ac
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java
@@ -0,0 +1,62 @@
+/*
+ * 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.io;
+
+import java.nio.channels.FileChannel;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class FileInputStream extends java.io.InputStream {
+
+public FileInputStream(java.lang.String name) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public FileInputStream(java.io.File file) throws java.io.FileNotFoundException { throw new RuntimeException("Stub!"); }
+
+public FileInputStream(java.io.FileDescriptor fdObj) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public FileInputStream(java.io.FileDescriptor fdObj, boolean isFdOwner) { throw new RuntimeException("Stub!"); }
+
+public int read() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public int read(byte[] b) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public int read(byte[] b, int off, int len) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public long skip(long n) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public int available() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public final java.io.FileDescriptor getFD() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.FileChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+protected void finalize() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/lang/Byte.annotated.java b/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
new file mode 100644
index 0000000..2d61598
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
@@ -0,0 +1,93 @@
+/*
+ * 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(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Byte valueOf(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Byte valueOf(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Byte decode(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!"); }
+
+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(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(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!"); }
+
+@libcore.api.CorePlatformApi
+public static java.lang.String toHexString(byte b, boolean upperCase) { 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/annotations/mmodule/java/lang/Class.annotated.java b/ojluni/annotations/mmodule/java/lang/Class.annotated.java
new file mode 100644
index 0000000..fd80abb
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/lang/Class.annotated.java
@@ -0,0 +1,189 @@
+/*
+ * 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!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String className) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String name, boolean initialize, java.lang.ClassLoader loader) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public native T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+public boolean isInstance(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isAssignableFrom(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 isFinalizable() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotation() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getClassLoader() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<? super T> getSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type getGenericSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.lang.String getPackageName$() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?>[] getInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?> getComponentType() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object[] getSigners() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getEnclosingMethod() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?> getEnclosingConstructor() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?> getDeclaringClass();
+
+public native java.lang.Class<?> getEnclosingClass();
+
+public java.lang.String getSimpleName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+
+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.Class<?>[] getClasses() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field getField(java.lang.String name) throws java.lang.NoSuchFieldException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getDeclaredClasses();
+
+public native java.lang.reflect.Field[] getDeclaredFields();
+
+@libcore.api.CorePlatformApi
+public native java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public native java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.reflect.Field getDeclaredField(java.lang.String name) throws java.lang.NoSuchFieldException;
+
+public java.lang.reflect.Method getDeclaredMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getInstanceMethod(java.lang.String name, java.lang.Class<?>[] parameterTypes) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getDeclaredConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.io.InputStream getResourceAsStream(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.net.URL getResource(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!"); }
+
+public T[] getEnumConstants() { throw new RuntimeException("Stub!"); }
+
+public T[] getEnumConstantsShared() { throw new RuntimeException("Stub!"); }
+
+public T cast(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public <U> java.lang.Class<? extends U> asSubclass(java.lang.Class<U> clazz) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public native <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(java.lang.Class<A> annotationClass);
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+
+public boolean isProxy() { throw new RuntimeException("Stub!"); }
+
+public int getAccessFlags() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/lang/Math.annotated.java b/ojluni/annotations/mmodule/java/lang/Math.annotated.java
new file mode 100644
index 0000000..46fae4e
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/lang/Math.annotated.java
@@ -0,0 +1,190 @@
+/*
+ * 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.util.Random;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Math {
+
+Math() { throw new RuntimeException("Stub!"); }
+
+public static native double sin(double a);
+
+public static native double cos(double a);
+
+public static native double tan(double a);
+
+public static native double asin(double a);
+
+public static native double acos(double a);
+
+public static native double atan(double a);
+
+public static double toRadians(double angdeg) { throw new RuntimeException("Stub!"); }
+
+public static double toDegrees(double angrad) { throw new RuntimeException("Stub!"); }
+
+public static native double exp(double a);
+
+public static native double log(double a);
+
+public static native double log10(double a);
+
+public static native double sqrt(double a);
+
+public static native double cbrt(double a);
+
+public static native double IEEEremainder(double f1, double f2);
+
+public static native double ceil(double a);
+
+public static native double floor(double a);
+
+public static native double rint(double a);
+
+public static native double atan2(double y, double x);
+
+public static native double pow(double a, double b);
+
+public static int round(float a) { throw new RuntimeException("Stub!"); }
+
+public static long round(double a) { throw new RuntimeException("Stub!"); }
+
+public static double random() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static long randomLongInternal() { throw new RuntimeException("Stub!"); }
+
+public static int addExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long addExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int subtractExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long subtractExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int multiplyExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long multiplyExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int incrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long incrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int decrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long decrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int negateExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long negateExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int toIntExact(long value) { throw new RuntimeException("Stub!"); }
+
+public static int floorDiv(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorDiv(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int floorMod(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorMod(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int abs(int a) { throw new RuntimeException("Stub!"); }
+
+public static long abs(long a) { throw new RuntimeException("Stub!"); }
+
+public static float abs(float a) { throw new RuntimeException("Stub!"); }
+
+public static double abs(double a) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double ulp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float ulp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double signum(double d) { throw new RuntimeException("Stub!"); }
+
+public static float signum(float f) { throw new RuntimeException("Stub!"); }
+
+public static native double sinh(double x);
+
+public static native double cosh(double x);
+
+public static native double tanh(double x);
+
+public static native double hypot(double x, double y);
+
+public static native double expm1(double x);
+
+public static native double log1p(double x);
+
+public static double copySign(double magnitude, double sign) { throw new RuntimeException("Stub!"); }
+
+public static float copySign(float magnitude, float sign) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(float f) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(double d) { throw new RuntimeException("Stub!"); }
+
+public static double nextAfter(double start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static float nextAfter(float start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static double nextUp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextUp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double nextDown(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextDown(float f) { throw new RuntimeException("Stub!"); }
+
+public static double scalb(double d, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static float scalb(float f, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static final double E = 2.718281828459045;
+
+public static final double PI = 3.141592653589793;
+}
+
diff --git a/ojluni/annotations/mmodule/java/lang/System.annotated.java b/ojluni/annotations/mmodule/java/lang/System.annotated.java
new file mode 100644
index 0000000..918b3da
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/lang/System.annotated.java
@@ -0,0 +1,109 @@
+/*
+ * 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(java.io.InputStream in) { throw new RuntimeException("Stub!"); }
+
+public static void setOut(java.io.PrintStream out) { throw new RuntimeException("Stub!"); }
+
+public static void setErr(java.io.PrintStream err) { throw new RuntimeException("Stub!"); }
+
+public static java.io.Console console() { throw new RuntimeException("Stub!"); }
+
+public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static void setSecurityManager(java.lang.SecurityManager s) { throw new RuntimeException("Stub!"); }
+
+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(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+public static int identityHashCode(java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Properties getProperties() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String lineSeparator() { throw new RuntimeException("Stub!"); }
+
+public static void setProperties(java.util.Properties props) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key, java.lang.String def) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String setProperty(java.lang.String key, java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String clearProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getenv(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(java.lang.String filename) { throw new RuntimeException("Stub!"); }
+
+public static void loadLibrary(java.lang.String libname) { throw new RuntimeException("Stub!"); }
+
+public static native java.lang.String mapLibraryName(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; }
+
+@libcore.api.CorePlatformApi
+public static void logE(String message, Throwable th) { throw new RuntimeException("Stub!"); }
+
+}
+
diff --git a/ojluni/annotations/mmodule/java/lang/Thread.annotated.java b/ojluni/annotations/mmodule/java/lang/Thread.annotated.java
new file mode 100644
index 0000000..2499518
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/lang/Thread.annotated.java
@@ -0,0 +1,177 @@
+/*
+ * 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!"); }
+
+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!"); }
+
+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!"); }
+
+@libcore.api.CorePlatformApi
+public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() { 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/mmodule/java/net/DatagramSocket.annotated.java b/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java
new file mode 100644
index 0000000..b462769
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import java.nio.channels.DatagramChannel;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DatagramSocket implements java.io.Closeable {
+
+public DatagramSocket() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+protected DatagramSocket(java.net.DatagramSocketImpl impl) { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(java.net.SocketAddress bindaddr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(int port) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(int port, java.net.InetAddress laddr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void bind(java.net.SocketAddress addr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.InetAddress address, int port) { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress addr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void disconnect() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isConnected() { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public int getPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getRemoteSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public void send(java.net.DatagramPacket p) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void receive(java.net.DatagramPacket p) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSendBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSendBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setBroadcast(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean getBroadcast() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setTrafficClass(int tc) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getTrafficClass() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void close() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.DatagramChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.io.FileDescriptor getFileDescriptor$() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/Inet4Address.annotated.java b/ojluni/annotations/mmodule/java/net/Inet4Address.annotated.java
new file mode 100644
index 0000000..e10debf
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/Inet4Address.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+import java.io.ObjectStreamException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet4Address extends java.net.InetAddress {
+
+Inet4Address() { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ALL;
+static { ALL = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ANY;
+static { ANY = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress LOOPBACK;
+static { LOOPBACK = null; }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/Inet6Address.annotated.java b/ojluni/annotations/mmodule/java/net/Inet6Address.annotated.java
new file mode 100644
index 0000000..7888710
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/Inet6Address.annotated.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+
+@libcore.api.CorePlatformApi
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet6Address extends java.net.InetAddress {
+
+Inet6Address() { throw new RuntimeException("Stub!"); }
+
+public static java.net.Inet6Address getByAddress(java.lang.String host, byte[] addr, java.net.NetworkInterface nif) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.Inet6Address getByAddress(java.lang.String host, byte[] addr, int scope_id) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public int getScopeId() { throw new RuntimeException("Stub!"); }
+
+public java.net.NetworkInterface getScopedInterface() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isIPv4CompatibleAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ANY;
+static { ANY = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress LOOPBACK;
+static { LOOPBACK = null; }
+}
diff --git a/ojluni/annotations/mmodule/java/net/InetAddress.annotated.java b/ojluni/annotations/mmodule/java/net/InetAddress.annotated.java
new file mode 100644
index 0000000..6f4492d
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/InetAddress.annotated.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import java.io.ObjectStreamException;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetAddress implements java.io.Serializable {
+
+InetAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isReachable(int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public boolean isReachable(java.net.NetworkInterface netif, int ttl, int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public boolean isReachableByICMP(int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getCanonicalHostName() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByAddress(java.lang.String host, byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByName(java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress[] getAllByName(java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByAddress(byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static boolean isNumeric(java.lang.String address) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static void clearDnsCache() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress getByNameOnNet(java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress[] getAllByNameOnNet(java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/InetSocketAddress.annotated.java b/ojluni/annotations/mmodule/java/net/InetSocketAddress.annotated.java
new file mode 100644
index 0000000..554b8e3
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/InetSocketAddress.annotated.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.net;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetSocketAddress extends java.net.SocketAddress {
+
+@libcore.api.CorePlatformApi
+public InetSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(int port) { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(java.net.InetAddress addr, int port) { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(java.lang.String hostname, int port) { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetSocketAddress createUnresolved(java.lang.String host, int port) { throw new RuntimeException("Stub!"); }
+
+public final int getPort() { throw new RuntimeException("Stub!"); }
+
+public final java.net.InetAddress getAddress() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getHostName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getHostString() { throw new RuntimeException("Stub!"); }
+
+public final boolean isUnresolved() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/ServerSocket.annotated.java b/ojluni/annotations/mmodule/java/net/ServerSocket.annotated.java
new file mode 100644
index 0000000..1fcd05f
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/ServerSocket.annotated.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1995, 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.net;
+
+import java.nio.channels.ServerSocketChannel;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ServerSocket implements java.io.Closeable {
+
+public ServerSocket() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port, int backlog) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port, int backlog, java.net.InetAddress bindAddr) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress endpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress endpoint, int backlog) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.Socket accept() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public SocketImpl getImpl() throws SocketException { throw new RuntimeException("Stub!"); }
+
+protected final void implAccept(java.net.Socket s) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.ServerSocketChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setSocketFactory(java.net.SocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/Socket.annotated.java b/ojluni/annotations/mmodule/java/net/Socket.annotated.java
new file mode 100644
index 0000000..e021788
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/Socket.annotated.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import java.nio.channels.SocketChannel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Socket implements java.io.Closeable {
+
+public Socket() { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.Proxy proxy) { throw new RuntimeException("Stub!"); }
+
+protected Socket(java.net.SocketImpl impl) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.lang.String host, int port) throws java.io.IOException, java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.InetAddress address, int port) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.lang.String host, int port, java.net.InetAddress localAddr, int localPort) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.InetAddress address, int port, java.net.InetAddress localAddr, int localPort) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public Socket(java.lang.String host, int port, boolean stream) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public Socket(java.net.InetAddress host, int port, boolean stream) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress endpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress endpoint, int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress bindpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public int getPort() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getRemoteSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.SocketChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public java.io.InputStream getInputStream() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.io.OutputStream getOutputStream() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setTcpNoDelay(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getTcpNoDelay() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setSoLinger(boolean on, int linger) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public int getSoLinger() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void sendUrgentData(int data) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setOOBInline(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getOOBInline() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSendBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSendBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setKeepAlive(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getKeepAlive() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setTrafficClass(int tc) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public int getTrafficClass() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void shutdownInput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void shutdownOutput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public boolean isConnected() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public boolean isInputShutdown() { throw new RuntimeException("Stub!"); }
+
+public boolean isOutputShutdown() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setSocketImplFactory(java.net.SocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
+public java.io.FileDescriptor getFileDescriptor$() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/net/SocketImpl.annotated.java b/ojluni/annotations/mmodule/java/net/SocketImpl.annotated.java
new file mode 100644
index 0000000..ab1f94e
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/net/SocketImpl.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.net;
+
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SocketImpl implements java.net.SocketOptions {
+
+public SocketImpl() { throw new RuntimeException("Stub!"); }
+
+protected abstract void create(boolean stream) throws java.io.IOException;
+
+protected abstract void connect(java.lang.String host, int port) throws java.io.IOException;
+
+protected abstract void connect(java.net.InetAddress address, int port) throws java.io.IOException;
+
+protected abstract void connect(java.net.SocketAddress address, int timeout) throws java.io.IOException;
+
+protected abstract void bind(java.net.InetAddress host, int port) throws java.io.IOException;
+
+protected abstract void listen(int backlog) throws java.io.IOException;
+
+protected abstract void accept(java.net.SocketImpl s) throws java.io.IOException;
+
+protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
+
+protected abstract java.io.OutputStream getOutputStream() throws java.io.IOException;
+
+protected abstract int available() throws java.io.IOException;
+
+protected abstract void close() throws java.io.IOException;
+
+protected void shutdownInput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+protected void shutdownOutput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+protected java.io.FileDescriptor getFileDescriptor() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public FileDescriptor getFD$() { throw new RuntimeException("Stub!"); }
+
+protected java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+protected int getPort() { throw new RuntimeException("Stub!"); }
+
+protected boolean supportsUrgentData() { throw new RuntimeException("Stub!"); }
+
+protected abstract void sendUrgentData(int data) throws java.io.IOException;
+
+protected int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+
+protected java.net.InetAddress address;
+
+protected java.io.FileDescriptor fd;
+
+protected int localport;
+
+protected int port;
+}
+
diff --git a/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java b/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java
new file mode 100644
index 0000000..d0caba2
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+
+ByteBuffer(int mark, int pos, int lim, int cap) { super(0, 0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocateDirect(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocate(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array) { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer slice();
+
+public abstract java.nio.ByteBuffer duplicate();
+
+public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+
+public abstract byte get();
+
+public abstract java.nio.ByteBuffer put(byte b);
+
+public abstract byte get(int index);
+
+public abstract java.nio.ByteBuffer put(int index, byte b);
+
+public java.nio.ByteBuffer get(byte[] dst, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte[] src) { throw new RuntimeException("Stub!"); }
+
+public final boolean hasArray() { throw new RuntimeException("Stub!"); }
+
+public final byte[] array() { throw new RuntimeException("Stub!"); }
+
+public final int arrayOffset() { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer compact();
+
+public abstract boolean isDirect();
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object ob) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(java.nio.ByteBuffer that) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteOrder order() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer order(java.nio.ByteOrder bo) { throw new RuntimeException("Stub!"); }
+
+public abstract char getChar();
+
+public abstract java.nio.ByteBuffer putChar(char value);
+
+public abstract char getChar(int index);
+
+public abstract java.nio.ByteBuffer putChar(int index, char value);
+
+public abstract java.nio.CharBuffer asCharBuffer();
+
+public abstract short getShort();
+
+public abstract java.nio.ByteBuffer putShort(short value);
+
+public abstract short getShort(int index);
+
+public abstract java.nio.ByteBuffer putShort(int index, short value);
+
+public abstract java.nio.ShortBuffer asShortBuffer();
+
+public abstract int getInt();
+
+public abstract java.nio.ByteBuffer putInt(int value);
+
+public abstract int getInt(int index);
+
+public abstract java.nio.ByteBuffer putInt(int index, int value);
+
+public abstract java.nio.IntBuffer asIntBuffer();
+
+public abstract long getLong();
+
+public abstract java.nio.ByteBuffer putLong(long value);
+
+public abstract long getLong(int index);
+
+public abstract java.nio.ByteBuffer putLong(int index, long value);
+
+public abstract java.nio.LongBuffer asLongBuffer();
+
+public abstract float getFloat();
+
+public abstract java.nio.ByteBuffer putFloat(float value);
+
+public abstract float getFloat(int index);
+
+public abstract java.nio.ByteBuffer putFloat(int index, float value);
+
+public abstract java.nio.FloatBuffer asFloatBuffer();
+
+public abstract double getDouble();
+
+public abstract java.nio.ByteBuffer putDouble(double value);
+
+public abstract double getDouble(int index);
+
+public abstract java.nio.ByteBuffer putDouble(int index, double value);
+
+public abstract java.nio.DoubleBuffer asDoubleBuffer();
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/nio/DirectByteBuffer.annotated.java b/ojluni/annotations/mmodule/java/nio/DirectByteBuffer.annotated.java
new file mode 100644
index 0000000..51e0e9c
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/nio/DirectByteBuffer.annotated.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 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.nio;
+
+
+@libcore.api.CorePlatformApi
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DirectByteBuffer extends java.nio.MappedByteBuffer implements sun.nio.ch.DirectBuffer {
+
+@libcore.api.CorePlatformApi
+public DirectByteBuffer(int cap, long addr, java.io.FileDescriptor fd, java.lang.Runnable unmapper, boolean isReadOnly) { super(0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public final java.lang.Object attachment() { throw new RuntimeException("Stub!"); }
+
+public final sun.misc.Cleaner cleaner() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer slice() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer duplicate() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer asReadOnlyBuffer() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public final long address() { throw new RuntimeException("Stub!"); }
+
+public final byte get() { throw new RuntimeException("Stub!"); }
+
+public final byte get(int i) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst, int dstOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(int i, byte x) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int srcOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer compact() { throw new RuntimeException("Stub!"); }
+
+public final boolean isDirect() { throw new RuntimeException("Stub!"); }
+
+public final boolean isReadOnly() { throw new RuntimeException("Stub!"); }
+
+public final char getChar() { throw new RuntimeException("Stub!"); }
+
+public final char getChar(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(int i, char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.CharBuffer asCharBuffer() { throw new RuntimeException("Stub!"); }
+
+public final short getShort() { throw new RuntimeException("Stub!"); }
+
+public final short getShort(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(int i, short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ShortBuffer asShortBuffer() { throw new RuntimeException("Stub!"); }
+
+public int getInt() { throw new RuntimeException("Stub!"); }
+
+public int getInt(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int i, int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.IntBuffer asIntBuffer() { throw new RuntimeException("Stub!"); }
+
+public final long getLong() { throw new RuntimeException("Stub!"); }
+
+public final long getLong(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(int i, long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.LongBuffer asLongBuffer() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(int i, float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.FloatBuffer asFloatBuffer() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(int i, double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.DoubleBuffer asDoubleBuffer() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+public final void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/security/Provider.annotated.java b/ojluni/annotations/mmodule/java/security/Provider.annotated.java
new file mode 100644
index 0000000..2fce78b
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/security/Provider.annotated.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.security;
+
+import java.io.*;
+import java.util.*;
+import java.lang.ref.*;
+import java.lang.reflect.*;
+import java.security.Security;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Provider extends java.util.Properties {
+
+protected Provider(java.lang.String name, double version, java.lang.String info) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public double getVersion() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getInfo() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public synchronized void clear() { throw new RuntimeException("Stub!"); }
+
+public synchronized void load(java.io.InputStream inStream) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void putAll(java.util.Map<?,?> t) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet() { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<java.lang.Object> keySet() { throw new RuntimeException("Stub!"); }
+
+public java.util.Collection<java.lang.Object> values() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object put(java.lang.Object key, java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object putIfAbsent(java.lang.Object key, java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object remove(java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean remove(java.lang.Object key, java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean replace(java.lang.Object key, java.lang.Object oldValue, java.lang.Object newValue) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object replace(java.lang.Object key, java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?> function) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object compute(java.lang.Object key, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object computeIfAbsent(java.lang.Object key, java.util.function.Function<? super java.lang.Object,?> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object computeIfPresent(java.lang.Object key, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object merge(java.lang.Object key, java.lang.Object value, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object get(java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.Object getOrDefault(java.lang.Object key, java.lang.Object defaultValue) { throw new RuntimeException("Stub!"); }
+
+public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object,? super java.lang.Object> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.Enumeration<java.lang.Object> keys() { throw new RuntimeException("Stub!"); }
+
+public java.util.Enumeration<java.lang.Object> elements() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.security.Provider.Service getService(java.lang.String type, java.lang.String algorithm) { throw new RuntimeException("Stub!"); }
+
+public synchronized java.util.Set<java.security.Provider.Service> getServices() { throw new RuntimeException("Stub!"); }
+
+protected synchronized void putService(java.security.Provider.Service s) { throw new RuntimeException("Stub!"); }
+
+protected synchronized void removeService(java.security.Provider.Service s) { throw new RuntimeException("Stub!"); }
+
+public void setRegistered() { throw new RuntimeException("Stub!"); }
+
+public void setUnregistered() { throw new RuntimeException("Stub!"); }
+
+public boolean isRegistered() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public synchronized void warmUpServiceProvision() { throw new RuntimeException("Stub!"); }
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Service {
+
+public Service(java.security.Provider provider, java.lang.String type, java.lang.String algorithm, java.lang.String className, java.util.List<java.lang.String> aliases, java.util.Map<java.lang.String, java.lang.String> attributes) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getType() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getAlgorithm() { throw new RuntimeException("Stub!"); }
+
+public final java.security.Provider getProvider() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getClassName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getAttribute(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object newInstance(java.lang.Object constructorParameter) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public boolean supportsParameter(java.lang.Object parameter) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+}
+
diff --git a/ojluni/annotations/mmodule/java/security/Signature.annotated.java b/ojluni/annotations/mmodule/java/security/Signature.annotated.java
new file mode 100644
index 0000000..87323e2
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/security/Signature.annotated.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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.security;
+
+import java.util.*;
+import java.io.*;
+import sun.security.jca.*;
+import java.nio.ByteBuffer;
+import java.security.spec.AlgorithmParameterSpec;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Signature extends java.security.SignatureSpi {
+
+protected Signature(java.lang.String algorithm) { throw new RuntimeException("Stub!"); }
+
+public static java.security.Signature getInstance(java.lang.String algorithm) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static java.security.Signature getInstance(java.lang.String algorithm, java.lang.String provider) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException { throw new RuntimeException("Stub!"); }
+
+public static java.security.Signature getInstance(java.lang.String algorithm, java.security.Provider provider) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public final java.security.Provider getProvider() { throw new RuntimeException("Stub!"); }
+
+public final void initVerify(java.security.PublicKey publicKey) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void initVerify(java.security.cert.Certificate certificate) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void initSign(java.security.PrivateKey privateKey) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void initSign(java.security.PrivateKey privateKey, java.security.SecureRandom random) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final byte[] sign() throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final int sign(byte[] outbuf, int offset, int len) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final boolean verify(byte[] signature) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final boolean verify(byte[] signature, int offset, int length) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte b) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte[] data) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte[] data, int off, int len) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final void update(java.nio.ByteBuffer data) throws java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getAlgorithm() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void setParameter(java.lang.String param, java.lang.Object value) throws java.security.InvalidParameterException { throw new RuntimeException("Stub!"); }
+
+public final void setParameter(java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidAlgorithmParameterException { throw new RuntimeException("Stub!"); }
+
+public final java.security.AlgorithmParameters getParameters() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final java.lang.Object getParameter(java.lang.String param) throws java.security.InvalidParameterException { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.security.SignatureSpi getCurrentSpi() { throw new RuntimeException("Stub!"); }
+
+protected static final int SIGN = 2; // 0x2
+
+protected static final int UNINITIALIZED = 0; // 0x0
+
+protected static final int VERIFY = 3; // 0x3
+
+protected int state = 0; // 0x0
+}
+
diff --git a/ojluni/annotations/mmodule/java/security/spec/ECParameterSpec.annotated.java b/ojluni/annotations/mmodule/java/security/spec/ECParameterSpec.annotated.java
new file mode 100644
index 0000000..926ee08
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/security/spec/ECParameterSpec.annotated.java
@@ -0,0 +1,49 @@
+/*
+ * 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.security.spec;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+
+public ECParameterSpec(java.security.spec.EllipticCurve curve, java.security.spec.ECPoint g, java.math.BigInteger n, int h) { throw new RuntimeException("Stub!"); }
+
+public java.security.spec.EllipticCurve getCurve() { throw new RuntimeException("Stub!"); }
+
+public java.security.spec.ECPoint getGenerator() { throw new RuntimeException("Stub!"); }
+
+public java.math.BigInteger getOrder() { throw new RuntimeException("Stub!"); }
+
+public int getCofactor() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.IntraCoreApi
+public void setCurveName(String curveName) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.IntraCoreApi
+public String getCurveName() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/sun/security/util/DerEncoder.annotated.java b/ojluni/annotations/mmodule/java/sun/security/util/DerEncoder.annotated.java
new file mode 100644
index 0000000..1307552
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/sun/security/util/DerEncoder.annotated.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+@libcore.api.Hide
+@libcore.api.IntraCoreApi
+public interface DerEncoder {
+
+    @libcore.api.IntraCoreApi
+    public void derEncode(OutputStream out)
+        throws IOException;
+
+}
diff --git a/ojluni/annotations/mmodule/java/sun/security/util/ObjectIdentifier.annotated.java b/ojluni/annotations/mmodule/java/sun/security/util/ObjectIdentifier.annotated.java
new file mode 100644
index 0000000..d1d5eac
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/sun/security/util/ObjectIdentifier.annotated.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.security.util;
+
+import java.io.*;
+import java.math.BigInteger;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class ObjectIdentifier implements java.io.Serializable {
+
+@libcore.api.CorePlatformApi
+public ObjectIdentifier(java.lang.String oid) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ObjectIdentifier(int[] values) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ObjectIdentifier(sun.security.util.DerInputStream in) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static sun.security.util.ObjectIdentifier newInternal(int[] values) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public boolean equals(sun.security.util.ObjectIdentifier other) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public int[] toIntArray() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java b/ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java
new file mode 100644
index 0000000..dc2baf6
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java
@@ -0,0 +1,54 @@
+/*
+ * 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 sun.security.x509;
+import java.io.Serializable;
+import java.security.NoSuchAlgorithmException;
+
+import sun.security.util.DerEncoder;
+import sun.security.util.ObjectIdentifier;
+
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
+@libcore.api.Hide
+public class AlgorithmId implements Serializable, DerEncoder {
+
+    @libcore.api.CorePlatformApi
+    public AlgorithmId(ObjectIdentifier oid) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.CorePlatformApi
+    @libcore.api.IntraCoreApi
+    public String getName() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.IntraCoreApi
+    public static AlgorithmId get(String algname) throws NoSuchAlgorithmException {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java b/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java
new file mode 100644
index 0000000..5a28d02
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.text;
+
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Calendar;
+import java.util.Date;
+import java.io.InvalidObjectException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class DateFormat extends java.text.Format {
+
+protected DateFormat() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.StringBuffer format(java.lang.Object obj, java.lang.StringBuffer toAppendTo, java.text.FieldPosition fieldPosition) { throw new RuntimeException("Stub!"); }
+
+public abstract java.lang.StringBuffer format(java.util.Date date, java.lang.StringBuffer toAppendTo, java.text.FieldPosition fieldPosition);
+
+public final java.lang.String format(java.util.Date date) { throw new RuntimeException("Stub!"); }
+
+public java.util.Date parse(java.lang.String source) throws java.text.ParseException { throw new RuntimeException("Stub!"); }
+
+public abstract java.util.Date parse(java.lang.String source, java.text.ParsePosition pos);
+
+public java.lang.Object parseObject(java.lang.String source, java.text.ParsePosition pos) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getTimeInstance() { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getTimeInstance(int style) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getTimeInstance(int style, java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateInstance() { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateInstance(int style) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateInstance(int style, java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateTimeInstance() { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle, java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat getInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static final void set24HourTimePref(java.lang.Boolean is24Hour) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale[] getAvailableLocales() { throw new RuntimeException("Stub!"); }
+
+public void setCalendar(java.util.Calendar newCalendar) { throw new RuntimeException("Stub!"); }
+
+public java.util.Calendar getCalendar() { throw new RuntimeException("Stub!"); }
+
+public void setNumberFormat(java.text.NumberFormat newNumberFormat) { throw new RuntimeException("Stub!"); }
+
+public java.text.NumberFormat getNumberFormat() { throw new RuntimeException("Stub!"); }
+
+public void setTimeZone(java.util.TimeZone zone) { throw new RuntimeException("Stub!"); }
+
+public java.util.TimeZone getTimeZone() { throw new RuntimeException("Stub!"); }
+
+public void setLenient(boolean lenient) { throw new RuntimeException("Stub!"); }
+
+public boolean isLenient() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public static final int AM_PM_FIELD = 14; // 0xe
+
+public static final int DATE_FIELD = 3; // 0x3
+
+public static final int DAY_OF_WEEK_FIELD = 9; // 0x9
+
+public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; // 0xb
+
+public static final int DAY_OF_YEAR_FIELD = 10; // 0xa
+
+public static final int DEFAULT = 2; // 0x2
+
+public static final int ERA_FIELD = 0; // 0x0
+
+public static final int FULL = 0; // 0x0
+
+public static final int HOUR0_FIELD = 16; // 0x10
+
+public static final int HOUR1_FIELD = 15; // 0xf
+
+public static final int HOUR_OF_DAY0_FIELD = 5; // 0x5
+
+public static final int HOUR_OF_DAY1_FIELD = 4; // 0x4
+
+public static final int LONG = 1; // 0x1
+
+public static final int MEDIUM = 2; // 0x2
+
+public static final int MILLISECOND_FIELD = 8; // 0x8
+
+public static final int MINUTE_FIELD = 6; // 0x6
+
+public static final int MONTH_FIELD = 2; // 0x2
+
+public static final int SECOND_FIELD = 7; // 0x7
+
+public static final int SHORT = 3; // 0x3
+
+public static final int TIMEZONE_FIELD = 17; // 0x11
+
+public static final int WEEK_OF_MONTH_FIELD = 13; // 0xd
+
+public static final int WEEK_OF_YEAR_FIELD = 12; // 0xc
+
+public static final int YEAR_FIELD = 1; // 0x1
+
+protected java.util.Calendar calendar;
+
+public static java.lang.Boolean is24Hour;
+
+protected java.text.NumberFormat numberFormat;
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Field extends java.text.Format.Field {
+
+protected Field(java.lang.String name, int calendarField) { super(null); throw new RuntimeException("Stub!"); }
+
+public static java.text.DateFormat.Field ofCalendarField(int calendarField) { throw new RuntimeException("Stub!"); }
+
+public int getCalendarField() { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object readResolve() throws java.io.InvalidObjectException { throw new RuntimeException("Stub!"); }
+
+public static final java.text.DateFormat.Field AM_PM;
+static { AM_PM = null; }
+
+public static final java.text.DateFormat.Field DAY_OF_MONTH;
+static { DAY_OF_MONTH = null; }
+
+public static final java.text.DateFormat.Field DAY_OF_WEEK;
+static { DAY_OF_WEEK = null; }
+
+public static final java.text.DateFormat.Field DAY_OF_WEEK_IN_MONTH;
+static { DAY_OF_WEEK_IN_MONTH = null; }
+
+public static final java.text.DateFormat.Field DAY_OF_YEAR;
+static { DAY_OF_YEAR = null; }
+
+public static final java.text.DateFormat.Field ERA;
+static { ERA = null; }
+
+public static final java.text.DateFormat.Field HOUR0;
+static { HOUR0 = null; }
+
+public static final java.text.DateFormat.Field HOUR1;
+static { HOUR1 = null; }
+
+public static final java.text.DateFormat.Field HOUR_OF_DAY0;
+static { HOUR_OF_DAY0 = null; }
+
+public static final java.text.DateFormat.Field HOUR_OF_DAY1;
+static { HOUR_OF_DAY1 = null; }
+
+public static final java.text.DateFormat.Field MILLISECOND;
+static { MILLISECOND = null; }
+
+public static final java.text.DateFormat.Field MINUTE;
+static { MINUTE = null; }
+
+public static final java.text.DateFormat.Field MONTH;
+static { MONTH = null; }
+
+public static final java.text.DateFormat.Field SECOND;
+static { SECOND = null; }
+
+public static final java.text.DateFormat.Field TIME_ZONE;
+static { TIME_ZONE = null; }
+
+public static final java.text.DateFormat.Field WEEK_OF_MONTH;
+static { WEEK_OF_MONTH = null; }
+
+public static final java.text.DateFormat.Field WEEK_OF_YEAR;
+static { WEEK_OF_YEAR = null; }
+
+public static final java.text.DateFormat.Field YEAR;
+static { YEAR = null; }
+}
+
+}
+
diff --git a/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java b/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java
new file mode 100644
index 0000000..9f494b6
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java
@@ -0,0 +1,66 @@
+/*
+ * 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 LinkedHashMap<K, V> extends java.util.HashMap<K,V> implements java.util.Map<K,V> {
+
+public LinkedHashMap(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+public LinkedHashMap(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public LinkedHashMap() { throw new RuntimeException("Stub!"); }
+
+public LinkedHashMap(java.util.Map<? extends K, ? extends V> m) { throw new RuntimeException("Stub!"); }
+
+public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { throw new RuntimeException("Stub!"); }
+
+public boolean containsValue(java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public V get(java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public V getOrDefault(java.lang.Object key, V defaultValue) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.util.Map.Entry<K,V> eldest() { throw new RuntimeException("Stub!"); }
+
+protected boolean removeEldestEntry(java.util.Map.Entry<K,V> eldest) { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<K> keySet() { throw new RuntimeException("Stub!"); }
+
+public java.util.Collection<V> values() { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<java.util.Map.Entry<K,V>> entrySet() { throw new RuntimeException("Stub!"); }
+
+public void forEach(java.util.function.BiConsumer<? super K,? super V> action) { throw new RuntimeException("Stub!"); }
+
+public void replaceAll(java.util.function.BiFunction<? super K,? super V,? extends V> function) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/java/util/Locale.annotated.java b/ojluni/annotations/mmodule/java/util/Locale.annotated.java
new file mode 100644
index 0000000..d8aad03
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/util/Locale.annotated.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.util;
+
+import java.text.MessageFormat;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Locale implements java.lang.Cloneable, java.io.Serializable {
+
+public Locale(java.lang.String language, java.lang.String country, java.lang.String variant) { throw new RuntimeException("Stub!"); }
+
+public Locale(java.lang.String language, java.lang.String country) { throw new RuntimeException("Stub!"); }
+
+public Locale(java.lang.String language) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale getDefault() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale getDefault(java.util.Locale.Category category) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale initDefault() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDefault(java.util.Locale newLocale) { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDefault(java.util.Locale.Category category, java.util.Locale newLocale) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale[] getAvailableLocales() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String[] getISOCountries() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String[] getISOLanguages() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getLanguage() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getScript() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getCountry() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getVariant() { throw new RuntimeException("Stub!"); }
+
+public boolean hasExtensions() { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale stripExtensions() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getExtension(char key) { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<java.lang.Character> getExtensionKeys() { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<java.lang.String> getUnicodeLocaleAttributes() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getUnicodeLocaleType(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public java.util.Set<java.lang.String> getUnicodeLocaleKeys() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toLanguageTag() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale forLanguageTag(java.lang.String languageTag) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getISO3Language() throws java.util.MissingResourceException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getISO3Country() throws java.util.MissingResourceException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayLanguage() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayLanguage(java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayScript() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayScript(java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayCountry() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayCountry(java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayVariant() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayVariant(java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getDisplayName(java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.lang.String adjustLanguageCode(java.lang.String languageCode) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.util.Locale> filter(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.util.Locale> locales, java.util.Locale.FilteringMode mode) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.util.Locale> filter(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.util.Locale> locales) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.lang.String> filterTags(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.lang.String> tags, java.util.Locale.FilteringMode mode) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.lang.String> filterTags(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.lang.String> tags) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Locale lookup(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.util.Locale> locales) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String lookupTag(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Collection<java.lang.String> tags) { throw new RuntimeException("Stub!"); }
+
+public static final java.util.Locale CANADA;
+static { CANADA = null; }
+
+public static final java.util.Locale CANADA_FRENCH;
+static { CANADA_FRENCH = null; }
+
+public static final java.util.Locale CHINA;
+static { CHINA = null; }
+
+public static final java.util.Locale CHINESE;
+static { CHINESE = null; }
+
+public static final java.util.Locale ENGLISH;
+static { ENGLISH = null; }
+
+public static final java.util.Locale FRANCE;
+static { FRANCE = null; }
+
+public static final java.util.Locale FRENCH;
+static { FRENCH = null; }
+
+public static final java.util.Locale GERMAN;
+static { GERMAN = null; }
+
+public static final java.util.Locale GERMANY;
+static { GERMANY = null; }
+
+public static final java.util.Locale ITALIAN;
+static { ITALIAN = null; }
+
+public static final java.util.Locale ITALY;
+static { ITALY = null; }
+
+public static final java.util.Locale JAPAN;
+static { JAPAN = null; }
+
+public static final java.util.Locale JAPANESE;
+static { JAPANESE = null; }
+
+public static final java.util.Locale KOREA;
+static { KOREA = null; }
+
+public static final java.util.Locale KOREAN;
+static { KOREAN = null; }
+
+public static final java.util.Locale PRC;
+static { PRC = null; }
+
+public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
+
+public static final java.util.Locale ROOT;
+static { ROOT = null; }
+
+public static final java.util.Locale SIMPLIFIED_CHINESE;
+static { SIMPLIFIED_CHINESE = null; }
+
+public static final java.util.Locale TAIWAN;
+static { TAIWAN = null; }
+
+public static final java.util.Locale TRADITIONAL_CHINESE;
+static { TRADITIONAL_CHINESE = null; }
+
+public static final java.util.Locale UK;
+static { UK = null; }
+
+public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
+
+public static final java.util.Locale US;
+static { US = null; }
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class Builder {
+
+public Builder() { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setLocale(java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setLanguageTag(java.lang.String languageTag) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setLanguage(java.lang.String language) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setScript(java.lang.String script) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setRegion(java.lang.String region) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setVariant(java.lang.String variant) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setExtension(char key, java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder setUnicodeLocaleKeyword(java.lang.String key, java.lang.String type) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder addUnicodeLocaleAttribute(java.lang.String attribute) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder removeUnicodeLocaleAttribute(java.lang.String attribute) { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder clear() { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale.Builder clearExtensions() { throw new RuntimeException("Stub!"); }
+
+public java.util.Locale build() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum Category {
+DISPLAY,
+FORMAT;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum FilteringMode {
+AUTOSELECT_FILTERING,
+EXTENDED_FILTERING,
+IGNORE_EXTENDED_RANGES,
+MAP_EXTENDED_RANGES,
+REJECT_EXTENDED_RANGES;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class LanguageRange {
+
+public LanguageRange(java.lang.String range) { throw new RuntimeException("Stub!"); }
+
+public LanguageRange(java.lang.String range, double weight) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getRange() { throw new RuntimeException("Stub!"); }
+
+public double getWeight() { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.util.Locale.LanguageRange> parse(java.lang.String ranges) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.util.Locale.LanguageRange> parse(java.lang.String ranges, java.util.Map<java.lang.String, java.util.List<java.lang.String>> map) { throw new RuntimeException("Stub!"); }
+
+public static java.util.List<java.util.Locale.LanguageRange> mapEquivalents(java.util.List<java.util.Locale.LanguageRange> priorityList, java.util.Map<java.lang.String, java.util.List<java.lang.String>> map) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static final double MAX_WEIGHT = 1.0;
+
+public static final double MIN_WEIGHT = 0.0;
+}
+
+}
+
diff --git a/ojluni/annotations/mmodule/java/util/concurrent/CompletableFuture.annotated.java b/ojluni/annotations/mmodule/java/util/concurrent/CompletableFuture.annotated.java
new file mode 100644
index 0000000..5ac5a83
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/util/concurrent/CompletableFuture.annotated.java
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+
+package java.util.concurrent;
+
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CompletableFuture<T> implements java.util.concurrent.Future<T>, java.util.concurrent.CompletionStage<T> {
+
+public CompletableFuture() { throw new RuntimeException("Stub!"); }
+
+public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U> supplier) { throw new RuntimeException("Stub!"); }
+
+public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U> supplier, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable runnable) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(java.lang.Runnable runnable, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public static <U> java.util.concurrent.CompletableFuture<U> completedFuture(U value) { throw new RuntimeException("Stub!"); }
+
+public boolean isDone() { throw new RuntimeException("Stub!"); }
+
+public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public T get(long timeout, java.util.concurrent.TimeUnit unit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException { throw new RuntimeException("Stub!"); }
+
+public T join() { throw new RuntimeException("Stub!"); }
+
+public T getNow(T valueIfAbsent) { throw new RuntimeException("Stub!"); }
+
+public boolean complete(T value) { throw new RuntimeException("Stub!"); }
+
+public boolean completeExceptionally(java.lang.Throwable ex) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T,? extends U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U> fn, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T> action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(java.lang.Runnable action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public <U, V> java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiFunction<? super T,? super U,? extends V> fn) { throw new RuntimeException("Stub!"); }
+
+public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiFunction<? super T,? super U,? extends V> fn) { throw new RuntimeException("Stub!"); }
+
+public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiFunction<? super T,? super U,? extends V> fn, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiConsumer<? super T,? super U> action) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiConsumer<? super T,? super U> action) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U> other, java.util.function.BiConsumer<? super T,? super U> action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Function<? super T,U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Function<? super T,U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Function<? super T,U> fn, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T> other, java.util.function.Consumer<? super T> action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?> other, java.lang.Runnable action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>> fn, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T,? super java.lang.Throwable> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable> action) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable> action, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U> fn) { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U> fn, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> toCompletableFuture() { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable,? extends T> fn) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>... cfs) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>... cfs) { throw new RuntimeException("Stub!"); }
+
+public boolean cancel(boolean mayInterruptIfRunning) { throw new RuntimeException("Stub!"); }
+
+public boolean isCancelled() { throw new RuntimeException("Stub!"); }
+
+public boolean isCompletedExceptionally() { throw new RuntimeException("Stub!"); }
+
+public void obtrudeValue(T value) { throw new RuntimeException("Stub!"); }
+
+public void obtrudeException(java.lang.Throwable ex) { throw new RuntimeException("Stub!"); }
+
+public int getNumberOfDependents() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public <U> java.util.concurrent.CompletableFuture<U> newIncompleteFuture() { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.Executor defaultExecutor() { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> copy() { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletionStage<T> minimalCompletionStage() { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> completeAsync(java.util.function.Supplier<? extends T> supplier, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> completeAsync(java.util.function.Supplier<? extends T> supplier) { throw new RuntimeException("Stub!"); }
+
+public java.util.concurrent.CompletableFuture<T> orTimeout(long timeout, java.util.concurrent.TimeUnit unit) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.util.concurrent.CompletableFuture<T> completeOnTimeout(T value, long timeout, java.util.concurrent.TimeUnit unit) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.Executor delayedExecutor(long delay, java.util.concurrent.TimeUnit unit, java.util.concurrent.Executor executor) { throw new RuntimeException("Stub!"); }
+
+public static java.util.concurrent.Executor delayedExecutor(long delay, java.util.concurrent.TimeUnit unit) { throw new RuntimeException("Stub!"); }
+
+public static <U> java.util.concurrent.CompletionStage<U> completedStage(U value) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static <U> java.util.concurrent.CompletableFuture<U> failedFuture(java.lang.Throwable ex) { throw new RuntimeException("Stub!"); }
+
+public static <U> java.util.concurrent.CompletionStage<U> failedStage(java.lang.Throwable ex) { throw new RuntimeException("Stub!"); }
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static interface AsynchronousCompletionTask {
+}
+
+}
diff --git a/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java b/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java
new file mode 100644
index 0000000..66b3616
--- /dev/null
+++ b/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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.zip;
+
+import java.nio.file.attribute.FileTime;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ZipEntry implements java.lang.Cloneable {
+
+public ZipEntry(java.lang.String name, java.lang.String comment, long crc, long compressedSize, long size, int compressionMethod, int xdostime, byte[] extra, long dataOffset) { throw new RuntimeException("Stub!"); }
+
+public ZipEntry(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public ZipEntry(java.util.zip.ZipEntry e) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public long getDataOffset() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public void setTime(long time) { throw new RuntimeException("Stub!"); }
+
+public long getTime() { throw new RuntimeException("Stub!"); }
+
+public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime time) { throw new RuntimeException("Stub!"); }
+
+public java.nio.file.attribute.FileTime getLastModifiedTime() { throw new RuntimeException("Stub!"); }
+
+public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime time) { throw new RuntimeException("Stub!"); }
+
+public java.nio.file.attribute.FileTime getLastAccessTime() { throw new RuntimeException("Stub!"); }
+
+public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime time) { throw new RuntimeException("Stub!"); }
+
+public java.nio.file.attribute.FileTime getCreationTime() { throw new RuntimeException("Stub!"); }
+
+public void setSize(long size) { throw new RuntimeException("Stub!"); }
+
+public long getSize() { throw new RuntimeException("Stub!"); }
+
+public long getCompressedSize() { throw new RuntimeException("Stub!"); }
+
+public void setCompressedSize(long csize) { throw new RuntimeException("Stub!"); }
+
+public void setCrc(long crc) { throw new RuntimeException("Stub!"); }
+
+public long getCrc() { throw new RuntimeException("Stub!"); }
+
+public void setMethod(int method) { throw new RuntimeException("Stub!"); }
+
+public int getMethod() { throw new RuntimeException("Stub!"); }
+
+public void setExtra(byte[] extra) { throw new RuntimeException("Stub!"); }
+
+public byte[] getExtra() { throw new RuntimeException("Stub!"); }
+
+public void setComment(java.lang.String comment) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getComment() { throw new RuntimeException("Stub!"); }
+
+public boolean isDirectory() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public static final int CENATT = 36; // 0x24
+
+public static final int CENATX = 38; // 0x26
+
+public static final int CENCOM = 32; // 0x20
+
+public static final int CENCRC = 16; // 0x10
+
+public static final int CENDSK = 34; // 0x22
+
+public static final int CENEXT = 30; // 0x1e
+
+public static final int CENFLG = 8; // 0x8
+
+public static final int CENHDR = 46; // 0x2e
+
+public static final int CENHOW = 10; // 0xa
+
+public static final int CENLEN = 24; // 0x18
+
+public static final int CENNAM = 28; // 0x1c
+
+public static final int CENOFF = 42; // 0x2a
+
+public static final long CENSIG = 33639248L; // 0x2014b50L
+
+public static final int CENSIZ = 20; // 0x14
+
+public static final int CENTIM = 12; // 0xc
+
+public static final int CENVEM = 4; // 0x4
+
+public static final int CENVER = 6; // 0x6
+
+public static final int DEFLATED = 8; // 0x8
+
+public static final int ENDCOM = 20; // 0x14
+
+public static final int ENDHDR = 22; // 0x16
+
+public static final int ENDOFF = 16; // 0x10
+
+public static final long ENDSIG = 101010256L; // 0x6054b50L
+
+public static final int ENDSIZ = 12; // 0xc
+
+public static final int ENDSUB = 8; // 0x8
+
+public static final int ENDTOT = 10; // 0xa
+
+public static final int EXTCRC = 4; // 0x4
+
+public static final int EXTHDR = 16; // 0x10
+
+public static final int EXTLEN = 12; // 0xc
+
+public static final long EXTSIG = 134695760L; // 0x8074b50L
+
+public static final int EXTSIZ = 8; // 0x8
+
+public static final int LOCCRC = 14; // 0xe
+
+public static final int LOCEXT = 28; // 0x1c
+
+public static final int LOCFLG = 6; // 0x6
+
+public static final int LOCHDR = 30; // 0x1e
+
+public static final int LOCHOW = 8; // 0x8
+
+public static final int LOCLEN = 22; // 0x16
+
+public static final int LOCNAM = 26; // 0x1a
+
+public static final long LOCSIG = 67324752L; // 0x4034b50L
+
+public static final int LOCSIZ = 18; // 0x12
+
+public static final int LOCTIM = 10; // 0xa
+
+public static final int LOCVER = 4; // 0x4
+
+public static final int STORED = 0; // 0x0
+
+public static final long UPPER_DOSTIME_BOUND = 4036608000000L; // 0x3abd8960000L
+}
+
diff --git a/ojluni/annotations/mmodule/javax/crypto/Cipher.annotated.java b/ojluni/annotations/mmodule/javax/crypto/Cipher.annotated.java
new file mode 100644
index 0000000..bafd946
--- /dev/null
+++ b/ojluni/annotations/mmodule/javax/crypto/Cipher.annotated.java
@@ -0,0 +1,136 @@
+/*
+ * 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 javax.crypto;
+
+import java.util.*;
+import java.util.regex.*;
+import java.security.*;
+import javax.crypto.spec.*;
+import sun.security.jca.*;
+import java.nio.ReadOnlyBufferException;
+import java.nio.ByteBuffer;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.Provider.Service;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Cipher {
+
+protected Cipher(javax.crypto.CipherSpi cipherSpi, java.security.Provider provider, java.lang.String transformation) { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Cipher getInstance(java.lang.String transformation) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Cipher getInstance(java.lang.String transformation, java.lang.String provider) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException, java.security.NoSuchProviderException { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Cipher getInstance(java.lang.String transformation, java.security.Provider provider) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException { throw new RuntimeException("Stub!"); }
+
+public final java.security.Provider getProvider() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getAlgorithm() { throw new RuntimeException("Stub!"); }
+
+public final int getBlockSize() { throw new RuntimeException("Stub!"); }
+
+public final int getOutputSize(int inputLen) { throw new RuntimeException("Stub!"); }
+
+public final byte[] getIV() { throw new RuntimeException("Stub!"); }
+
+public final java.security.AlgorithmParameters getParameters() { throw new RuntimeException("Stub!"); }
+
+public final javax.crypto.ExemptionMechanism getExemptionMechanism() { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key, java.security.AlgorithmParameters params) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.cert.Certificate certificate) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(int opmode, java.security.cert.Certificate certificate, java.security.SecureRandom random) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final byte[] update(byte[] input) { throw new RuntimeException("Stub!"); }
+
+public final byte[] update(byte[] input, int inputOffset, int inputLen) { throw new RuntimeException("Stub!"); }
+
+public final int update(byte[] input, int inputOffset, int inputLen, byte[] output) throws javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final int update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final int update(java.nio.ByteBuffer input, java.nio.ByteBuffer output) throws javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final byte[] doFinal() throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException { throw new RuntimeException("Stub!"); }
+
+public final int doFinal(byte[] output, int outputOffset) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final byte[] doFinal(byte[] input) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException { throw new RuntimeException("Stub!"); }
+
+public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException { throw new RuntimeException("Stub!"); }
+
+public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final int doFinal(java.nio.ByteBuffer input, java.nio.ByteBuffer output) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final byte[] wrap(java.security.Key key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final java.security.Key unwrap(byte[] wrappedKey, java.lang.String wrappedKeyAlgorithm, int wrappedKeyType) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static final int getMaxAllowedKeyLength(java.lang.String transformation) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static final java.security.spec.AlgorithmParameterSpec getMaxAllowedParameterSpec(java.lang.String transformation) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public final void updateAAD(byte[] src) { throw new RuntimeException("Stub!"); }
+
+public final void updateAAD(byte[] src, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+public final void updateAAD(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public javax.crypto.CipherSpi getCurrentSpi() { throw new RuntimeException("Stub!"); }
+
+public static final int DECRYPT_MODE = 2; // 0x2
+
+public static final int ENCRYPT_MODE = 1; // 0x1
+
+public static final int PRIVATE_KEY = 2; // 0x2
+
+public static final int PUBLIC_KEY = 1; // 0x1
+
+public static final int SECRET_KEY = 3; // 0x3
+
+public static final int UNWRAP_MODE = 4; // 0x4
+
+public static final int WRAP_MODE = 3; // 0x3
+}
+
diff --git a/ojluni/annotations/mmodule/javax/crypto/Mac.annotated.java b/ojluni/annotations/mmodule/javax/crypto/Mac.annotated.java
new file mode 100644
index 0000000..a7e1995
--- /dev/null
+++ b/ojluni/annotations/mmodule/javax/crypto/Mac.annotated.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1998, 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 javax.crypto;
+
+import java.util.*;
+import java.security.*;
+import sun.security.jca.*;
+import java.nio.ByteBuffer;
+import java.security.spec.AlgorithmParameterSpec;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Mac implements java.lang.Cloneable {
+
+protected Mac(javax.crypto.MacSpi macSpi, java.security.Provider provider, java.lang.String algorithm) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getAlgorithm() { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Mac getInstance(java.lang.String algorithm) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Mac getInstance(java.lang.String algorithm, java.lang.String provider) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException { throw new RuntimeException("Stub!"); }
+
+public static final javax.crypto.Mac getInstance(java.lang.String algorithm, java.security.Provider provider) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public final java.security.Provider getProvider() { throw new RuntimeException("Stub!"); }
+
+public final int getMacLength() { throw new RuntimeException("Stub!"); }
+
+public final void init(java.security.Key key) throws java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void init(java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte input) throws java.lang.IllegalStateException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte[] input) throws java.lang.IllegalStateException { throw new RuntimeException("Stub!"); }
+
+public final void update(byte[] input, int offset, int len) throws java.lang.IllegalStateException { throw new RuntimeException("Stub!"); }
+
+public final void update(java.nio.ByteBuffer input) { throw new RuntimeException("Stub!"); }
+
+public final byte[] doFinal() throws java.lang.IllegalStateException { throw new RuntimeException("Stub!"); }
+
+public final void doFinal(byte[] output, int outOffset) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException { throw new RuntimeException("Stub!"); }
+
+public final byte[] doFinal(byte[] input) throws java.lang.IllegalStateException { throw new RuntimeException("Stub!"); }
+
+public final void reset() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public javax.crypto.MacSpi getCurrentSpi() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java b/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java
new file mode 100644
index 0000000..b09384a
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java
@@ -0,0 +1,43 @@
+/*
+ * 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 sun.misc;
+
+import java.lang.ref.*;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Cleaner extends java.lang.ref.PhantomReference<java.lang.Object> {
+
+Cleaner(java.lang.Object referent, java.lang.Runnable thunk) { super(null, null); throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static sun.misc.Cleaner create(java.lang.Object ob, java.lang.Runnable thunk) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public void clean() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/mmodule/sun/misc/Unsafe.annotated.java b/ojluni/annotations/mmodule/sun/misc/Unsafe.annotated.java
new file mode 100644
index 0000000..f272a9a
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/misc/Unsafe.annotated.java
@@ -0,0 +1,69 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Unsafe {
+
+    private Unsafe() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.CorePlatformApi
+    public static sun.misc.Unsafe getUnsafe() {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.CorePlatformApi
+    public long objectFieldOffset(java.lang.reflect.Field field) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.CorePlatformApi
+    public int arrayBaseOffset(java.lang.Class clazz) {
+        throw new RuntimeException("Stub!");
+    }
+
+    @libcore.api.CorePlatformApi
+    public native byte getByte(java.lang.Object obj, long offset);
+
+    @libcore.api.CorePlatformApi
+    public native byte getByte(long address);
+
+    @libcore.api.CorePlatformApi
+    public native long getLong(java.lang.Object obj, long offset);
+
+    @libcore.api.CorePlatformApi
+    public native long getLong(long address);
+
+    @libcore.api.CorePlatformApi
+    public native void putByte(java.lang.Object obj, long offset, byte newValue);
+
+    @libcore.api.CorePlatformApi
+    public native void putByte(long address, byte x);
+}
diff --git a/ojluni/annotations/mmodule/sun/nio/ch/DirectBuffer.annotated.java b/ojluni/annotations/mmodule/sun/nio/ch/DirectBuffer.annotated.java
new file mode 100644
index 0000000..90b9446
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/nio/ch/DirectBuffer.annotated.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2000, 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 sun.nio.ch;
+
+
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface DirectBuffer {
+
+public long address();
+
+public java.lang.Object attachment();
+
+public sun.misc.Cleaner cleaner();
+}
diff --git a/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java b/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java
new file mode 100644
index 0000000..ca8716b
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * 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 sun.security.jca;
+
+import java.security.Provider;
+import java.util.Set;
+import java.security.NoSuchAlgorithmException;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Providers {
+
+Providers() { throw new RuntimeException("Stub!"); }
+
+public static java.security.Provider getSunProvider() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.lang.Object startJarVerification() { throw new RuntimeException("Stub!"); }
+
+
+  @libcore.api.CorePlatformApi
+public static void stopJarVerification(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static sun.security.jca.ProviderList getProviderList() { throw new RuntimeException("Stub!"); }
+
+public static void setProviderList(sun.security.jca.ProviderList newList) { throw new RuntimeException("Stub!"); }
+
+public static sun.security.jca.ProviderList getFullProviderList() { throw new RuntimeException("Stub!"); }
+
+public static sun.security.jca.ProviderList getThreadProviderList() { throw new RuntimeException("Stub!"); }
+
+public static synchronized sun.security.jca.ProviderList beginThreadProviderList(sun.security.jca.ProviderList list) { throw new RuntimeException("Stub!"); }
+
+public static synchronized void endThreadProviderList(sun.security.jca.ProviderList list) { throw new RuntimeException("Stub!"); }
+
+public static void setMaximumAllowableApiLevelForBcDeprecation(int targetApiLevel) { throw new RuntimeException("Stub!"); }
+
+public static int getMaximumAllowableApiLevelForBcDeprecation() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void checkBouncyCastleDeprecation(java.lang.String provider, java.lang.String service, java.lang.String algorithm) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static synchronized void checkBouncyCastleDeprecation(java.security.Provider provider, java.lang.String service, java.lang.String algorithm) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+public static final int DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION = 27; // 0x1b
+}
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java
new file mode 100644
index 0000000..c4a0a21
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1996, 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 sun.security.pkcs;
+
+import java.io.*;
+import sun.security.util.*;
+
+/**
+ * A ContentInfo type, as defined in PKCS#7.
+ *
+ * @author Benjamin Renaud
+ */
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+public class ContentInfo {
+
+public ContentInfo(sun.security.util.ObjectIdentifier contentType, sun.security.util.DerValue content) { throw new RuntimeException("Stub!"); }
+
+/**
+ * Make a contentInfo of type data.
+ */
+
+public ContentInfo(byte[] bytes) { throw new RuntimeException("Stub!"); }
+
+/**
+ * Parses a PKCS#7 content info.
+ */
+
+public ContentInfo(sun.security.util.DerInputStream derin) throws java.io.IOException, sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+/**
+ * Parses a PKCS#7 content info.
+ *
+ * <p>This constructor is used only for backwards compatibility with
+ * PKCS#7 blocks that were generated using JDK1.1.x.
+ *
+ * @param derin the ASN.1 encoding of the content info.
+ * @param oldStyle flag indicating whether or not the given content info
+ * is encoded according to JDK1.1.x.
+ */
+
+public ContentInfo(sun.security.util.DerInputStream derin, boolean oldStyle) throws java.io.IOException, sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+public sun.security.util.DerValue getContent() { throw new RuntimeException("Stub!"); }
+
+public sun.security.util.ObjectIdentifier getContentType() { throw new RuntimeException("Stub!"); }
+
+public byte[] getData() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+/**
+ * Returns a byte array representation of the data held in
+ * the content field.
+ */
+
+@libcore.api.CorePlatformApi
+public byte[] getContentBytes() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static sun.security.util.ObjectIdentifier DATA_OID;
+
+public static sun.security.util.ObjectIdentifier DIGESTED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier ENCRYPTED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier ENVELOPED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID;
+
+public static sun.security.util.ObjectIdentifier OLD_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier OLD_SIGNED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier PKCS7_OID;
+
+public static sun.security.util.ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier SIGNED_DATA_OID;
+
+public static sun.security.util.ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID;
+}
+
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java
new file mode 100644
index 0000000..2d5cb84
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java
@@ -0,0 +1,88 @@
+/*
+ * 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 sun.security.pkcs;
+
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import sun.security.util.*;
+import sun.security.x509.AlgorithmId;
+import sun.security.x509.X500Name;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class PKCS7 {
+
+@libcore.api.CorePlatformApi
+public PKCS7(java.io.InputStream in) throws java.io.IOException, sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+public PKCS7(sun.security.util.DerInputStream derin) throws sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public PKCS7(byte[] bytes) throws sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+public PKCS7(sun.security.x509.AlgorithmId[] digestAlgorithmIds, sun.security.pkcs.ContentInfo contentInfo, java.security.cert.X509Certificate[] certificates, java.security.cert.X509CRL[] crls, sun.security.pkcs.SignerInfo[] signerInfos) { throw new RuntimeException("Stub!"); }
+
+public PKCS7(sun.security.x509.AlgorithmId[] digestAlgorithmIds, sun.security.pkcs.ContentInfo contentInfo, java.security.cert.X509Certificate[] certificates, sun.security.pkcs.SignerInfo[] signerInfos) { throw new RuntimeException("Stub!"); }
+
+public void encodeSignedData(java.io.OutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void encodeSignedData(sun.security.util.DerOutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public sun.security.pkcs.SignerInfo verify(sun.security.pkcs.SignerInfo info, byte[] bytes) throws java.security.NoSuchAlgorithmException, java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public sun.security.pkcs.SignerInfo verify(sun.security.pkcs.SignerInfo info, java.io.InputStream dataInputStream) throws java.io.IOException, java.security.NoSuchAlgorithmException, java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public sun.security.pkcs.SignerInfo[] verify(byte[] bytes) throws java.security.NoSuchAlgorithmException, java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public sun.security.pkcs.SignerInfo[] verify() throws java.security.NoSuchAlgorithmException, java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public java.math.BigInteger getVersion() { throw new RuntimeException("Stub!"); }
+
+public sun.security.x509.AlgorithmId[] getDigestAlgorithmIds() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public sun.security.pkcs.ContentInfo getContentInfo() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.security.cert.X509Certificate[] getCertificates() { throw new RuntimeException("Stub!"); }
+
+public java.security.cert.X509CRL[] getCRLs() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public sun.security.pkcs.SignerInfo[] getSignerInfos() { throw new RuntimeException("Stub!"); }
+
+public java.security.cert.X509Certificate getCertificate(java.math.BigInteger serial, sun.security.x509.X500Name issuerName) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public boolean isOldStyle() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java
new file mode 100644
index 0000000..ab44b06
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1996, 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.
+ */
+
+/**
+ * Generic PKCS Parsing exception.
+ *
+ * @author Benjamin Renaud
+ */
+
+
+package sun.security.pkcs;
+
+@libcore.api.Hide
+@libcore.api.CorePlatformApi
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ParsingException extends java.io.IOException {
+
+public ParsingException() { throw new RuntimeException("Stub!"); }
+
+public ParsingException(java.lang.String s) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java
new file mode 100644
index 0000000..b929e2e
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.security.pkcs;
+
+import sun.security.util.DerEncoder;
+import java.io.IOException;
+
+@libcore.api.CorePlatformApi
+@libcore.api.Hide
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class SignerInfo implements sun.security.util.DerEncoder {
+
+@libcore.api.CorePlatformApi
+public SignerInfo() { throw new RuntimeException("Stub!"); }
+
+public SignerInfo(sun.security.x509.X500Name issuerName, java.math.BigInteger serial, sun.security.x509.AlgorithmId digestAlgorithmId, sun.security.x509.AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest) { throw new RuntimeException("Stub!"); }
+
+public SignerInfo(sun.security.x509.X500Name issuerName, java.math.BigInteger serial, sun.security.x509.AlgorithmId digestAlgorithmId, sun.security.pkcs.PKCS9Attributes authenticatedAttributes, sun.security.x509.AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest, sun.security.pkcs.PKCS9Attributes unauthenticatedAttributes) { throw new RuntimeException("Stub!"); }
+
+public SignerInfo(sun.security.util.DerInputStream derin) throws java.io.IOException, sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+public SignerInfo(sun.security.util.DerInputStream derin, boolean oldStyle) throws java.io.IOException, sun.security.pkcs.ParsingException { throw new RuntimeException("Stub!"); }
+
+public void encode(sun.security.util.DerOutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void derEncode(java.io.OutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.security.cert.X509Certificate getCertificate(sun.security.pkcs.PKCS7 block) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.util.ArrayList<java.security.cert.X509Certificate> getCertificateChain(sun.security.pkcs.PKCS7 block) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.math.BigInteger getVersion() { throw new RuntimeException("Stub!"); }
+
+public sun.security.x509.X500Name getIssuerName() { throw new RuntimeException("Stub!"); }
+
+public java.math.BigInteger getCertificateSerialNumber() { throw new RuntimeException("Stub!"); }
+
+public sun.security.x509.AlgorithmId getDigestAlgorithmId() { throw new RuntimeException("Stub!"); }
+
+public sun.security.pkcs.PKCS9Attributes getAuthenticatedAttributes() { throw new RuntimeException("Stub!"); }
+
+public sun.security.x509.AlgorithmId getDigestEncryptionAlgorithmId() { throw new RuntimeException("Stub!"); }
+
+public byte[] getEncryptedDigest() { throw new RuntimeException("Stub!"); }
+
+public sun.security.pkcs.PKCS9Attributes getUnauthenticatedAttributes() { throw new RuntimeException("Stub!"); }
+
+public sun.security.pkcs.PKCS7 getTsToken() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.security.Timestamp getTimestamp() throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException, java.security.SignatureException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/mmodule/sun/util/locale/LanguageTag.annotated.java b/ojluni/annotations/mmodule/sun/util/locale/LanguageTag.annotated.java
new file mode 100644
index 0000000..eaec071
--- /dev/null
+++ b/ojluni/annotations/mmodule/sun/util/locale/LanguageTag.annotated.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/*
+ *******************************************************************************
+ * Copyright (C) 2010, International Business Machines Corporation and         *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+package sun.util.locale;
+
+@libcore.api.Hide
+@libcore.api.CorePlatformApi
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class LanguageTag {
+
+LanguageTag() { throw new RuntimeException("Stub!"); }
+
+public static sun.util.locale.LanguageTag parse(java.lang.String languageTag, sun.util.locale.ParseStatus sts) { throw new RuntimeException("Stub!"); }
+
+public static sun.util.locale.LanguageTag parseLocale(sun.util.locale.BaseLocale baseLocale, sun.util.locale.LocaleExtensions localeExtensions) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getLanguage() { throw new RuntimeException("Stub!"); }
+
+public java.util.List<java.lang.String> getExtlangs() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getScript() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getRegion() { throw new RuntimeException("Stub!"); }
+
+public java.util.List<java.lang.String> getVariants() { throw new RuntimeException("Stub!"); }
+
+public java.util.List<java.lang.String> getExtensions() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getPrivateuse() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static boolean isLanguage(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isExtlang(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isScript(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isRegion(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isVariant(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isExtensionSingleton(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isExtensionSingletonChar(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isExtensionSubtag(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isPrivateusePrefix(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean isPrivateusePrefixChar(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isPrivateuseSubtag(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeLanguage(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeExtlang(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeScript(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeRegion(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeVariant(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeExtension(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeExtensionSingleton(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizeExtensionSubtag(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizePrivateuse(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String canonicalizePrivateuseSubtag(java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.String PRIVATEUSE = "x";
+
+public static final java.lang.String PRIVUSE_VARIANT_PREFIX = "lvariant";
+
+public static final java.lang.String SEP = "-";
+
+public static final java.lang.String UNDETERMINED = "und";
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/io/ByteArrayOutputStream.annotated.java b/ojluni/annotations/sdk/nullability/java/io/ByteArrayOutputStream.annotated.java
new file mode 100644
index 0000000..3fdca11
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/io/ByteArrayOutputStream.annotated.java
@@ -0,0 +1,61 @@
+/*
+ * 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.io;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ByteArrayOutputStream extends java.io.OutputStream {
+
+public ByteArrayOutputStream() { throw new RuntimeException("Stub!"); }
+
+public ByteArrayOutputStream(int size) { throw new RuntimeException("Stub!"); }
+
+public synchronized void write(int b) { throw new RuntimeException("Stub!"); }
+
+public synchronized void write(byte @libcore.util.NonNull [] b, int off, int len) { throw new RuntimeException("Stub!"); }
+
+public synchronized void writeTo(@libcore.util.NonNull java.io.OutputStream out) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void reset() { throw new RuntimeException("Stub!"); }
+
+public synchronized byte @libcore.util.NonNull [] toByteArray() { throw new RuntimeException("Stub!"); }
+
+public synchronized int size() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String toString(@libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+@libcore.util.NonNull public synchronized java.lang.String toString(int hibyte) { throw new RuntimeException("Stub!"); }
+
+public void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+protected byte @libcore.util.NonNull [] buf;
+
+protected int count;
+}
diff --git a/ojluni/annotations/sdk/nullability/java/io/File.annotated.java b/ojluni/annotations/sdk/nullability/java/io/File.annotated.java
new file mode 100644
index 0000000..497c434
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/io/File.annotated.java
@@ -0,0 +1,159 @@
+/*
+ * 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.io;
+
+import java.nio.file.Path;
+import java.net.URI;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.FileSystems;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class File implements java.io.Serializable, java.lang.Comparable<java.io.File> {
+
+public File(@libcore.util.NonNull java.lang.String pathname) { throw new RuntimeException("Stub!"); }
+
+public File(@libcore.util.Nullable java.lang.String parent, @libcore.util.NonNull java.lang.String child) { throw new RuntimeException("Stub!"); }
+
+public File(@libcore.util.Nullable java.io.File parent, @libcore.util.NonNull java.lang.String child) { throw new RuntimeException("Stub!"); }
+
+public File(@libcore.util.NonNull java.net.URI uri) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getParent() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.io.File getParentFile() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getPath() { throw new RuntimeException("Stub!"); }
+
+public boolean isAbsolute() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getAbsolutePath() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.File getAbsoluteFile() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getCanonicalPath() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.io.File getCanonicalFile() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+@libcore.util.NonNull public java.net.URL toURL() throws java.net.MalformedURLException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.net.URI toURI() { throw new RuntimeException("Stub!"); }
+
+public boolean canRead() { throw new RuntimeException("Stub!"); }
+
+public boolean canWrite() { throw new RuntimeException("Stub!"); }
+
+public boolean exists() { throw new RuntimeException("Stub!"); }
+
+public boolean isDirectory() { throw new RuntimeException("Stub!"); }
+
+public boolean isFile() { throw new RuntimeException("Stub!"); }
+
+public boolean isHidden() { throw new RuntimeException("Stub!"); }
+
+public long lastModified() { throw new RuntimeException("Stub!"); }
+
+public long length() { throw new RuntimeException("Stub!"); }
+
+public boolean createNewFile() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public boolean delete() { throw new RuntimeException("Stub!"); }
+
+public void deleteOnExit() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.Nullable [] list() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.Nullable [] list(@libcore.util.Nullable java.io.FilenameFilter filter) { throw new RuntimeException("Stub!"); }
+
+public java.io.@libcore.util.NonNull File @libcore.util.Nullable [] listFiles() { throw new RuntimeException("Stub!"); }
+
+public java.io.@libcore.util.NonNull File @libcore.util.Nullable [] listFiles(@libcore.util.Nullable java.io.FilenameFilter filter) { throw new RuntimeException("Stub!"); }
+
+public java.io.@libcore.util.NonNull File @libcore.util.Nullable [] listFiles(@libcore.util.Nullable java.io.FileFilter filter) { throw new RuntimeException("Stub!"); }
+
+public boolean mkdir() { throw new RuntimeException("Stub!"); }
+
+public boolean mkdirs() { throw new RuntimeException("Stub!"); }
+
+public boolean renameTo(@libcore.util.NonNull java.io.File dest) { throw new RuntimeException("Stub!"); }
+
+public boolean setLastModified(long time) { throw new RuntimeException("Stub!"); }
+
+public boolean setReadOnly() { throw new RuntimeException("Stub!"); }
+
+public boolean setWritable(boolean writable, boolean ownerOnly) { throw new RuntimeException("Stub!"); }
+
+public boolean setWritable(boolean writable) { throw new RuntimeException("Stub!"); }
+
+public boolean setReadable(boolean readable, boolean ownerOnly) { throw new RuntimeException("Stub!"); }
+
+public boolean setReadable(boolean readable) { throw new RuntimeException("Stub!"); }
+
+public boolean setExecutable(boolean executable, boolean ownerOnly) { throw new RuntimeException("Stub!"); }
+
+public boolean setExecutable(boolean executable) { throw new RuntimeException("Stub!"); }
+
+public boolean canExecute() { throw new RuntimeException("Stub!"); }
+
+public static java.io.@libcore.util.NonNull File @libcore.util.NonNull [] listRoots() { throw new RuntimeException("Stub!"); }
+
+public long getTotalSpace() { throw new RuntimeException("Stub!"); }
+
+public long getFreeSpace() { throw new RuntimeException("Stub!"); }
+
+public long getUsableSpace() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.io.File createTempFile(@libcore.util.NonNull java.lang.String prefix, @libcore.util.Nullable java.lang.String suffix, @libcore.util.Nullable java.io.File directory) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.io.File createTempFile(@libcore.util.NonNull java.lang.String prefix, @libcore.util.Nullable java.lang.String suffix) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.io.File pathname) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable 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.nio.file.Path toPath() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.lang.String pathSeparator;
+static { pathSeparator = null; }
+
+public static final char pathSeparatorChar;
+static { pathSeparatorChar = 0; }
+
+@libcore.util.NonNull public static final java.lang.String separator;
+static { separator = null; }
+
+public static final char separatorChar;
+static { separatorChar = 0; }
+}
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/annotations/sdk/nullability/java/lang/Appendable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
new file mode 100644
index 0000000..0ef58db
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Appendable.annotated.java
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * 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.IOException;
+
+@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;
+}
+
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/annotations/sdk/nullability/java/lang/CharSequence.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
new file mode 100644
index 0000000..e61d5d4
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/CharSequence.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * 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.stream.IntStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface CharSequence {
+
+public int length();
+
+public char charAt(int index);
+
+@libcore.util.NonNull public java.lang.CharSequence subSequence(int start, int end);
+
+@libcore.util.NonNull public java.lang.String toString();
+
+@libcore.util.NonNull public default java.util.stream.IntStream chars() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public default java.util.stream.IntStream codePoints() { throw new RuntimeException("Stub!"); }
+}
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..5cbfa49
--- /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!"); }
+
+@libcore.util.NonNull 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..b49785e
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Enum.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * 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(@libcore.util.NonNull java.lang.String name, int ordinal) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String name() { throw new RuntimeException("Stub!"); }
+
+public final int ordinal() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object other) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public final int compareTo(@libcore.util.NullFromTypeParam E o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.Class<E> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T extends java.lang.Enum<T>> T valueOf(@libcore.util.NonNull java.lang.Class<T> enumType, @libcore.util.NonNull 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/annotations/sdk/nullability/java/lang/Iterable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
new file mode 100644
index 0000000..8986b35
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Iterable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import libcore.util.NonNull;
+import libcore.util.NullFromTypeParam;
+
+public interface Iterable<T> {
+
+  public @NonNull Iterator<@NullFromTypeParam T> iterator();
+  public default void forEach(@NonNull Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+  @NonNull 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..45939e8
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Object.annotated.java
@@ -0,0 +1,57 @@
+/*
+ * 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!"); }
+
+@libcore.util.NonNull 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..b39f09a
--- /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, @libcore.util.NonNull 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..6b21f17
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Thread.annotated.java
@@ -0,0 +1,164 @@
+/*
+ * 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(@libcore.util.Nullable java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.Nullable java.lang.ThreadGroup group, @libcore.util.Nullable java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.Nullable java.lang.ThreadGroup group, @libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.Nullable java.lang.Runnable target, @libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.Nullable java.lang.ThreadGroup group, @libcore.util.Nullable java.lang.Runnable target, @libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(@libcore.util.Nullable java.lang.ThreadGroup group, @libcore.util.Nullable java.lang.Runnable target, @libcore.util.NonNull 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!"); }
+
+@libcore.util.NonNull 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(@libcore.util.Nullable 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(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable 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!"); }
+
+@libcore.util.Nullable public java.lang.ClassLoader getContextClassLoader() { throw new RuntimeException("Stub!"); }
+
+public void setContextClassLoader(@libcore.util.Nullable java.lang.ClassLoader cl) { throw new RuntimeException("Stub!"); }
+
+public static native boolean holdsLock(@libcore.util.NonNull java.lang.Object obj);
+
+public java.lang.@libcore.util.NonNull StackTraceElement @libcore.util.NonNull [] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Map<@libcore.util.NonNull java.lang.Thread,java.lang.@libcore.util.NonNull StackTraceElement @libcore.util.NonNull []> getAllStackTraces() { throw new RuntimeException("Stub!"); }
+
+public long getId() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Thread.State getState() { throw new RuntimeException("Stub!"); }
+
+public static void setDefaultUncaughtExceptionHandler(@libcore.util.Nullable java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public void setUncaughtExceptionHandler(@libcore.util.Nullable 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(@libcore.util.NonNull java.lang.Thread t, @libcore.util.NonNull 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/Throwable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Throwable.annotated.java
new file mode 100644
index 0000000..f6cef0c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/Throwable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * 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.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Throwable implements java.io.Serializable {
+
+public Throwable() { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+protected Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause, boolean enableSuppression, boolean writableStackTrace) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getMessage() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getLocalizedMessage() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public synchronized java.lang.Throwable getCause() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.Throwable initCause(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintStream s) { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintWriter s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.Throwable fillInStackTrace() { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull StackTraceElement @libcore.util.NonNull [] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void setStackTrace(java.lang.@libcore.util.NonNull StackTraceElement @libcore.util.NonNull [] stackTrace) { throw new RuntimeException("Stub!"); }
+
+public final synchronized void addSuppressed(@libcore.util.NonNull java.lang.Throwable exception) { throw new RuntimeException("Stub!"); }
+
+public final synchronized java.lang.@libcore.util.NonNull Throwable @libcore.util.NonNull [] getSuppressed() { 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..f601635
--- /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!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> 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 <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull 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!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull 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..97cb3a2
--- /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(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull 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(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull 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..f0fba5c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Array.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * 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(@libcore.util.NonNull java.lang.Class<?> componentType, int length) throws java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newInstance(@libcore.util.NonNull java.lang.Class<?> componentType, int... dimensions) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+public static int getLength(@libcore.util.NonNull java.lang.Object array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.Object get(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static byte getByte(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static char getChar(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static short getShort(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static int getInt(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static long getLong(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static float getFloat(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static double getDouble(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void set(@libcore.util.NonNull java.lang.Object array, int index, @libcore.util.Nullable java.lang.Object value) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setBoolean(@libcore.util.NonNull java.lang.Object array, int index, boolean z) { throw new RuntimeException("Stub!"); }
+
+public static void setByte(@libcore.util.NonNull java.lang.Object array, int index, byte b) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setChar(@libcore.util.NonNull java.lang.Object array, int index, char c) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setShort(@libcore.util.NonNull java.lang.Object array, int index, short s) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setInt(@libcore.util.NonNull java.lang.Object array, int index, int i) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setLong(@libcore.util.NonNull java.lang.Object array, int index, long l) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setFloat(@libcore.util.NonNull java.lang.Object array, int index, float f) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setDouble(@libcore.util.NonNull 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..58bd810
--- /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(@libcore.util.Nullable 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!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull 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..4b5b841
--- /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();
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull getjava.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull 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(@libcore.util.NonNull 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..8a26ce3
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Field.annotated.java
@@ -0,0 +1,101 @@
+/*
+ * 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!"); }
+
+@libcore.util.NonNull 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!"); }
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable 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.Nullable public native java.lang.Object get(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native boolean getBoolean(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native byte getByte(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native char getChar(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native short getShort(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native int getInt(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native long getLong(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native float getFloat(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native double getDouble(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void set(@libcore.util.Nullable java.lang.Object obj, @libcore.util.Nullable java.lang.Object value) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setBoolean(@libcore.util.Nullable java.lang.Object obj, boolean z) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setByte(@libcore.util.Nullable java.lang.Object obj, byte b) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setChar(@libcore.util.Nullable java.lang.Object obj, char c) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setShort(@libcore.util.Nullable java.lang.Object obj, short s) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setInt(@libcore.util.Nullable java.lang.Object obj, int i) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setLong(@libcore.util.Nullable java.lang.Object obj, long l) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setFloat(@libcore.util.Nullable java.lang.Object obj, float f) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setDouble(@libcore.util.Nullable java.lang.Object obj, double d) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
new file mode 100644
index 0000000..c173408
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericArrayType.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * 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
+ * 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 interface GenericArrayType extends java.lang.reflect.Type {
+
+@libcore.util.NonNull public java.lang.reflect.Type getGenericComponentType();
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
new file mode 100644
index 0000000..3614d84
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/GenericDeclaration.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+
+@libcore.util.NonNull public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
new file mode 100644
index 0000000..0552ce2
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Member.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * 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 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
+}
+
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..004a5ed
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Method.annotated.java
@@ -0,0 +1,83 @@
+/*
+ * 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!"); }
+
+@libcore.util.NonNull 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(@libcore.util.Nullable 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.Nullable public native java.lang.Object invoke(@libcore.util.Nullable java.lang.Object obj, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable ... 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!"); }
+
+@libcore.util.Nullable public native java.lang.Object getDefaultValue();
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull 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..247db53
--- /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(@libcore.util.Nullable 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!"); }
+
+@libcore.util.NonNull 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!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull 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!"); }
+
+@libcore.util.Nullable public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull 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/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
new file mode 100644
index 0000000..1502d68
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/ParameterizedType.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * 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 interface ParameterizedType extends java.lang.reflect.Type {
+
+public java.lang.reflect.@libcore.util.NonNull Type @libcore.util.NonNull [] getActualTypeArguments();
+
+@libcore.util.NonNull public java.lang.reflect.Type getRawType();
+
+@libcore.util.Nullable 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..eb396c7
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Proxy.annotated.java
@@ -0,0 +1,46 @@
+/*
+ * 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(@libcore.util.NonNull java.lang.reflect.InvocationHandler h) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Class<?> getProxyClass(@libcore.util.Nullable java.lang.ClassLoader loader, java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull ... interfaces) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.Object newProxyInstance(@libcore.util.Nullable java.lang.ClassLoader loader, java.lang.@libcore.util.NonNull Class<?> @libcore.util.NonNull [] interfaces, @libcore.util.NonNull java.lang.reflect.InvocationHandler h) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean isProxyClass(@libcore.util.NonNull java.lang.Class<?> cl) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(@libcore.util.NonNull java.lang.Object proxy) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.reflect.InvocationHandler h;
+}
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
new file mode 100644
index 0000000..f2b646b
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/Type.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Type {
+
+@libcore.util.NonNull public default java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
new file mode 100644
index 0000000..5654963
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/TypeVariable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
+
+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/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
new file mode 100644
index 0000000..c8b90a0
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/lang/reflect/WildcardType.annotated.java
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * 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 interface WildcardType extends java.lang.reflect.Type {
+
+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/nio/ByteBuffer.annotated.java b/ojluni/annotations/sdk/nullability/java/nio/ByteBuffer.annotated.java
new file mode 100644
index 0000000..30c82ec
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/nio/ByteBuffer.annotated.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * 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
+ * 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.nio;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+
+ByteBuffer(int mark, int pos, int lim, int cap) { super(0, 0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.nio.ByteBuffer allocateDirect(int capacity) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.nio.ByteBuffer allocate(int capacity) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.nio.ByteBuffer wrap(byte @libcore.util.NonNull [] array, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.nio.ByteBuffer wrap(byte @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer slice();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer duplicate();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+
+public abstract byte get();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer put(byte b);
+
+public abstract byte get(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer put(int index, byte b);
+
+@libcore.util.NonNull public java.nio.ByteBuffer get(byte @libcore.util.NonNull [] dst, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.ByteBuffer get(byte @libcore.util.NonNull [] dst) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.ByteBuffer put(@libcore.util.NonNull java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.ByteBuffer put(byte @libcore.util.NonNull [] src, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.nio.ByteBuffer put(byte @libcore.util.NonNull [] src) { throw new RuntimeException("Stub!"); }
+
+public final boolean hasArray() { throw new RuntimeException("Stub!"); }
+
+public final byte @libcore.util.NonNull [] array() { throw new RuntimeException("Stub!"); }
+
+public final int arrayOffset() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer position(int newPosition) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer limit(int newLimit) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer mark() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer reset() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer clear() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer flip() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.nio.Buffer rewind() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer compact();
+
+public abstract boolean isDirect();
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object ob) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.nio.ByteBuffer that) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.nio.ByteOrder order() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.nio.ByteBuffer order(@libcore.util.NonNull java.nio.ByteOrder bo) { throw new RuntimeException("Stub!"); }
+
+public abstract char getChar();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putChar(char value);
+
+public abstract char getChar(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putChar(int index, char value);
+
+@libcore.util.NonNull public abstract java.nio.CharBuffer asCharBuffer();
+
+public abstract short getShort();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putShort(short value);
+
+public abstract short getShort(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putShort(int index, short value);
+
+@libcore.util.NonNull public abstract java.nio.ShortBuffer asShortBuffer();
+
+public abstract int getInt();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putInt(int value);
+
+public abstract int getInt(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putInt(int index, int value);
+
+@libcore.util.NonNull public abstract java.nio.IntBuffer asIntBuffer();
+
+public abstract long getLong();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putLong(long value);
+
+public abstract long getLong(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putLong(int index, long value);
+
+@libcore.util.NonNull public abstract java.nio.LongBuffer asLongBuffer();
+
+public abstract float getFloat();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putFloat(float value);
+
+public abstract float getFloat(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putFloat(int index, float value);
+
+@libcore.util.NonNull public abstract java.nio.FloatBuffer asFloatBuffer();
+
+public abstract double getDouble();
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putDouble(double value);
+
+public abstract double getDouble(int index);
+
+@libcore.util.NonNull public abstract java.nio.ByteBuffer putDouble(int index, double value);
+
+@libcore.util.NonNull public abstract java.nio.DoubleBuffer asDoubleBuffer();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/security/MessageDigest.annotated.java b/ojluni/annotations/sdk/nullability/java/security/MessageDigest.annotated.java
new file mode 100644
index 0000000..7ffbc1c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/security/MessageDigest.annotated.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1996, 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.security;
+
+import java.util.*;
+import java.lang.*;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class MessageDigest extends java.security.MessageDigestSpi {
+
+protected MessageDigest(@libcore.util.NonNull java.lang.String algorithm) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.security.MessageDigest getInstance(@libcore.util.NonNull java.lang.String algorithm) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.security.MessageDigest getInstance(@libcore.util.NonNull java.lang.String algorithm, @libcore.util.NonNull java.lang.String provider) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.security.MessageDigest getInstance(@libcore.util.NonNull java.lang.String algorithm, @libcore.util.NonNull java.security.Provider provider) throws java.security.NoSuchAlgorithmException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.security.Provider getProvider() { throw new RuntimeException("Stub!"); }
+
+public void update(byte input) { throw new RuntimeException("Stub!"); }
+
+public void update(byte @libcore.util.NonNull [] input, int offset, int len) { throw new RuntimeException("Stub!"); }
+
+public void update(byte @libcore.util.NonNull [] input) { throw new RuntimeException("Stub!"); }
+
+public final void update(@libcore.util.NonNull java.nio.ByteBuffer input) { throw new RuntimeException("Stub!"); }
+
+public byte @libcore.util.NonNull [] digest() { throw new RuntimeException("Stub!"); }
+
+public int digest(byte @libcore.util.NonNull [] buf, int offset, int len) throws java.security.DigestException { throw new RuntimeException("Stub!"); }
+
+public byte @libcore.util.NonNull [] digest(byte @libcore.util.NonNull [] input) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static boolean isEqual(byte @libcore.util.Nullable [] digesta, byte @libcore.util.Nullable [] digestb) { throw new RuntimeException("Stub!"); }
+
+public void reset() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String getAlgorithm() { throw new RuntimeException("Stub!"); }
+
+public final int getDigestLength() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/text/DateFormat.annotated.java b/ojluni/annotations/sdk/nullability/java/text/DateFormat.annotated.java
new file mode 100644
index 0000000..13e11a3
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/text/DateFormat.annotated.java
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.text;
+
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Calendar;
+import java.util.Date;
+import java.io.InvalidObjectException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class DateFormat extends java.text.Format {
+
+protected DateFormat() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.StringBuffer format(@libcore.util.NonNull java.lang.Object obj, @libcore.util.NonNull java.lang.StringBuffer toAppendTo, @libcore.util.NonNull java.text.FieldPosition fieldPosition) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.StringBuffer format(@libcore.util.NonNull java.util.Date date, @libcore.util.NonNull java.lang.StringBuffer toAppendTo, @libcore.util.NonNull java.text.FieldPosition fieldPosition);
+
+@libcore.util.NonNull public final java.lang.String format(@libcore.util.NonNull java.util.Date date) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Date parse(@libcore.util.NonNull java.lang.String source) throws java.text.ParseException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public abstract java.util.Date parse(@libcore.util.NonNull java.lang.String source, @libcore.util.NonNull java.text.ParsePosition pos);
+
+@libcore.util.Nullable public java.lang.Object parseObject(@libcore.util.NonNull java.lang.String source, @libcore.util.NonNull java.text.ParsePosition pos) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getTimeInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getTimeInstance(int style) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getTimeInstance(int style, @libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateInstance(int style) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateInstance(int style, @libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateTimeInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle, @libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat getInstance() { throw new RuntimeException("Stub!"); }
+
+public static java.util.@libcore.util.NonNull Locale @libcore.util.NonNull [] getAvailableLocales() { throw new RuntimeException("Stub!"); }
+
+public void setCalendar(@libcore.util.NonNull java.util.Calendar newCalendar) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar getCalendar() { throw new RuntimeException("Stub!"); }
+
+public void setNumberFormat(@libcore.util.NonNull java.text.NumberFormat newNumberFormat) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.text.NumberFormat getNumberFormat() { throw new RuntimeException("Stub!"); }
+
+public void setTimeZone(@libcore.util.NonNull java.util.TimeZone zone) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.TimeZone getTimeZone() { throw new RuntimeException("Stub!"); }
+
+public void setLenient(boolean lenient) { throw new RuntimeException("Stub!"); }
+
+public boolean isLenient() { 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!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public static final int AM_PM_FIELD = 14; // 0xe
+
+public static final int DATE_FIELD = 3; // 0x3
+
+public static final int DAY_OF_WEEK_FIELD = 9; // 0x9
+
+public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; // 0xb
+
+public static final int DAY_OF_YEAR_FIELD = 10; // 0xa
+
+public static final int DEFAULT = 2; // 0x2
+
+public static final int ERA_FIELD = 0; // 0x0
+
+public static final int FULL = 0; // 0x0
+
+public static final int HOUR0_FIELD = 16; // 0x10
+
+public static final int HOUR1_FIELD = 15; // 0xf
+
+public static final int HOUR_OF_DAY0_FIELD = 5; // 0x5
+
+public static final int HOUR_OF_DAY1_FIELD = 4; // 0x4
+
+public static final int LONG = 1; // 0x1
+
+public static final int MEDIUM = 2; // 0x2
+
+public static final int MILLISECOND_FIELD = 8; // 0x8
+
+public static final int MINUTE_FIELD = 6; // 0x6
+
+public static final int MONTH_FIELD = 2; // 0x2
+
+public static final int SECOND_FIELD = 7; // 0x7
+
+public static final int SHORT = 3; // 0x3
+
+public static final int TIMEZONE_FIELD = 17; // 0x11
+
+public static final int WEEK_OF_MONTH_FIELD = 13; // 0xd
+
+public static final int WEEK_OF_YEAR_FIELD = 12; // 0xc
+
+public static final int YEAR_FIELD = 1; // 0x1
+
+@libcore.util.NonNull protected java.util.Calendar calendar;
+
+@libcore.util.NonNull protected java.text.NumberFormat numberFormat;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Field extends java.text.Format.Field {
+
+protected Field(@libcore.util.NonNull java.lang.String name, int calendarField) { super(null); throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.DateFormat.Field ofCalendarField(int calendarField) { throw new RuntimeException("Stub!"); }
+
+public int getCalendarField() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull protected java.lang.Object readResolve() throws java.io.InvalidObjectException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field AM_PM;
+static { AM_PM = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field DAY_OF_MONTH;
+static { DAY_OF_MONTH = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK;
+static { DAY_OF_WEEK = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK_IN_MONTH;
+static { DAY_OF_WEEK_IN_MONTH = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field DAY_OF_YEAR;
+static { DAY_OF_YEAR = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field ERA;
+static { ERA = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field HOUR0;
+static { HOUR0 = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field HOUR1;
+static { HOUR1 = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY0;
+static { HOUR_OF_DAY0 = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY1;
+static { HOUR_OF_DAY1 = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field MILLISECOND;
+static { MILLISECOND = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field MINUTE;
+static { MINUTE = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field MONTH;
+static { MONTH = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field SECOND;
+static { SECOND = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field TIME_ZONE;
+static { TIME_ZONE = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field WEEK_OF_MONTH;
+static { WEEK_OF_MONTH = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field WEEK_OF_YEAR;
+static { WEEK_OF_YEAR = null; }
+
+@libcore.util.NonNull public static final java.text.DateFormat.Field YEAR;
+static { YEAR = null; }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/text/NumberFormat.annotated.java b/ojluni/annotations/sdk/nullability/java/text/NumberFormat.annotated.java
new file mode 100644
index 0000000..7f51005
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/text/NumberFormat.annotated.java
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.text;
+
+import java.util.Locale;
+import java.util.Currency;
+import java.math.RoundingMode;
+import java.math.BigInteger;
+import java.io.InvalidObjectException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class NumberFormat extends java.text.Format {
+
+protected NumberFormat() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer format(@libcore.util.NonNull java.lang.Object number, @libcore.util.NonNull java.lang.StringBuffer toAppendTo, @libcore.util.NonNull java.text.FieldPosition pos) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public final java.lang.Object parseObject(@libcore.util.NonNull java.lang.String source, @libcore.util.NonNull java.text.ParsePosition pos) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String format(double number) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String format(long number) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.lang.StringBuffer format(double number, @libcore.util.NonNull java.lang.StringBuffer toAppendTo, @libcore.util.NonNull java.text.FieldPosition pos);
+
+@libcore.util.NonNull public abstract java.lang.StringBuffer format(long number, @libcore.util.NonNull java.lang.StringBuffer toAppendTo, @libcore.util.NonNull java.text.FieldPosition pos);
+
+@libcore.util.Nullable public abstract java.lang.Number parse(@libcore.util.NonNull java.lang.String source, @libcore.util.NonNull java.text.ParsePosition parsePosition);
+
+@libcore.util.Nullable public java.lang.Number parse(@libcore.util.NonNull java.lang.String source) throws java.text.ParseException { throw new RuntimeException("Stub!"); }
+
+public boolean isParseIntegerOnly() { throw new RuntimeException("Stub!"); }
+
+public void setParseIntegerOnly(boolean value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat getInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.NumberFormat getInstance(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat getNumberInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.NumberFormat getNumberInstance(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat getIntegerInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.NumberFormat getIntegerInstance(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat getCurrencyInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.NumberFormat getCurrencyInstance(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat getPercentInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.text.NumberFormat getPercentInstance(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+public static java.util.@libcore.util.NonNull Locale @libcore.util.NonNull [] getAvailableLocales() { 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!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public boolean isGroupingUsed() { throw new RuntimeException("Stub!"); }
+
+public void setGroupingUsed(boolean newValue) { throw new RuntimeException("Stub!"); }
+
+public int getMaximumIntegerDigits() { throw new RuntimeException("Stub!"); }
+
+public void setMaximumIntegerDigits(int newValue) { throw new RuntimeException("Stub!"); }
+
+public int getMinimumIntegerDigits() { throw new RuntimeException("Stub!"); }
+
+public void setMinimumIntegerDigits(int newValue) { throw new RuntimeException("Stub!"); }
+
+public int getMaximumFractionDigits() { throw new RuntimeException("Stub!"); }
+
+public void setMaximumFractionDigits(int newValue) { throw new RuntimeException("Stub!"); }
+
+public int getMinimumFractionDigits() { throw new RuntimeException("Stub!"); }
+
+public void setMinimumFractionDigits(int newValue) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Currency getCurrency() { throw new RuntimeException("Stub!"); }
+
+public void setCurrency(@libcore.util.NonNull java.util.Currency currency) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.math.RoundingMode getRoundingMode() { throw new RuntimeException("Stub!"); }
+
+public void setRoundingMode(@libcore.util.Nullable java.math.RoundingMode roundingMode) { throw new RuntimeException("Stub!"); }
+
+public static final int FRACTION_FIELD = 1; // 0x1
+
+public static final int INTEGER_FIELD = 0; // 0x0
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Field extends java.text.Format.Field {
+
+protected Field(@libcore.util.NonNull java.lang.String name) { super(null); throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull protected java.lang.Object readResolve() throws java.io.InvalidObjectException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field CURRENCY;
+static { CURRENCY = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field DECIMAL_SEPARATOR;
+static { DECIMAL_SEPARATOR = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field EXPONENT;
+static { EXPONENT = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field EXPONENT_SIGN;
+static { EXPONENT_SIGN = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field EXPONENT_SYMBOL;
+static { EXPONENT_SYMBOL = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field FRACTION;
+static { FRACTION = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field GROUPING_SEPARATOR;
+static { GROUPING_SEPARATOR = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field INTEGER;
+static { INTEGER = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field PERCENT;
+static { PERCENT = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field PERMILLE;
+static { PERMILLE = null; }
+
+@libcore.util.NonNull public static final java.text.NumberFormat.Field SIGN;
+static { SIGN = null; }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/AbstractCollection.annotated.java b/ojluni/annotations/sdk/nullability/java/util/AbstractCollection.annotated.java
new file mode 100644
index 0000000..529e351
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/AbstractCollection.annotated.java
@@ -0,0 +1,62 @@
+/*
+ * 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 abstract class AbstractCollection<E> implements java.util.Collection<E> {
+
+protected AbstractCollection() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+public abstract int size();
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c) { 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 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!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/AbstractList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/AbstractList.annotated.java
new file mode 100644
index 0000000..ed89f7b
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/AbstractList.annotated.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 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.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class AbstractList<E> extends java.util.AbstractCollection<E> implements java.util.List<E> {
+
+protected AbstractList() { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public abstract E get(int index);
+
+@libcore.util.NullFromTypeParam public E set(int index, @libcore.util.NullFromTypeParam E element) { 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 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!"); }
+
+public void clear() { 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!"); }
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { 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.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index) { 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 boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+protected void removeRange(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+protected transient int modCount = 0; // 0x0
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/AbstractMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/AbstractMap.annotated.java
new file mode 100644
index 0000000..a0c97b0
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/AbstractMap.annotated.java
@@ -0,0 +1,108 @@
+/*
+ * 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;
+
+import java.util.Map.Entry;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class AbstractMap<K, V> implements java.util.Map<K,V> {
+
+protected AbstractMap() { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V get(@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!"); }
+
+@libcore.util.Nullable public V remove(@libcore.util.Nullable java.lang.Object key) { 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!"); }
+
+public void clear() { 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 abstract 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) { 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 protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class SimpleEntry<K, V> implements java.util.Map.Entry<K,V>, java.io.Serializable {
+
+public SimpleEntry(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public SimpleEntry(@libcore.util.NonNull java.util.Map.Entry<? extends @libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam V> entry) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public K getKey() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public V getValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public V setValue(@libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class SimpleImmutableEntry<K, V> implements java.util.Map.Entry<K,V>, java.io.Serializable {
+
+public SimpleImmutableEntry(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public SimpleImmutableEntry(@libcore.util.NonNull java.util.Map.Entry<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> entry) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public K getKey() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public V getValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public V setValue(@libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/AbstractSequentialList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/AbstractSequentialList.annotated.java
new file mode 100644
index 0000000..42c8127
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/AbstractSequentialList.annotated.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2006, 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 abstract class AbstractSequentialList<E> extends java.util.AbstractList<E> {
+
+protected AbstractSequentialList() { 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 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 addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public abstract java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index);
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/AbstractSet.annotated.java b/ojluni/annotations/sdk/nullability/java/util/AbstractSet.annotated.java
new file mode 100644
index 0000000..2281ee0
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/AbstractSet.annotated.java
@@ -0,0 +1,40 @@
+/*
+ * 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 abstract class AbstractSet<E> extends java.util.AbstractCollection<E> implements java.util.Set<E> {
+
+protected AbstractSet() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/ArrayDeque.annotated.java b/ojluni/annotations/sdk/nullability/java/util/ArrayDeque.annotated.java
new file mode 100644
index 0000000..014b99c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/ArrayDeque.annotated.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Josh Bloch of Google Inc. and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ArrayDeque<@libcore.util.NonNull E> extends java.util.AbstractCollection<E> implements java.util.Deque<E>, java.lang.Cloneable, java.io.Serializable {
+
+public ArrayDeque() { throw new RuntimeException("Stub!"); }
+
+public ArrayDeque(int numElements) { throw new RuntimeException("Stub!"); }
+
+public ArrayDeque(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public void addFirst(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public void addLast(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean offerFirst(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean offerLast(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E removeFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E removeLast() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E pollFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E pollLast() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E getFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E getLast() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E peekFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E peekLast() { throw new RuntimeException("Stub!"); }
+
+public boolean removeFirstOccurrence(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public boolean removeLastOccurrence(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean offer(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E remove() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E poll() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E element() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E peek() { throw new RuntimeException("Stub!"); }
+
+public void push(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E pop() { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { 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.Iterator<@libcore.util.NullFromTypeParam E> descendingIterator() { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o) { 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 java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.ArrayDeque<@libcore.util.NullFromTypeParam E> clone() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
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/Arrays.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Arrays.annotated.java
new file mode 100644
index 0000000..99dec24
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Arrays.annotated.java
@@ -0,0 +1,356 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Array;
+import java.util.concurrent.ForkJoinPool;
+import java.util.function.BinaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.IntBinaryOperator;
+import java.util.stream.Stream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.DoubleStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Arrays {
+
+Arrays() { throw new RuntimeException("Stub!"); }
+
+public static void sort(int @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(int @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(long @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(long @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(short @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(short @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(char @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(char @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(byte @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(byte @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(float @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(float @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void sort(double @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(double @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(byte @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(byte @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(char @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(char @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(short @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(short @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(int @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(int @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(long @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(long @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(float @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(float @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(double @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSort(double @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static <T extends java.lang.Comparable<? super T>> void parallelSort(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static <T extends java.lang.Comparable<? super T>> void parallelSort(T @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static <T> void parallelSort(T @libcore.util.NonNull [] a, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> cmp) { throw new RuntimeException("Stub!"); }
+
+public static <T> void parallelSort(T @libcore.util.NonNull [] a, int fromIndex, int toIndex, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> cmp) { throw new RuntimeException("Stub!"); }
+
+public static void sort(java.lang.@libcore.util.NonNull Object @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+public static void sort(java.lang.@libcore.util.NonNull Object @libcore.util.NonNull [] a, int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+public static <T> void sort(T @libcore.util.NonNull [] a, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static <T> void sort(T @libcore.util.NonNull [] a, int fromIndex, int toIndex, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static <T> void parallelPrefix(T @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.BinaryOperator<@libcore.util.NullFromTypeParam T> op) { throw new RuntimeException("Stub!"); }
+
+public static <T> void parallelPrefix(T @libcore.util.NonNull [] array, int fromIndex, int toIndex, @libcore.util.NonNull java.util.function.BinaryOperator<@libcore.util.NullFromTypeParam T> op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(long @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.LongBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(long @libcore.util.NonNull [] array, int fromIndex, int toIndex, @libcore.util.NonNull java.util.function.LongBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(double @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.DoubleBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(double @libcore.util.NonNull [] array, int fromIndex, int toIndex, @libcore.util.NonNull java.util.function.DoubleBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(int @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static void parallelPrefix(int @libcore.util.NonNull [] array, int fromIndex, int toIndex, @libcore.util.NonNull java.util.function.IntBinaryOperator op) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(long @libcore.util.NonNull [] a, long key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(long @libcore.util.NonNull [] a, int fromIndex, int toIndex, long key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(int @libcore.util.NonNull [] a, int key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(int @libcore.util.NonNull [] a, int fromIndex, int toIndex, int key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(short @libcore.util.NonNull [] a, short key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(short @libcore.util.NonNull [] a, int fromIndex, int toIndex, short key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(char @libcore.util.NonNull [] a, char key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(char @libcore.util.NonNull [] a, int fromIndex, int toIndex, char key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(byte @libcore.util.NonNull [] a, byte key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(byte @libcore.util.NonNull [] a, int fromIndex, int toIndex, byte key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(double @libcore.util.NonNull [] a, double key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(double @libcore.util.NonNull [] a, int fromIndex, int toIndex, double key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(float @libcore.util.NonNull [] a, float key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(float @libcore.util.NonNull [] a, int fromIndex, int toIndex, float key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(java.lang.@libcore.util.NonNull Object @libcore.util.NonNull [] a, @libcore.util.NonNull java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public static int binarySearch(java.lang.@libcore.util.NonNull Object @libcore.util.NonNull [] a, int fromIndex, int toIndex, @libcore.util.NonNull java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public static <T> int binarySearch(T @libcore.util.NonNull [] a, @libcore.util.NullFromTypeParam T key, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static <T> int binarySearch(T @libcore.util.NonNull [] a, int fromIndex, int toIndex, @libcore.util.NullFromTypeParam T key, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(long @libcore.util.Nullable [] a, long @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(int @libcore.util.Nullable [] a, int @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(short @libcore.util.Nullable [] a, short @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(char @libcore.util.Nullable [] a, char @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(byte @libcore.util.Nullable [] a, byte @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(boolean @libcore.util.Nullable [] a, boolean @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(double @libcore.util.Nullable [] a, double @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(float @libcore.util.Nullable [] a, float @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+public static void fill(long @libcore.util.NonNull [] a, long val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(long @libcore.util.NonNull [] a, int fromIndex, int toIndex, long val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(int @libcore.util.NonNull [] a, int val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(int @libcore.util.NonNull [] a, int fromIndex, int toIndex, int val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(short @libcore.util.NonNull [] a, short val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(short @libcore.util.NonNull [] a, int fromIndex, int toIndex, short val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(char @libcore.util.NonNull [] a, char val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(char @libcore.util.NonNull [] a, int fromIndex, int toIndex, char val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(byte @libcore.util.NonNull [] a, byte val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(byte @libcore.util.NonNull [] a, int fromIndex, int toIndex, byte val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(boolean @libcore.util.NonNull [] a, boolean val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(boolean @libcore.util.NonNull [] a, int fromIndex, int toIndex, boolean val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(double @libcore.util.NonNull [] a, double val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(double @libcore.util.NonNull [] a, int fromIndex, int toIndex, double val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(float @libcore.util.NonNull [] a, float val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(float @libcore.util.NonNull [] a, int fromIndex, int toIndex, float val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] a, @libcore.util.Nullable java.lang.Object val) { throw new RuntimeException("Stub!"); }
+
+public static void fill(java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] a, int fromIndex, int toIndex, @libcore.util.Nullable java.lang.Object val) { throw new RuntimeException("Stub!"); }
+
+public static <T> T @libcore.util.NonNull [] copyOf(T @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static <T, U> T @libcore.util.NonNull [] copyOf(U @libcore.util.NonNull [] original, int newLength, @libcore.util.NonNull java.lang.Class<? extends T[]> newType) { throw new RuntimeException("Stub!"); }
+
+public static byte @libcore.util.NonNull [] copyOf(byte @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static short @libcore.util.NonNull [] copyOf(short @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static int @libcore.util.NonNull [] copyOf(int @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static long @libcore.util.NonNull [] copyOf(long @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static char @libcore.util.NonNull [] copyOf(char @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static float @libcore.util.NonNull [] copyOf(float @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static double @libcore.util.NonNull [] copyOf(double @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static boolean @libcore.util.NonNull [] copyOf(boolean @libcore.util.NonNull [] original, int newLength) { throw new RuntimeException("Stub!"); }
+
+public static <T> T @libcore.util.NonNull [] copyOfRange(T @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static <T, U> T @libcore.util.NonNull [] copyOfRange(U @libcore.util.NonNull [] original, int from, int to, @libcore.util.NonNull java.lang.Class<? extends T[]> newType) { throw new RuntimeException("Stub!"); }
+
+public static byte @libcore.util.NonNull [] copyOfRange(byte @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static short @libcore.util.NonNull [] copyOfRange(short @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static int @libcore.util.NonNull [] copyOfRange(int @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static long @libcore.util.NonNull [] copyOfRange(long @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static char @libcore.util.NonNull [] copyOfRange(char @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static float @libcore.util.NonNull [] copyOfRange(float @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static double @libcore.util.NonNull [] copyOfRange(double @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+public static boolean @libcore.util.NonNull [] copyOfRange(boolean @libcore.util.NonNull [] original, int from, int to) { throw new RuntimeException("Stub!"); }
+
+@java.lang.SafeVarargs
+@libcore.util.NonNull public static <T> java.util.List<@libcore.util.NullFromTypeParam T> asList(T @libcore.util.NonNull ... a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(long @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(int @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(short @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(char @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(byte @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(boolean @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(float @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(double @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static int deepHashCode(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static boolean deepEquals(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a1, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a2) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(long @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(int @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(short @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(char @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(byte @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(boolean @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(float @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(double @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String deepToString(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] a) { throw new RuntimeException("Stub!"); }
+
+public static <T> void setAll(T @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntFunction<? extends @libcore.util.NullFromTypeParam T> generator) { throw new RuntimeException("Stub!"); }
+
+public static <T> void parallelSetAll(T @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntFunction<? extends @libcore.util.NullFromTypeParam T> generator) { throw new RuntimeException("Stub!"); }
+
+public static void setAll(int @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntUnaryOperator generator) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSetAll(int @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntUnaryOperator generator) { throw new RuntimeException("Stub!"); }
+
+public static void setAll(long @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntToLongFunction generator) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSetAll(long @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntToLongFunction generator) { throw new RuntimeException("Stub!"); }
+
+public static void setAll(double @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntToDoubleFunction generator) { throw new RuntimeException("Stub!"); }
+
+public static void parallelSetAll(double @libcore.util.NonNull [] array, @libcore.util.NonNull java.util.function.IntToDoubleFunction generator) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Spliterator<@libcore.util.NullFromTypeParam T> spliterator(T @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Spliterator<@libcore.util.NullFromTypeParam T> spliterator(T @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfInt spliterator(int @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfInt spliterator(int @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfLong spliterator(long @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfLong spliterator(long @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfDouble spliterator(double @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Spliterator.OfDouble spliterator(double @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.stream.Stream<@libcore.util.NullFromTypeParam T> stream(T @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.stream.Stream<@libcore.util.NullFromTypeParam T> stream(T @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.IntStream stream(int @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.IntStream stream(int @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.LongStream stream(long @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.LongStream stream(long @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.DoubleStream stream(double @libcore.util.NonNull [] array) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.stream.DoubleStream stream(double @libcore.util.NonNull [] array, int startInclusive, int endExclusive) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Calendar.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Calendar.annotated.java
new file mode 100644
index 0000000..73efc29
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Calendar.annotated.java
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
+ *
+ *   The original version of this source code and documentation is copyrighted
+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
+ * materials are provided under terms of a License Agreement between Taligent
+ * and Sun. This technology is protected by multiple US and International
+ * patents. This notice and attribution to Taligent may not be removed.
+ *   Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.util;
+
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.time.Instant;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Calendar implements java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<java.util.Calendar> {
+
+protected Calendar() { throw new RuntimeException("Stub!"); }
+
+protected Calendar(@libcore.util.NonNull java.util.TimeZone zone, @libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Calendar getInstance() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Calendar getInstance(@libcore.util.NonNull java.util.TimeZone zone) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Calendar getInstance(@libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Calendar getInstance(@libcore.util.NonNull java.util.TimeZone zone, @libcore.util.NonNull java.util.Locale aLocale) { throw new RuntimeException("Stub!"); }
+
+public static synchronized java.util.@libcore.util.NonNull Locale @libcore.util.NonNull [] getAvailableLocales() { throw new RuntimeException("Stub!"); }
+
+protected abstract void computeTime();
+
+protected abstract void computeFields();
+
+@libcore.util.NonNull public final java.util.Date getTime() { throw new RuntimeException("Stub!"); }
+
+public final void setTime(@libcore.util.NonNull java.util.Date date) { throw new RuntimeException("Stub!"); }
+
+public long getTimeInMillis() { throw new RuntimeException("Stub!"); }
+
+public void setTimeInMillis(long millis) { throw new RuntimeException("Stub!"); }
+
+public int get(int field) { throw new RuntimeException("Stub!"); }
+
+protected final int internalGet(int field) { throw new RuntimeException("Stub!"); }
+
+public void set(int field, int value) { throw new RuntimeException("Stub!"); }
+
+public final void set(int year, int month, int date) { throw new RuntimeException("Stub!"); }
+
+public final void set(int year, int month, int date, int hourOfDay, int minute) { throw new RuntimeException("Stub!"); }
+
+public final void set(int year, int month, int date, int hourOfDay, int minute, int second) { throw new RuntimeException("Stub!"); }
+
+public final void clear() { throw new RuntimeException("Stub!"); }
+
+public final void clear(int field) { throw new RuntimeException("Stub!"); }
+
+public final boolean isSet(int field) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getDisplayName(int field, int style, @libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map<java.lang.@libcore.util.NonNull String, java.lang.@libcore.util.NonNull Integer> getDisplayNames(int field, int style, @libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+protected void complete() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Set<java.lang.@libcore.util.NonNull String> getAvailableCalendarTypes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getCalendarType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean before(@libcore.util.Nullable java.lang.Object when) { throw new RuntimeException("Stub!"); }
+
+public boolean after(@libcore.util.Nullable java.lang.Object when) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.util.Calendar anotherCalendar) { throw new RuntimeException("Stub!"); }
+
+public abstract void add(int field, int amount);
+
+public abstract void roll(int field, boolean up);
+
+public void roll(int field, int amount) { throw new RuntimeException("Stub!"); }
+
+public void setTimeZone(@libcore.util.NonNull java.util.TimeZone value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.TimeZone getTimeZone() { throw new RuntimeException("Stub!"); }
+
+public void setLenient(boolean lenient) { throw new RuntimeException("Stub!"); }
+
+public boolean isLenient() { throw new RuntimeException("Stub!"); }
+
+public void setFirstDayOfWeek(int value) { throw new RuntimeException("Stub!"); }
+
+public int getFirstDayOfWeek() { throw new RuntimeException("Stub!"); }
+
+public void setMinimalDaysInFirstWeek(int value) { throw new RuntimeException("Stub!"); }
+
+public int getMinimalDaysInFirstWeek() { throw new RuntimeException("Stub!"); }
+
+public boolean isWeekDateSupported() { throw new RuntimeException("Stub!"); }
+
+public int getWeekYear() { throw new RuntimeException("Stub!"); }
+
+public void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) { throw new RuntimeException("Stub!"); }
+
+public int getWeeksInWeekYear() { throw new RuntimeException("Stub!"); }
+
+public abstract int getMinimum(int field);
+
+public abstract int getMaximum(int field);
+
+public abstract int getGreatestMinimum(int field);
+
+public abstract int getLeastMaximum(int field);
+
+public int getActualMinimum(int field) { throw new RuntimeException("Stub!"); }
+
+public int getActualMaximum(int field) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.time.Instant toInstant() { throw new RuntimeException("Stub!"); }
+
+public static final int ALL_STYLES = 0; // 0x0
+
+public static final int AM = 0; // 0x0
+
+public static final int AM_PM = 9; // 0x9
+
+public static final int APRIL = 3; // 0x3
+
+public static final int AUGUST = 7; // 0x7
+
+public static final int DATE = 5; // 0x5
+
+public static final int DAY_OF_MONTH = 5; // 0x5
+
+public static final int DAY_OF_WEEK = 7; // 0x7
+
+public static final int DAY_OF_WEEK_IN_MONTH = 8; // 0x8
+
+public static final int DAY_OF_YEAR = 6; // 0x6
+
+public static final int DECEMBER = 11; // 0xb
+
+public static final int DST_OFFSET = 16; // 0x10
+
+public static final int ERA = 0; // 0x0
+
+public static final int FEBRUARY = 1; // 0x1
+
+public static final int FIELD_COUNT = 17; // 0x11
+
+public static final int FRIDAY = 6; // 0x6
+
+public static final int HOUR = 10; // 0xa
+
+public static final int HOUR_OF_DAY = 11; // 0xb
+
+public static final int JANUARY = 0; // 0x0
+
+public static final int JULY = 6; // 0x6
+
+public static final int JUNE = 5; // 0x5
+
+public static final int LONG = 2; // 0x2
+
+public static final int LONG_FORMAT = 2; // 0x2
+
+public static final int LONG_STANDALONE = 32770; // 0x8002
+
+public static final int MARCH = 2; // 0x2
+
+public static final int MAY = 4; // 0x4
+
+public static final int MILLISECOND = 14; // 0xe
+
+public static final int MINUTE = 12; // 0xc
+
+public static final int MONDAY = 2; // 0x2
+
+public static final int MONTH = 2; // 0x2
+
+public static final int NARROW_FORMAT = 4; // 0x4
+
+public static final int NARROW_STANDALONE = 32772; // 0x8004
+
+public static final int NOVEMBER = 10; // 0xa
+
+public static final int OCTOBER = 9; // 0x9
+
+public static final int PM = 1; // 0x1
+
+public static final int SATURDAY = 7; // 0x7
+
+public static final int SECOND = 13; // 0xd
+
+public static final int SEPTEMBER = 8; // 0x8
+
+public static final int SHORT = 1; // 0x1
+
+public static final int SHORT_FORMAT = 1; // 0x1
+
+public static final int SHORT_STANDALONE = 32769; // 0x8001
+
+public static final int SUNDAY = 1; // 0x1
+
+public static final int THURSDAY = 5; // 0x5
+
+public static final int TUESDAY = 3; // 0x3
+
+public static final int UNDECIMBER = 12; // 0xc
+
+public static final int WEDNESDAY = 4; // 0x4
+
+public static final int WEEK_OF_MONTH = 4; // 0x4
+
+public static final int WEEK_OF_YEAR = 3; // 0x3
+
+public static final int YEAR = 1; // 0x1
+
+public static final int ZONE_OFFSET = 15; // 0xf
+
+protected boolean areFieldsSet;
+
+protected int @libcore.util.NonNull [] fields;
+
+protected boolean @libcore.util.NonNull [] isSet;
+
+protected boolean isTimeSet;
+
+protected long time;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Builder {
+
+public Builder() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setInstant(long instant) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setInstant(@libcore.util.NonNull java.util.Date instant) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder set(int field, int value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setFields(int @libcore.util.NonNull ... fieldValuePairs) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setDate(int year, int month, int dayOfMonth) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setTimeOfDay(int hourOfDay, int minute, int second) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setTimeOfDay(int hourOfDay, int minute, int second, int millis) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setTimeZone(@libcore.util.NonNull java.util.TimeZone zone) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setLenient(boolean lenient) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setCalendarType(@libcore.util.NonNull java.lang.String type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setLocale(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar.Builder setWeekDefinition(int firstDayOfWeek, int minimalDaysInFirstWeek) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Calendar build() { throw new RuntimeException("Stub!"); }
+}
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Collection.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Collection.annotated.java
new file mode 100644
index 0000000..d2f425f
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Collection.annotated.java
@@ -0,0 +1,72 @@
+/*
+ * 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;
+
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Collection<E> extends java.lang.Iterable<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();
+
+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 removeAll(@libcore.util.NonNull java.util.Collection<?> c);
+
+public default boolean removeIf(@libcore.util.NonNull java.util.function.Predicate<? super @libcore.util.NullFromTypeParam E> filter) { throw new RuntimeException("Stub!"); }
+
+public boolean retainAll(@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!"); }
+
+@libcore.util.NonNull public default java.util.stream.Stream<@libcore.util.NullFromTypeParam E> stream() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public default java.util.stream.Stream<@libcore.util.NullFromTypeParam E> parallelStream() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Collections.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Collections.annotated.java
new file mode 100644
index 0000000..3e3e636
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Collections.annotated.java
@@ -0,0 +1,179 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Array;
+import java.util.stream.Stream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Collections {
+
+Collections() { throw new RuntimeException("Stub!"); }
+
+public static <T extends java.lang.Comparable<? super T>> void sort(@libcore.util.NonNull java.util.List<@libcore.util.NonNull T> list) { throw new RuntimeException("Stub!"); }
+
+public static <T> void sort(@libcore.util.NonNull java.util.List<@libcore.util.NullFromTypeParam T> list, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static <T> int binarySearch(@libcore.util.NonNull java.util.List<? extends @libcore.util.NonNull java.lang.Comparable<? super T>> list, @libcore.util.NonNull T key) { throw new RuntimeException("Stub!"); }
+
+public static <T> int binarySearch(@libcore.util.NonNull java.util.List<? extends @libcore.util.NullFromTypeParam T> list, @libcore.util.NullFromTypeParam T key, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+public static void reverse(@libcore.util.NonNull java.util.List<?> list) { throw new RuntimeException("Stub!"); }
+
+public static void shuffle(@libcore.util.NonNull java.util.List<?> list) { throw new RuntimeException("Stub!"); }
+
+public static void shuffle(@libcore.util.NonNull java.util.List<?> list, @libcore.util.NonNull java.util.Random rnd) { throw new RuntimeException("Stub!"); }
+
+public static void swap(@libcore.util.NonNull java.util.List<?> list, int i, int j) { throw new RuntimeException("Stub!"); }
+
+public static <T> void fill(@libcore.util.NonNull java.util.List<? super @libcore.util.NullFromTypeParam T> list, @libcore.util.NullFromTypeParam T obj) { throw new RuntimeException("Stub!"); }
+
+public static <T> void copy(@libcore.util.NonNull java.util.List<? super @libcore.util.NullFromTypeParam T> dest, @libcore.util.NonNull java.util.List<? extends @libcore.util.NullFromTypeParam T> src) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T min(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NonNull T> coll) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public static <T> T min(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam T> coll, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> comp) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T max(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NonNull T> coll) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public static <T> T max(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam T> coll, @libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam T> comp) { throw new RuntimeException("Stub!"); }
+
+public static void rotate(@libcore.util.NonNull java.util.List<?> list, int distance) { throw new RuntimeException("Stub!"); }
+
+public static <T> boolean replaceAll(@libcore.util.NonNull java.util.List<@libcore.util.NullFromTypeParam T> list, @libcore.util.NullFromTypeParam T oldVal, @libcore.util.NullFromTypeParam T newVal) { throw new RuntimeException("Stub!"); }
+
+public static int indexOfSubList(@libcore.util.NonNull java.util.List<?> source, @libcore.util.NonNull java.util.List<?> target) { throw new RuntimeException("Stub!"); }
+
+public static int lastIndexOfSubList(@libcore.util.NonNull java.util.List<?> source, @libcore.util.NonNull java.util.List<?> target) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Collection<@libcore.util.NullFromTypeParam T> unmodifiableCollection(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Set<@libcore.util.NullFromTypeParam T> unmodifiableSet(@libcore.util.NonNull java.util.Set<? extends @libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.SortedSet<@libcore.util.NullFromTypeParam T> unmodifiableSortedSet(@libcore.util.NonNull java.util.SortedSet<@libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.NavigableSet<@libcore.util.NullFromTypeParam T> unmodifiableNavigableSet(@libcore.util.NonNull java.util.NavigableSet<@libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.List<@libcore.util.NullFromTypeParam T> unmodifiableList(@libcore.util.NonNull java.util.List<? extends @libcore.util.NullFromTypeParam T> list) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> unmodifiableMap(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> unmodifiableSortedMap(@libcore.util.NonNull java.util.SortedMap<@libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> unmodifiableNavigableMap(@libcore.util.NonNull java.util.NavigableMap<@libcore.util.NullFromTypeParam K, ? extends @libcore.util.NullFromTypeParam  V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Collection<@libcore.util.NullFromTypeParam T> synchronizedCollection(@libcore.util.NonNull java.util.Collection<@libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Set<@libcore.util.NullFromTypeParam T> synchronizedSet(@libcore.util.NonNull java.util.Set<@libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.SortedSet<@libcore.util.NullFromTypeParam T> synchronizedSortedSet(@libcore.util.NonNull java.util.SortedSet<@libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.NavigableSet<@libcore.util.NullFromTypeParam T> synchronizedNavigableSet(@libcore.util.NonNull java.util.NavigableSet<@libcore.util.NullFromTypeParam T> s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.List<@libcore.util.NullFromTypeParam T> synchronizedList(@libcore.util.NonNull java.util.List<@libcore.util.NullFromTypeParam T> list) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> synchronizedMap(@libcore.util.NonNull java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> synchronizedSortedMap(@libcore.util.NonNull java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> synchronizedNavigableMap(@libcore.util.NonNull java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.Collection<@libcore.util.NullFromTypeParam E> checkedCollection(@libcore.util.NonNull java.util.Collection<@libcore.util.NullFromTypeParam E> c, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.Queue<@libcore.util.NullFromTypeParam E> checkedQueue(@libcore.util.NonNull java.util.Queue<@libcore.util.NullFromTypeParam E> queue, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.Set<@libcore.util.NullFromTypeParam E> checkedSet(@libcore.util.NonNull java.util.Set<@libcore.util.NullFromTypeParam E> s, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.SortedSet<@libcore.util.NullFromTypeParam E> checkedSortedSet(@libcore.util.NonNull java.util.SortedSet<@libcore.util.NullFromTypeParam E> s, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.NavigableSet<@libcore.util.NullFromTypeParam E> checkedNavigableSet(@libcore.util.NonNull java.util.NavigableSet<@libcore.util.NullFromTypeParam E> s, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.List<@libcore.util.NullFromTypeParam E> checkedList(@libcore.util.NonNull java.util.List<@libcore.util.NullFromTypeParam E> list, @libcore.util.NonNull java.lang.Class<E> type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> checkedMap(@libcore.util.NonNull java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m, @libcore.util.NonNull java.lang.Class<K> keyType, @libcore.util.NonNull java.lang.Class<V> valueType) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> checkedSortedMap(@libcore.util.NonNull java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m, @libcore.util.NonNull java.lang.Class<K> keyType, @libcore.util.NonNull java.lang.Class<V> valueType) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> checkedNavigableMap(@libcore.util.NonNull java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> m, @libcore.util.NonNull java.lang.Class<K> keyType, @libcore.util.NonNull java.lang.Class<V> valueType) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Iterator<@libcore.util.NullFromTypeParam T> emptyIterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.ListIterator<@libcore.util.NullFromTypeParam T> emptyListIterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Enumeration<@libcore.util.NullFromTypeParam T> emptyEnumeration() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final <T> java.util.Set<@libcore.util.NullFromTypeParam T> emptySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.SortedSet<@libcore.util.NullFromTypeParam E> emptySortedSet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.NavigableSet<@libcore.util.NullFromTypeParam E> emptyNavigableSet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final <T> java.util.List<@libcore.util.NullFromTypeParam T> emptyList() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final <K, V> java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> emptyMap() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final <K, V> java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> emptySortedMap() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final <K, V> java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> emptyNavigableMap() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Set<@libcore.util.NullFromTypeParam T> singleton(@libcore.util.NullFromTypeParam T o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.List<@libcore.util.NullFromTypeParam T> singletonList(@libcore.util.NullFromTypeParam T o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> java.util.Map<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> singletonMap(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.List<@libcore.util.NullFromTypeParam T> nCopies(int n, @libcore.util.NullFromTypeParam T o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Comparator<@libcore.util.NonNull T> reverseOrder() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Comparator<@libcore.util.NullFromTypeParam T> reverseOrder(@libcore.util.Nullable java.util.Comparator<@libcore.util.NullFromTypeParam T> cmp) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Enumeration<@libcore.util.NullFromTypeParam T> enumeration(@libcore.util.NonNull java.util.Collection<@libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.ArrayList<@libcore.util.NullFromTypeParam T> list(@libcore.util.NonNull java.util.Enumeration<@libcore.util.NullFromTypeParam T> e) { throw new RuntimeException("Stub!"); }
+
+public static int frequency(@libcore.util.NonNull java.util.Collection<?> c, @libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public static boolean disjoint(@libcore.util.NonNull java.util.Collection<?> c1, @libcore.util.NonNull java.util.Collection<?> c2) { throw new RuntimeException("Stub!"); }
+
+@java.lang.SafeVarargs
+public static <T> boolean addAll(@libcore.util.NonNull java.util.Collection<? super @libcore.util.NullFromTypeParam T> c, T @libcore.util.NonNull ... elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.Set<@libcore.util.NullFromTypeParam E> newSetFromMap(@libcore.util.NonNull java.util.Map<@libcore.util.NullFromTypeParam E, @libcore.util.NonNull java.lang.Boolean> map) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> java.util.Queue<@libcore.util.NullFromTypeParam T> asLifoQueue(@libcore.util.NonNull java.util.Deque<@libcore.util.NullFromTypeParam T> deque) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.util.List EMPTY_LIST;
+static { EMPTY_LIST = null; }
+
+@libcore.util.NonNull public static final java.util.Map EMPTY_MAP;
+static { EMPTY_MAP = null; }
+
+@libcore.util.NonNull public static final java.util.Set EMPTY_SET;
+static { EMPTY_SET = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Deque.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Deque.annotated.java
new file mode 100644
index 0000000..d93d5a2
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Deque.annotated.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Josh Bloch with assistance from members of
+ * JCP JSR-166 Expert Group and released to the public domain, as explained
+ * at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Deque<E> extends java.util.Queue<E> {
+
+public void addFirst(@libcore.util.NullFromTypeParam E e);
+
+public void addLast(@libcore.util.NullFromTypeParam E e);
+
+public boolean offerFirst(@libcore.util.NullFromTypeParam E e);
+
+public boolean offerLast(@libcore.util.NullFromTypeParam E e);
+
+@libcore.util.NullFromTypeParam public E removeFirst();
+
+@libcore.util.NullFromTypeParam public E removeLast();
+
+@libcore.util.Nullable public E pollFirst();
+
+@libcore.util.Nullable public E pollLast();
+
+@libcore.util.NullFromTypeParam public E getFirst();
+
+@libcore.util.NullFromTypeParam public E getLast();
+
+@libcore.util.Nullable public E peekFirst();
+
+@libcore.util.Nullable public E peekLast();
+
+public boolean removeFirstOccurrence(@libcore.util.Nullable java.lang.Object o);
+
+public boolean removeLastOccurrence(@libcore.util.Nullable java.lang.Object o);
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean offer(@libcore.util.NullFromTypeParam E e);
+
+@libcore.util.NullFromTypeParam public E remove();
+
+@libcore.util.Nullable public E poll();
+
+@libcore.util.NullFromTypeParam public E element();
+
+@libcore.util.Nullable public E peek();
+
+public void push(@libcore.util.NullFromTypeParam E e);
+
+@libcore.util.NullFromTypeParam public E pop();
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o);
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o);
+
+public int size();
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> descendingIterator();
+}
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/annotations/sdk/nullability/java/util/HashSet.annotated.java b/ojluni/annotations/sdk/nullability/java/util/HashSet.annotated.java
new file mode 100644
index 0000000..c099118
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/HashSet.annotated.java
@@ -0,0 +1,58 @@
+/*
+ * 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 HashSet<E> extends java.util.AbstractSet<E> implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
+
+public HashSet() { throw new RuntimeException("Stub!"); }
+
+public HashSet(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public HashSet(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+public HashSet(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { 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 boolean add(@libcore.util.NullFromTypeParam E e) { 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!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
new file mode 100644
index 0000000..b4f4522
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Iterator.annotated.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.util.function.Consumer;
+
+public interface Iterator<E> {
+
+  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/LinkedList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/LinkedList.annotated.java
new file mode 100644
index 0000000..f85afd1
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/LinkedList.annotated.java
@@ -0,0 +1,116 @@
+/*
+ * 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 LinkedList<E> extends java.util.AbstractSequentialList<E> implements java.util.List<E>, java.util.Deque<E>, java.lang.Cloneable, java.io.Serializable {
+
+public LinkedList() { throw new RuntimeException("Stub!"); }
+
+public LinkedList(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E getFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E getLast() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E removeFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E removeLast() { throw new RuntimeException("Stub!"); }
+
+public void addFirst(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public void addLast(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o) { 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!"); }
+
+public void clear() { 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 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 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.Nullable public E peek() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E element() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E poll() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E remove() { throw new RuntimeException("Stub!"); }
+
+public boolean offer(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean offerFirst(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean offerLast(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E peekFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E peekLast() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E pollFirst() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public E pollLast() { throw new RuntimeException("Stub!"); }
+
+public void push(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public E pop() { throw new RuntimeException("Stub!"); }
+
+public boolean removeFirstOccurrence(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public boolean removeLastOccurrence(@libcore.util.Nullable java.lang.Object o) { 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.Iterator<@libcore.util.NullFromTypeParam E> descendingIterator() { 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!"); }
+
+public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { 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/Locale.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Locale.annotated.java
new file mode 100644
index 0000000..2b702d3
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Locale.annotated.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.
+ */
+
+/*
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ */
+
+
+package java.util;
+
+import java.text.MessageFormat;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Locale implements java.lang.Cloneable, java.io.Serializable {
+
+public Locale(@libcore.util.NonNull java.lang.String language, @libcore.util.NonNull java.lang.String country, @libcore.util.NonNull java.lang.String variant) { throw new RuntimeException("Stub!"); }
+
+public Locale(@libcore.util.NonNull java.lang.String language, @libcore.util.NonNull java.lang.String country) { throw new RuntimeException("Stub!"); }
+
+public Locale(@libcore.util.NonNull java.lang.String language) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Locale getDefault() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Locale getDefault(@libcore.util.NonNull java.util.Locale.Category category) { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDefault(@libcore.util.NonNull java.util.Locale newLocale) { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDefault(@libcore.util.NonNull java.util.Locale.Category category, @libcore.util.NonNull java.util.Locale newLocale) { throw new RuntimeException("Stub!"); }
+
+public static java.util.@libcore.util.NonNull Locale @libcore.util.NonNull [] getAvailableLocales() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] getISOCountries() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] getISOLanguages() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getLanguage() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getScript() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getCountry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getVariant() { throw new RuntimeException("Stub!"); }
+
+public boolean hasExtensions() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale stripExtensions() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getExtension(char key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<java.lang.@libcore.util.NonNull Character> getExtensionKeys() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<java.lang.@libcore.util.NonNull String> getUnicodeLocaleAttributes() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getUnicodeLocaleType(@libcore.util.NonNull java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Set<java.lang.@libcore.util.NonNull String> getUnicodeLocaleKeys() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toLanguageTag() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.Locale forLanguageTag(@libcore.util.NonNull java.lang.String languageTag) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getISO3Language() throws java.util.MissingResourceException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getISO3Country() throws java.util.MissingResourceException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayLanguage() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayLanguage(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayScript() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayScript(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayCountry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayCountry(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayVariant() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayVariant(@libcore.util.NonNull java.util.Locale inLocale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getDisplayName(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { 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!"); }
+
+@libcore.util.NonNull public static java.util.List<java.util.@libcore.util.NonNull Locale> filter(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.util.@libcore.util.NonNull Locale> locales, @libcore.util.NonNull java.util.Locale.FilteringMode mode) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.util.@libcore.util.NonNull Locale> filter(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.util.@libcore.util.NonNull Locale> locales) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.lang.@libcore.util.NonNull String> filterTags(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.lang.@libcore.util.NonNull String> tags, @libcore.util.NonNull java.util.Locale.FilteringMode mode) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.lang.@libcore.util.NonNull String> filterTags(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.lang.@libcore.util.NonNull String> tags) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.util.Locale lookup(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.util.@libcore.util.NonNull Locale> locales) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public static java.lang.String lookupTag(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Collection<java.lang.@libcore.util.NonNull String> tags) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.util.Locale CANADA;
+static { CANADA = null; }
+
+@libcore.util.NonNull public static final java.util.Locale CANADA_FRENCH;
+static { CANADA_FRENCH = null; }
+
+@libcore.util.NonNull public static final java.util.Locale CHINA;
+static { CHINA = null; }
+
+@libcore.util.NonNull public static final java.util.Locale CHINESE;
+static { CHINESE = null; }
+
+@libcore.util.NonNull public static final java.util.Locale ENGLISH;
+static { ENGLISH = null; }
+
+@libcore.util.NonNull public static final java.util.Locale FRANCE;
+static { FRANCE = null; }
+
+@libcore.util.NonNull public static final java.util.Locale FRENCH;
+static { FRENCH = null; }
+
+@libcore.util.NonNull public static final java.util.Locale GERMAN;
+static { GERMAN = null; }
+
+@libcore.util.NonNull public static final java.util.Locale GERMANY;
+static { GERMANY = null; }
+
+@libcore.util.NonNull public static final java.util.Locale ITALIAN;
+static { ITALIAN = null; }
+
+@libcore.util.NonNull public static final java.util.Locale ITALY;
+static { ITALY = null; }
+
+@libcore.util.NonNull public static final java.util.Locale JAPAN;
+static { JAPAN = null; }
+
+@libcore.util.NonNull public static final java.util.Locale JAPANESE;
+static { JAPANESE = null; }
+
+@libcore.util.NonNull public static final java.util.Locale KOREA;
+static { KOREA = null; }
+
+@libcore.util.NonNull public static final java.util.Locale KOREAN;
+static { KOREAN = null; }
+
+@libcore.util.NonNull public static final java.util.Locale PRC;
+static { PRC = null; }
+
+public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
+
+@libcore.util.NonNull public static final java.util.Locale ROOT;
+static { ROOT = null; }
+
+@libcore.util.NonNull public static final java.util.Locale SIMPLIFIED_CHINESE;
+static { SIMPLIFIED_CHINESE = null; }
+
+@libcore.util.NonNull public static final java.util.Locale TAIWAN;
+static { TAIWAN = null; }
+
+@libcore.util.NonNull public static final java.util.Locale TRADITIONAL_CHINESE;
+static { TRADITIONAL_CHINESE = null; }
+
+@libcore.util.NonNull public static final java.util.Locale UK;
+static { UK = null; }
+
+public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
+
+@libcore.util.NonNull public static final java.util.Locale US;
+static { US = null; }
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class Builder {
+
+public Builder() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setLocale(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setLanguageTag(@libcore.util.NonNull java.lang.String languageTag) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setLanguage(@libcore.util.Nullable java.lang.String language) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setScript(@libcore.util.Nullable java.lang.String script) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setRegion(@libcore.util.Nullable java.lang.String region) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setVariant(@libcore.util.Nullable java.lang.String variant) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setExtension(char key, @libcore.util.Nullable java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder setUnicodeLocaleKeyword(@libcore.util.NonNull java.lang.String key, @libcore.util.Nullable java.lang.String type) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder addUnicodeLocaleAttribute(@libcore.util.NonNull java.lang.String attribute) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder removeUnicodeLocaleAttribute(@libcore.util.NonNull java.lang.String attribute) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder clear() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale.Builder clearExtensions() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Locale build() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum Category {
+DISPLAY,
+FORMAT;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum FilteringMode {
+AUTOSELECT_FILTERING,
+EXTENDED_FILTERING,
+IGNORE_EXTENDED_RANGES,
+MAP_EXTENDED_RANGES,
+REJECT_EXTENDED_RANGES;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class LanguageRange {
+
+public LanguageRange(@libcore.util.NonNull java.lang.String range) { throw new RuntimeException("Stub!"); }
+
+public LanguageRange(@libcore.util.NonNull java.lang.String range, double weight) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getRange() { throw new RuntimeException("Stub!"); }
+
+public double getWeight() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> parse(@libcore.util.NonNull java.lang.String ranges) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.util.Locale.LanguageRange> parse(@libcore.util.NonNull java.lang.String ranges, @libcore.util.NonNull java.util.Map<java.lang.@libcore.util.NonNull String,java.util.@libcore.util.NonNull List<java.lang.@libcore.util.NonNull String>> map) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.List<java.util.Locale.LanguageRange> mapEquivalents(@libcore.util.NonNull java.util.List<java.util.Locale.@libcore.util.NonNull LanguageRange> priorityList, @libcore.util.NonNull java.util.Map<java.lang.@libcore.util.NonNull String,java.util.@libcore.util.NonNull List<java.lang.@libcore.util.NonNull String>> map) { 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!"); }
+
+public static final double MAX_WEIGHT = 1.0;
+
+public static final double MIN_WEIGHT = 0.0;
+}
+
+}
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..4008996
--- /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();
+
+@libcore.util.NonNull public static <K extends java.lang.Comparable<? super K>, V> java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.Nullable V>> comparingByKey() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V extends java.lang.Comparable<? super V>> java.util.Comparator<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.Nullable K, @libcore.util.NonNull V>> comparingByValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <K, V> 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!"); }
+
+@libcore.util.NonNull public static <K, V> 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/NavigableMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/NavigableMap.annotated.java
new file mode 100644
index 0000000..e3f4afb
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/NavigableMap.annotated.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Josh Bloch with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface NavigableMap<K, V> extends java.util.SortedMap<K,V> {
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> lowerEntry(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public K lowerKey(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> floorEntry(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public K floorKey(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> ceilingEntry(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public K ceilingKey(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> higherEntry(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public K higherKey(@libcore.util.NullFromTypeParam K key);
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> firstEntry();
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> lastEntry();
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> pollFirstEntry();
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> pollLastEntry();
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> descendingMap();
+
+@libcore.util.NonNull public java.util.NavigableSet<@libcore.util.NullFromTypeParam K> navigableKeySet();
+
+@libcore.util.NonNull public java.util.NavigableSet<@libcore.util.NullFromTypeParam K> descendingKeySet();
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> subMap(@libcore.util.NullFromTypeParam K fromKey, boolean fromInclusive, @libcore.util.NullFromTypeParam K toKey, boolean toInclusive);
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> headMap(@libcore.util.NullFromTypeParam K toKey, boolean inclusive);
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> tailMap(@libcore.util.NullFromTypeParam K fromKey, boolean inclusive);
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> subMap(@libcore.util.NullFromTypeParam K fromKey, @libcore.util.NullFromTypeParam K toKey);
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> headMap(@libcore.util.NullFromTypeParam K toKey);
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> tailMap(@libcore.util.NullFromTypeParam K fromKey);
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Objects.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Objects.annotated.java
new file mode 100644
index 0000000..591a022
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Objects.annotated.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, 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;
+
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Objects {
+
+Objects() { throw new RuntimeException("Stub!"); }
+
+public static boolean equals(@libcore.util.Nullable java.lang.Object a, @libcore.util.Nullable java.lang.Object b) { throw new RuntimeException("Stub!"); }
+
+public static boolean deepEquals(@libcore.util.Nullable java.lang.Object a, @libcore.util.Nullable java.lang.Object b) { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public static int hash(java.lang.@libcore.util.Nullable Object @libcore.util.Nullable ... values) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String toString(@libcore.util.Nullable java.lang.Object o, @libcore.util.NonNull java.lang.String nullDefault) { throw new RuntimeException("Stub!"); }
+
+public static <T> int compare(@libcore.util.NullFromTypeParam T a, @libcore.util.NullFromTypeParam T b, @libcore.util.NonNull java.util.Comparator<? super @libcore.util.NullFromTypeParam T> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> T requireNonNull(@libcore.util.Nullable T obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> T requireNonNull(@libcore.util.Nullable T obj, @libcore.util.NonNull java.lang.String message) { throw new RuntimeException("Stub!"); }
+
+public static boolean isNull(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static boolean nonNull(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <T> T requireNonNull(@libcore.util.Nullable T obj, @libcore.util.NonNull java.util.function.Supplier<@libcore.util.NonNull java.lang.String> messageSupplier) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Queue.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Queue.annotated.java
new file mode 100644
index 0000000..33c666a
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Queue.annotated.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Queue<E> extends java.util.Collection<E> {
+
+public boolean add(@libcore.util.NullFromTypeParam E e);
+
+public boolean offer(@libcore.util.NullFromTypeParam E e);
+
+@libcore.util.NullFromTypeParam public E remove();
+
+@libcore.util.Nullable public E poll();
+
+@libcore.util.NullFromTypeParam public E element();
+
+@libcore.util.Nullable public E peek();
+}
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/annotations/sdk/nullability/java/util/SortedMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/SortedMap.annotated.java
new file mode 100644
index 0000000..9d68839
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/SortedMap.annotated.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+package java.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface SortedMap<K, V> extends java.util.Map<K,V> {
+
+@libcore.util.Nullable public java.util.Comparator<? super @libcore.util.NullFromTypeParam K> comparator();
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> subMap(@libcore.util.NullFromTypeParam K fromKey, @libcore.util.NullFromTypeParam K toKey);
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> headMap(@libcore.util.NullFromTypeParam K toKey);
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> tailMap(@libcore.util.NullFromTypeParam K fromKey);
+
+@libcore.util.NullFromTypeParam public K firstKey();
+
+@libcore.util.NullFromTypeParam public K lastKey();
+
+@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();
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/TreeMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/TreeMap.annotated.java
new file mode 100644
index 0000000..87f1f20
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/TreeMap.annotated.java
@@ -0,0 +1,121 @@
+/*
+ * 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.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class TreeMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.NavigableMap<K,V>, java.lang.Cloneable, java.io.Serializable {
+
+public TreeMap() { throw new RuntimeException("Stub!"); }
+
+public TreeMap(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam K> comparator) { throw new RuntimeException("Stub!"); }
+
+public TreeMap(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+public TreeMap(@libcore.util.NonNull java.util.SortedMap<@libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> m) { throw new RuntimeException("Stub!"); }
+
+public int size() { throw new RuntimeException("Stub!"); }
+
+public boolean containsKey(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+public boolean containsValue(@libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V get(@libcore.util.Nullable java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Comparator<? super @libcore.util.NullFromTypeParam K> comparator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public K firstKey() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public K lastKey() { throw new RuntimeException("Stub!"); }
+
+public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NullFromTypeParam K,? extends @libcore.util.NullFromTypeParam V> map) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public V put(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { 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!"); }
+
+@libcore.util.NonNull public java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> firstEntry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> lastEntry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> pollFirstEntry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> pollLastEntry() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> lowerEntry(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public K lowerKey(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> floorEntry(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public K floorKey(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> ceilingEntry(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public K ceilingKey(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> higherEntry(@libcore.util.NullFromTypeParam K key) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public K higherKey(@libcore.util.NullFromTypeParam K key) { 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.NavigableSet<@libcore.util.NullFromTypeParam K> navigableKeySet() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.NavigableSet<@libcore.util.NullFromTypeParam K> descendingKeySet() { 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.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> descendingMap() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> subMap(@libcore.util.NullFromTypeParam K fromKey, boolean fromInclusive, @libcore.util.NullFromTypeParam K toKey, boolean toInclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> headMap(@libcore.util.NullFromTypeParam K toKey, boolean inclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.NavigableMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> tailMap(@libcore.util.NullFromTypeParam K fromKey, boolean inclusive) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> subMap(@libcore.util.NullFromTypeParam K fromKey, @libcore.util.NullFromTypeParam K toKey) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> headMap(@libcore.util.NullFromTypeParam K toKey) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.SortedMap<@libcore.util.NullFromTypeParam K, @libcore.util.NullFromTypeParam V> tailMap(@libcore.util.NullFromTypeParam K fromKey) { 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.NullFromTypeParam public V replace(@libcore.util.NullFromTypeParam K key, @libcore.util.NullFromTypeParam V value) { 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!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/Vector.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Vector.annotated.java
new file mode 100644
index 0000000..09bb48c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/Vector.annotated.java
@@ -0,0 +1,146 @@
+/*
+ * 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.util;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Vector<E> extends java.util.AbstractList<E> implements java.util.List<E>, java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable {
+
+public Vector(int initialCapacity, int capacityIncrement) { throw new RuntimeException("Stub!"); }
+
+public Vector(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public Vector() { throw new RuntimeException("Stub!"); }
+
+public Vector(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized void copyInto(java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] anArray) { throw new RuntimeException("Stub!"); }
+
+public synchronized void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public synchronized void ensureCapacity(int minCapacity) { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSize(int newSize) { throw new RuntimeException("Stub!"); }
+
+public synchronized int capacity() { throw new RuntimeException("Stub!"); }
+
+public synchronized int size() { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Enumeration<@libcore.util.NullFromTypeParam E> elements() { 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 synchronized int indexOf(@libcore.util.Nullable java.lang.Object o, int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.Nullable java.lang.Object o, int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E elementAt(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E firstElement() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E lastElement() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setElementAt(@libcore.util.NullFromTypeParam E obj, int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized void removeElementAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized void insertElementAt(@libcore.util.NullFromTypeParam E obj, int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized void addElement(@libcore.util.NullFromTypeParam E obj) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean removeElement(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public synchronized void removeAllElements() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.Object clone() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+public synchronized <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E get(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E set(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean add(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean remove(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public void add(int index, @libcore.util.NullFromTypeParam E element) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NullFromTypeParam public synchronized E remove(int index) { throw new RuntimeException("Stub!"); }
+
+public void clear() { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean addAll(int index, @libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public synchronized int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+protected synchronized void removeRange(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator(int index) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.util.ListIterator<@libcore.util.NullFromTypeParam E> listIterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public synchronized java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator() { throw new RuntimeException("Stub!"); }
+
+public synchronized void forEach(@libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NullFromTypeParam E> action) { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean removeIf(@libcore.util.NonNull java.util.function.Predicate<? super @libcore.util.NullFromTypeParam E> filter) { throw new RuntimeException("Stub!"); }
+
+public synchronized void replaceAll(@libcore.util.NonNull java.util.function.UnaryOperator<@libcore.util.NullFromTypeParam E> operator) { throw new RuntimeException("Stub!"); }
+
+public synchronized void sort(@libcore.util.Nullable java.util.Comparator<? super @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+
+protected int capacityIncrement;
+
+protected int elementCount;
+
+protected java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] elementData;
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/WeakHashMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/WeakHashMap.annotated.java
new file mode 100644
index 0000000..83ae1cb
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/WeakHashMap.annotated.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1998, 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;
+
+import java.lang.ref.WeakReference;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class WeakHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V> {
+
+public WeakHashMap(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+public WeakHashMap(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+public WeakHashMap() { throw new RuntimeException("Stub!"); }
+
+public WeakHashMap(@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!"); }
+
+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!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/concurrent/ConcurrentHashMap.annotated.java b/ojluni/annotations/sdk/nullability/java/util/concurrent/ConcurrentHashMap.annotated.java
new file mode 100644
index 0000000..bf53e84
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/concurrent/ConcurrentHashMap.annotated.java
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+
+package java.util.concurrent;
+
+import java.util.Set;
+import java.util.HashMap;
+import java.util.AbstractMap;
+import java.util.Iterator;
+import java.util.stream.Stream;
+import java.util.Spliterator;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Collection;
+import java.util.function.Function;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ConcurrentHashMap<K, V> extends java.util.AbstractMap<@libcore.util.NonNull K, @libcore.util.NonNull V> implements java.util.concurrent.ConcurrentMap<@libcore.util.NonNull K, @libcore.util.NonNull V>, java.io.Serializable {
+
+  public ConcurrentHashMap() { throw new RuntimeException("Stub!"); }
+
+  public ConcurrentHashMap(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+  public ConcurrentHashMap(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NonNull K,? extends @libcore.util.NonNull V> m) { throw new RuntimeException("Stub!"); }
+
+  public ConcurrentHashMap(int initialCapacity, float loadFactor) { throw new RuntimeException("Stub!"); }
+
+  public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { 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.NonNull java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+  public boolean containsKey(@libcore.util.NonNull java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+  public boolean containsValue(@libcore.util.NonNull java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V put(@libcore.util.NonNull K key, @libcore.util.NonNull V value) { throw new RuntimeException("Stub!"); }
+
+  public void putAll(@libcore.util.NonNull java.util.Map<? extends @libcore.util.NonNull K,? extends @libcore.util.NonNull V> m) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V remove(@libcore.util.NonNull java.lang.Object key) { throw new RuntimeException("Stub!"); }
+
+  public void clear() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.Set<@libcore.util.NonNull K> keySet() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.Collection<@libcore.util.NonNull V> values() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.Set<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> entrySet() { throw new RuntimeException("Stub!"); }
+
+  public int hashCode() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+  public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V putIfAbsent(@libcore.util.NonNull K key, @libcore.util.NonNull V value) { throw new RuntimeException("Stub!"); }
+
+  public boolean remove(@libcore.util.NonNull java.lang.Object key, @libcore.util.Nullable java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+  public boolean replace(@libcore.util.NonNull K key, @libcore.util.NonNull V oldValue, @libcore.util.NonNull V newValue) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V replace(@libcore.util.NonNull K key, @libcore.util.NonNull V value) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V getOrDefault(@libcore.util.NonNull java.lang.Object key, @libcore.util.Nullable V defaultValue) { throw new RuntimeException("Stub!"); }
+
+  public void forEach(@libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V> action) { throw new RuntimeException("Stub!"); }
+
+  public void replaceAll(@libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V,? extends @libcore.util.NonNull V> function) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V computeIfAbsent(@libcore.util.NonNull K key, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull K,? extends @libcore.util.Nullable V> mappingFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V computeIfPresent(@libcore.util.NonNull K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V compute(@libcore.util.NonNull K key, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.Nullable V,? extends @libcore.util.Nullable V> remappingFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V merge(@libcore.util.NonNull 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!"); }
+
+  public boolean contains(@libcore.util.NonNull java.lang.Object value) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.Enumeration<@libcore.util.NonNull K> keys() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.Enumeration<@libcore.util.NonNull V> elements() { throw new RuntimeException("Stub!"); }
+
+  public long mappingCount() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public static <@libcore.util.NonNull K> java.util.concurrent.ConcurrentHashMap.KeySetView<@libcore.util.NonNull K, @libcore.util.NonNull java.lang.Boolean> newKeySet() { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public static <@libcore.util.NonNull K> java.util.concurrent.ConcurrentHashMap.KeySetView<@libcore.util.NonNull K, @libcore.util.NonNull java.lang.Boolean> newKeySet(int initialCapacity) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.NonNull public java.util.concurrent.ConcurrentHashMap.KeySetView<@libcore.util.NonNull K, @libcore.util.NonNull V> keySet(@libcore.util.NonNull V mappedValue) { throw new RuntimeException("Stub!"); }
+
+  public void forEach(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiConsumer<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V> action) { throw new RuntimeException("Stub!"); }
+
+  public <U> void forEach(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull U> action) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U search(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> searchFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U reduce(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull U,? super @libcore.util.NonNull U,? extends @libcore.util.Nullable U> reducer) { throw new RuntimeException("Stub!"); }
+
+  public double reduceToDouble(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToDoubleBiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V> transformer, double basis, @libcore.util.NonNull java.util.function.DoubleBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public long reduceToLong(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToLongBiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V> transformer, long basis, @libcore.util.NonNull java.util.function.LongBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public int reduceToInt(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToIntBiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull V> transformer, int basis, @libcore.util.NonNull java.util.function.IntBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public void forEachKey(long parallelismThreshold, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull K> action) { throw new RuntimeException("Stub!"); }
+
+  public <U> void forEachKey(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull K,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull U> action) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U searchKeys(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull K,? extends @libcore.util.Nullable U> searchFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public K reduceKeys(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull K,? super @libcore.util.NonNull K,? extends @libcore.util.Nullable K> reducer) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U reduceKeys(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull K,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull U,? super @libcore.util.NonNull U,? extends @libcore.util.Nullable U> reducer) { throw new RuntimeException("Stub!"); }
+
+  public double reduceKeysToDouble(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToDoubleFunction<? super @libcore.util.NonNull K> transformer, double basis, @libcore.util.NonNull java.util.function.DoubleBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public long reduceKeysToLong(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToLongFunction<? super @libcore.util.NonNull K> transformer, long basis, @libcore.util.NonNull java.util.function.LongBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public int reduceKeysToInt(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToIntFunction<? super @libcore.util.NonNull K> transformer, int basis, @libcore.util.NonNull java.util.function.IntBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public void forEachValue(long parallelismThreshold, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull V> action) { throw new RuntimeException("Stub!"); }
+
+  public <U> void forEachValue(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull U> action) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U searchValues(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> searchFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public V reduceValues(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull V,? super @libcore.util.NonNull V,? extends @libcore.util.Nullable V> reducer) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U reduceValues(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<? super @libcore.util.NonNull V,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull U,? super @libcore.util.NonNull U,? extends @libcore.util.Nullable U> reducer) { throw new RuntimeException("Stub!"); }
+
+  public double reduceValuesToDouble(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToDoubleFunction<? super @libcore.util.NonNull V> transformer, double basis, @libcore.util.NonNull java.util.function.DoubleBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public long reduceValuesToLong(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToLongFunction<? super @libcore.util.NonNull V> transformer, long basis, @libcore.util.NonNull java.util.function.LongBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public int reduceValuesToInt(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToIntFunction<? super @libcore.util.NonNull V> transformer, int basis, @libcore.util.NonNull java.util.function.IntBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public void forEachEntry(long parallelismThreshold, @libcore.util.NonNull java.util.function.Consumer<? super java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> action) { throw new RuntimeException("Stub!"); }
+
+  public <U> void forEachEntry(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull U> action) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U searchEntries(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>,? extends @libcore.util.Nullable U> searchFunction) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public java.util.Map.Entry<@libcore.util.NonNull K, @libcore.util.NonNull V> reduceEntries(long parallelismThreshold, @libcore.util.NonNull java.util.function.BiFunction<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>, java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>,? extends java.util.Map.@libcore.util.Nullable Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> reducer) { throw new RuntimeException("Stub!"); }
+
+  @libcore.util.Nullable public <U> U reduceEntries(long parallelismThreshold, @libcore.util.NonNull java.util.function.Function<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>,? extends @libcore.util.Nullable U> transformer, @libcore.util.NonNull java.util.function.BiFunction<? super @libcore.util.NonNull U,? super @libcore.util.NonNull U,? extends @libcore.util.Nullable U> reducer) { throw new RuntimeException("Stub!"); }
+
+  public double reduceEntriesToDouble(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToDoubleFunction<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> transformer, double basis, @libcore.util.NonNull java.util.function.DoubleBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public long reduceEntriesToLong(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToLongFunction<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> transformer, long basis, @libcore.util.NonNull java.util.function.LongBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  public int reduceEntriesToInt(long parallelismThreshold, @libcore.util.NonNull java.util.function.ToIntFunction<java.util.Map.@libcore.util.NonNull Entry<@libcore.util.NonNull K, @libcore.util.NonNull V>> transformer, int basis, @libcore.util.NonNull java.util.function.IntBinaryOperator reducer) { throw new RuntimeException("Stub!"); }
+
+  @SuppressWarnings({"unchecked", "deprecation", "all"})
+  public static class KeySetView<K, V> implements java.util.Collection<K>, java.io.Serializable, java.util.Set<K> {
+
+    KeySetView(@libcore.util.NonNull java.util.concurrent.ConcurrentHashMap<K,V> map, @libcore.util.Nullable V value) { throw new RuntimeException("Stub!"); }
+
+    @libcore.util.Nullable public V getMappedValue() { throw new RuntimeException("Stub!"); }
+
+    public boolean contains(@libcore.util.NonNull java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+    public boolean remove(@libcore.util.NonNull java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+    @libcore.util.NonNull public java.util.Iterator<@libcore.util.NonNull K> iterator() { throw new RuntimeException("Stub!"); }
+
+    public boolean add(@libcore.util.NonNull K e) { throw new RuntimeException("Stub!"); }
+
+    public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NonNull K> c) { throw new RuntimeException("Stub!"); }
+
+    public int hashCode() { throw new RuntimeException("Stub!"); }
+
+    public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+    @libcore.util.NonNull public java.util.Spliterator<@libcore.util.NonNull K> spliterator() { throw new RuntimeException("Stub!"); }
+
+    public void forEach(@libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NonNull K> action) { throw new RuntimeException("Stub!"); }
+
+    public final boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+    public final int size() { throw new RuntimeException("Stub!"); }
+
+    public final boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+
+    public final void clear() { throw new RuntimeException("Stub!"); }
+
+    public final boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+    public final java.lang.@libcore.util.NonNull Object @libcore.util.NonNull [] toArray() { throw new RuntimeException("Stub!"); }
+
+    public final <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a) { throw new RuntimeException("Stub!"); }
+
+    @libcore.util.NonNull public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+    @libcore.util.NonNull public java.util.concurrent.ConcurrentHashMap<@libcore.util.NonNull K, @libcore.util.NonNull V> getMap() { throw new RuntimeException("Stub!"); }
+
+    public final boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c) { throw new RuntimeException("Stub!"); }
+  }
+
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/concurrent/CopyOnWriteArrayList.annotated.java b/ojluni/annotations/sdk/nullability/java/util/concurrent/CopyOnWriteArrayList.annotated.java
new file mode 100644
index 0000000..57ab75c
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/concurrent/CopyOnWriteArrayList.annotated.java
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group.  Adapted and released, under explicit permission,
+ * from JDK ArrayList.java which carries the following copyright:
+ *
+ * Copyright 1997 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ */
+
+
+package java.util.concurrent;
+
+import java.util.ConcurrentModificationException;
+import java.util.List;
+import java.util.Objects;
+import java.util.Collection;
+import java.util.Spliterator;
+import java.util.AbstractList;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class CopyOnWriteArrayList<E> implements java.util.List<E>, java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable {
+
+public CopyOnWriteArrayList() { throw new RuntimeException("Stub!"); }
+
+public CopyOnWriteArrayList(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { throw new RuntimeException("Stub!"); }
+
+public CopyOnWriteArrayList(E @libcore.util.NonNull [] toCopyIn) { 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 indexOf(@libcore.util.Nullable E e, int index) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.Nullable E e, int index) { 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!"); }
+
+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 boolean addIfAbsent(@libcore.util.NullFromTypeParam E e) { throw new RuntimeException("Stub!"); }
+
+public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c) { 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!"); }
+
+public int addAllAbsent(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c) { 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!"); }
+
+public void forEach(@libcore.util.NonNull java.util.function.Consumer<? super @libcore.util.NullFromTypeParam E> action) { 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!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object o) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { 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.ListIterator<@libcore.util.NullFromTypeParam E> listIterator() { 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.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.List<@libcore.util.NullFromTypeParam E> subList(int fromIndex, int toIndex) { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/logging/Level.annotated.java b/ojluni/annotations/sdk/nullability/java/util/logging/Level.annotated.java
new file mode 100644
index 0000000..769e9fd
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/logging/Level.annotated.java
@@ -0,0 +1,79 @@
+/*
+ * 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
+ * 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.logging;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Level implements java.io.Serializable {
+
+protected Level(@libcore.util.NonNull java.lang.String name, int value) { throw new RuntimeException("Stub!"); }
+
+protected Level(@libcore.util.NonNull java.lang.String name, int value, @libcore.util.Nullable java.lang.String resourceBundleName) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getResourceBundleName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getLocalizedName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final int intValue() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static synchronized java.util.logging.Level parse(@libcore.util.NonNull java.lang.String name) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object ox) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.util.logging.Level ALL;
+static { ALL = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level CONFIG;
+static { CONFIG = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level FINE;
+static { FINE = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level FINER;
+static { FINER = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level FINEST;
+static { FINEST = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level INFO;
+static { INFO = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level OFF;
+static { OFF = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level SEVERE;
+static { SEVERE = null; }
+
+@libcore.util.NonNull public static final java.util.logging.Level WARNING;
+static { WARNING = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/logging/Logger.annotated.java b/ojluni/annotations/sdk/nullability/java/util/logging/Logger.annotated.java
new file mode 100644
index 0000000..2ad4bfb
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/logging/Logger.annotated.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2000, 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.logging;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.function.Supplier;
+import java.util.MissingResourceException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Logger {
+
+protected Logger(@libcore.util.Nullable java.lang.String name, @libcore.util.Nullable java.lang.String resourceBundleName) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.util.logging.Logger getGlobal() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.logging.Logger getLogger(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.logging.Logger getLogger(@libcore.util.NonNull java.lang.String name, @libcore.util.Nullable java.lang.String resourceBundleName) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.logging.Logger getAnonymousLogger() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.logging.Logger getAnonymousLogger(@libcore.util.Nullable java.lang.String resourceBundleName) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.ResourceBundle getResourceBundle() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getResourceBundleName() { throw new RuntimeException("Stub!"); }
+
+public void setFilter(@libcore.util.Nullable java.util.logging.Filter newFilter) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.logging.Filter getFilter() { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.LogRecord record) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Object param1) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String msg, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] params) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Throwable thrown) { throw new RuntimeException("Stub!"); }
+
+public void log(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.Throwable thrown, @libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Object param1) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String msg, java.lang.@libcore.util.Nullable Object @Nu [] params) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Throwable thrown) { throw new RuntimeException("Stub!"); }
+
+public void logp(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.Throwable thrown, @libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String bundleName, @libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String bundleName, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Object param1) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String bundleName, @libcore.util.Nullable java.lang.String msg, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] params) { throw new RuntimeException("Stub!"); }
+
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.util.ResourceBundle bundle, @libcore.util.Nullable java.lang.String msg, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable ... params) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.String bundleName, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Throwable thrown) { throw new RuntimeException("Stub!"); }
+
+public void logrb(@libcore.util.NonNull java.util.logging.Level level, @libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.util.ResourceBundle bundle, @libcore.util.Nullable java.lang.String msg, @libcore.util.Nullable java.lang.Throwable thrown) { throw new RuntimeException("Stub!"); }
+
+public void entering(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod) { throw new RuntimeException("Stub!"); }
+
+public void entering(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.Object param1) { throw new RuntimeException("Stub!"); }
+
+public void entering(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, java.lang.@libcore.util.Nullable Object @libcore.util.Nullable [] params) { throw new RuntimeException("Stub!"); }
+
+public void exiting(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod) { throw new RuntimeException("Stub!"); }
+
+public void exiting(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.Object result) { throw new RuntimeException("Stub!"); }
+
+public void throwing(@libcore.util.Nullable java.lang.String sourceClass, @libcore.util.Nullable java.lang.String sourceMethod, @libcore.util.Nullable java.lang.Throwable thrown) { throw new RuntimeException("Stub!"); }
+
+public void severe(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void warning(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void info(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void config(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void fine(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void finer(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void finest(@libcore.util.Nullable java.lang.String msg) { throw new RuntimeException("Stub!"); }
+
+public void severe(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void warning(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void info(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void config(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void fine(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void finer(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void finest(@libcore.util.NonNull java.util.function.Supplier<java.lang.@libcore.util.Nullable String> msgSupplier) { throw new RuntimeException("Stub!"); }
+
+public void setLevel(@libcore.util.Nullable java.util.logging.Level newLevel) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.logging.Level getLevel() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoggable(@libcore.util.NonNull java.util.logging.Level level) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public void addHandler(@libcore.util.NonNull java.util.logging.Handler handler) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public void removeHandler(@libcore.util.Nullable java.util.logging.Handler handler) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.util.logging.@libcore.util.NonNull Handler @libcore.util.NonNull [] getHandlers() { throw new RuntimeException("Stub!"); }
+
+public void setUseParentHandlers(boolean useParentHandlers) { throw new RuntimeException("Stub!"); }
+
+public boolean getUseParentHandlers() { throw new RuntimeException("Stub!"); }
+
+public void setResourceBundle(@libcore.util.NonNull java.util.ResourceBundle bundle) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.util.logging.Logger getParent() { throw new RuntimeException("Stub!"); }
+
+public void setParent(@libcore.util.NonNull java.util.logging.Logger parent) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static final java.lang.String GLOBAL_LOGGER_NAME = "global";
+
+@Deprecated @libcore.util.NonNull public static final java.util.logging.Logger global;
+static { global = null; }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/regex/Matcher.annotated.java b/ojluni/annotations/sdk/nullability/java/util/regex/Matcher.annotated.java
new file mode 100644
index 0000000..1bc7c89
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/regex/Matcher.annotated.java
@@ -0,0 +1,103 @@
+/*
+ * 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.util.regex;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Matcher implements java.util.regex.MatchResult {
+
+Matcher(@libcore.util.NonNull java.util.regex.Pattern parent, @libcore.util.NonNull java.lang.CharSequence text) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Pattern pattern() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.MatchResult toMatchResult() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher usePattern(@libcore.util.NonNull java.util.regex.Pattern newPattern) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher reset() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher reset(@libcore.util.NonNull java.lang.CharSequence input) { throw new RuntimeException("Stub!"); }
+
+public int start() { throw new RuntimeException("Stub!"); }
+
+public int start(int group) { throw new RuntimeException("Stub!"); }
+
+public int start(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int end() { throw new RuntimeException("Stub!"); }
+
+public int end(int group) { throw new RuntimeException("Stub!"); }
+
+public int end(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String group() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String group(int group) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String group(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int groupCount() { throw new RuntimeException("Stub!"); }
+
+public boolean matches() { throw new RuntimeException("Stub!"); }
+
+public boolean find() { throw new RuntimeException("Stub!"); }
+
+public boolean find(int start) { throw new RuntimeException("Stub!"); }
+
+public boolean lookingAt() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String quoteReplacement(@libcore.util.NonNull java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher appendReplacement(@libcore.util.NonNull java.lang.StringBuffer sb, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.StringBuffer appendTail(@libcore.util.NonNull java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceAll(@libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String replaceFirst(@libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher region(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public int regionStart() { throw new RuntimeException("Stub!"); }
+
+public int regionEnd() { throw new RuntimeException("Stub!"); }
+
+public boolean hasTransparentBounds() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher useTransparentBounds(boolean b) { throw new RuntimeException("Stub!"); }
+
+public boolean hasAnchoringBounds() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher useAnchoringBounds(boolean b) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public boolean hitEnd() { throw new RuntimeException("Stub!"); }
+
+public boolean requireEnd() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/sdk/nullability/java/util/regex/Pattern.annotated.java b/ojluni/annotations/sdk/nullability/java/util/regex/Pattern.annotated.java
new file mode 100644
index 0000000..66db450
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/util/regex/Pattern.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * 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.util.regex;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Pattern implements java.io.Serializable {
+
+Pattern(@libcore.util.NonNull java.lang.String p, int f) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.regex.Pattern compile(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.util.regex.Pattern compile(@libcore.util.NonNull java.lang.String regex, int flags) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String pattern() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.regex.Matcher matcher(@libcore.util.NonNull java.lang.CharSequence input) { throw new RuntimeException("Stub!"); }
+
+public int flags() { throw new RuntimeException("Stub!"); }
+
+public static boolean matches(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.CharSequence input) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.CharSequence input, int limit) { throw new RuntimeException("Stub!"); }
+
+public java.lang.@libcore.util.NonNull String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.CharSequence input) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.lang.String quote(@libcore.util.NonNull java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.function.Predicate<java.lang.@libcore.util.NonNull String> asPredicate() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.util.stream.Stream<java.lang.@libcore.util.NonNull String> splitAsStream(@libcore.util.NonNull java.lang.CharSequence input) { throw new RuntimeException("Stub!"); }
+
+public static final int CANON_EQ = 128; // 0x80
+
+public static final int CASE_INSENSITIVE = 2; // 0x2
+
+public static final int COMMENTS = 4; // 0x4
+
+public static final int DOTALL = 32; // 0x20
+
+public static final int LITERAL = 16; // 0x10
+
+public static final int MULTILINE = 8; // 0x8
+
+public static final int UNICODE_CASE = 64; // 0x40
+
+public static final int UNICODE_CHARACTER_CLASS = 256; // 0x100
+
+public static final int UNIX_LINES = 1; // 0x1
+}
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..74ee3aa 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");
@@ -472,7 +478,7 @@
         initIDs();
     }
     */
-    // END Android-changed: Unused code.
+    // END Android-removed: Unused code.
 
     /**
      * Ensures that the <code>close</code> method of this file input stream is
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..56b5abe 100644
--- a/ojluni/src/main/java/java/io/ObjectInputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectInputStream.java
@@ -202,7 +202,7 @@
  * @see java.io.DataInput
  * @see java.io.ObjectOutputStream
  * @see java.io.Serializable
- * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
+ * @see <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
  * @since   JDK1.1
  */
 public class ObjectInputStream
@@ -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/ObjectOutputStream.java b/ojluni/src/main/java/java/io/ObjectOutputStream.java
index 7c4f0ca..fa8a658 100644
--- a/ojluni/src/main/java/java/io/ObjectOutputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectOutputStream.java
@@ -157,7 +157,7 @@
  * @see java.io.ObjectInputStream
  * @see java.io.Serializable
  * @see java.io.Externalizable
- * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
+ * @see <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
  * @since       JDK1.1
  */
 public class ObjectOutputStream
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index b2651b8..7d2efd2 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -53,20 +53,20 @@
 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
  * loaded in this Java VM can be found/created using the lookup method.
  *
  * <p>The algorithm to compute the SerialVersionUID is described in
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/class.html#4100">Object
+ * <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#4100">Object
  * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
  *
  * @author      Mike Warres
  * @author      Roger Riggs
  * @see ObjectStreamField
- * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
+ * @see <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
  * @since   JDK1.1
  */
 public class ObjectStreamClass implements Serializable {
@@ -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);
             }
         }
@@ -1798,10 +1797,27 @@
                 }
             }
 
-            // Android-changed: Clinit serialization workaround b/29064453
-            boolean checkSuperclass = !(VMRuntime.getRuntime().getTargetSdkVersion()
-                                       <= MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND);
-            if (hasStaticInitializer(cl, checkSuperclass)) {
+            // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
+            // Prior to SDK 24 hasStaticInitializer() would return true if the superclass had a
+            // static initializer, that was contrary to the specification. In SDK 24 the default
+            // behavior was corrected but the old behavior was preserved for apps that targeted 23
+            // or below in order to maintain backwards compatibility.
+            //
+            // if (hasStaticInitializer(cl)) {
+            boolean inheritStaticInitializer =
+                (VMRuntime.getRuntime().getTargetSdkVersion()
+                <= MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND);
+            boolean warnIncompatibleSUIDChange = false;
+            if (hasStaticInitializer(cl, inheritStaticInitializer)) {
+                // If a static initializer was found but the current class does not have one then
+                // the class's default SUID will change if the app targets SDK > 24 so send a
+                // warning.
+                if (inheritStaticInitializer && !hasStaticInitializer(cl, false)) {
+                    // Defer until hash has been calculated so the warning message can give precise
+                    // instructions to the developer on how to fix the problems.
+                    warnIncompatibleSUIDChange = true;
+                }
+                // END Android-changed: Fix/log clinit serialization workaround b/29064453
                 dout.writeUTF("<clinit>");
                 dout.writeInt(Modifier.STATIC);
                 dout.writeUTF("()V");
@@ -1866,6 +1882,14 @@
             for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
                 hash = (hash << 8) | (hashBytes[i] & 0xFF);
             }
+            // BEGIN Android-added: Fix/log clinit serialization workaround b/29064453
+            // ObjectStreamClass instances are cached per Class and caches its default
+            // serialVersionUID so it will only log one message per class per app process
+            // irrespective of the number of times the class is serialized.
+            if (warnIncompatibleSUIDChange) {
+                suidCompatibilityListener.warnDefaultSUIDTargetVersionDependent(cl, hash);
+            }
+            // END Android-added: Fix/log clinit serialization workaround b/29064453
             return hash;
         } catch (IOException ex) {
             throw new InternalError(ex);
@@ -1874,18 +1898,52 @@
         }
     }
 
-    // BEGIN Android-changed: Clinit serialization workaround b/29064453
-    /** Max SDK target version for which we use buggy hasStaticIntializier implementation. */
+    // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
+    /**
+     * Created for testing as there is no nice way to detect when a message is logged.
+     *
+     * @hide
+     */
+    public interface DefaultSUIDCompatibilityListener {
+        /**
+         * Called when a class being serialized/deserialized relies on the default SUID computation
+         * (because it has no explicit {@code serialVersionUID} field) where that computation is
+         * dependent on the app's targetSdkVersion.
+         *
+         * @param clazz the clazz for which the default SUID is being computed.
+         * @param hash the computed value.
+         */
+        void warnDefaultSUIDTargetVersionDependent(Class<?> clazz, long hash);
+    }
+
+    /**
+     * Public and mutable for testing purposes.
+     *
+     * @hide
+     */
+    public static DefaultSUIDCompatibilityListener suidCompatibilityListener =
+        (clazz, hash) -> {
+            System.logW("Class " + clazz.getCanonicalName() + " relies on its default SUID which"
+                + " is dependent on the app's targetSdkVersion. To avoid problems during upgrade"
+                + " add the following to class " + clazz.getCanonicalName() + "\n"
+                + "    private static final long serialVersionUID = " + hash + "L;");
+        };
+
+    /** Max SDK target version for which we use buggy hasStaticInitializer implementation. */
     static final int MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND = 23;
 
     /**
      * Returns true if the given class defines a static initializer method,
      * false otherwise.
-     * if checkSuperclass is false, we use a buggy version (for compatibility reason) that
-     * will return true even if only the superclass has a static initializer method.
+     *
+     * @param inheritStaticInitializer if false then this method will return true iff the given
+     * class has its own static initializer, if true (used for backwards compatibility for apps
+     * that target SDK version <= {@link #MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND}) it will
+     * return true if the given class or any of its ancestor classes have a static initializer.
      */
-    private native static boolean hasStaticInitializer(Class<?> cl, boolean checkSuperclass);
-    // END Android-changed: Clinit serialization workaround b/29064453
+    private native static boolean hasStaticInitializer(
+        Class<?> cl, boolean inheritStaticInitializer);
+    // END Android-changed: Fix/log clinit serialization workaround b/29064453
 
     /**
      * Class for computing and caching field/constructor/method signatures
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/PipedReader.java b/ojluni/src/main/java/java/io/PipedReader.java
index cc32d17..d72e1e5 100644
--- a/ojluni/src/main/java/java/io/PipedReader.java
+++ b/ojluni/src/main/java/java/io/PipedReader.java
@@ -186,7 +186,7 @@
             try {
                 wait(1000);
             } catch (InterruptedException ex) {
-                // BEGIN Android-changed: re-set the thread's interrupt status
+                // Android-changed: re-set the thread's interrupt status
                 // throw new java.io.InterruptedIOException();
                 IoUtils.throwInterruptedIoException();
             }
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..e2aad21 100644
--- a/ojluni/src/main/java/java/io/UnixFileSystem.java
+++ b/ojluni/src/main/java/java/io/UnixFileSystem.java
@@ -27,7 +27,13 @@
 
 import java.security.AccessController;
 
+import android.system.ErrnoException;
+import android.system.OsConstants;
+
 import dalvik.system.BlockGuard;
+
+import libcore.io.Libcore;
+
 import sun.security.action.GetPropertyAction;
 
 
@@ -166,7 +172,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 +245,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 +257,67 @@
         return rv | (hidden ? BA_HIDDEN : 0);
     }
 
-    // Android-changed: Added thread policy check
+    // Android-changed: Access files through common interface.
     public boolean checkAccess(File f, int access) {
-        BlockGuard.getThreadPolicy().onReadFromDisk();
-        return checkAccess0(f, access);
-    }
-    private native boolean checkAccess0(File f, int access);
+        final int mode;
+        switch (access) {
+            case FileSystem.ACCESS_OK:
+                mode = OsConstants.F_OK;
+                break;
+            case FileSystem.ACCESS_READ:
+                mode = OsConstants.R_OK;
+                break;
+            case FileSystem.ACCESS_WRITE:
+                mode = OsConstants.W_OK;
+                break;
+            case FileSystem.ACCESS_EXECUTE:
+                mode = OsConstants.X_OK;
+                break;
+            default:
+                throw new IllegalArgumentException("Bad access mode: " + access);
+        }
 
-    // Android-changed: Added thread policy check
+        try {
+            return Libcore.os.access(f.getPath(), mode);
+        } catch (ErrnoException e) {
+            return false;
+        }
+    }
+
+    // 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: Access files through common interface.
     public long getLength(File f) {
-        BlockGuard.getThreadPolicy().onReadFromDisk();
-        return getLength0(f);
+        try {
+            return Libcore.os.stat(f.getPath()).st_size;
+        } catch (ErrnoException e) {
+            return 0;
+        }
     }
-    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 +326,35 @@
         // anyway.
         cache.clear();
         javaHomePrefixCache.clear();
-        BlockGuard.getThreadPolicy().onWriteToDisk();
-        return delete0(f);
+        // BEGIN Android-changed: Access files through common interface.
+        try {
+            Libcore.os.remove(f.getPath());
+            return true;
+        } catch (ErrnoException e) {
+            return false;
+        }
+        // END Android-changed: Access files through common interface.
     }
 
-    private native boolean delete0(File f);
+    // Android-removed: Access files through common interface.
+    // 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 +363,31 @@
         // anyway.
         cache.clear();
         javaHomePrefixCache.clear();
-        BlockGuard.getThreadPolicy().onWriteToDisk();
-        return rename0(f1, f2);
+        // BEGIN Android-changed: Access files through common interface.
+        try {
+            Libcore.os.rename(f1.getPath(), f2.getPath());
+            return true;
+        } catch (ErrnoException e) {
+            return false;
+        }
+        // END Android-changed: Access files through common interface.
     }
 
-    private native boolean rename0(File f1, File f2);
+    // Android-removed: Access files through common interface.
+    // 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 +408,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/io/package.html b/ojluni/src/main/java/java/io/package.html
index 295da7f..db1c8a5 100644
--- a/ojluni/src/main/java/java/io/package.html
+++ b/ojluni/src/main/java/java/io/package.html
@@ -36,7 +36,7 @@
 
 <h2>Package Specification</h2>
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/serialTOC.html"> Java Object Serialization Specification </a>
+  <li><a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html"> Java Object Serialization Specification </a>
 </ul>
 
 <h2>Related Documentation</h2>
@@ -44,7 +44,7 @@
 For overviews, tutorials, examples, guides, and tool documentation,
 please see:
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/serialization">Serialization Enhancements</a>
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/serialization">Serialization Enhancements</a>
 </ul>
 
 @since JDK1.0
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..8b1635d 100644
--- a/ojluni/src/main/java/java/lang/Character.java
+++ b/ojluni/src/main/java/java/lang/Character.java
@@ -578,6 +578,9 @@
      */
     public static final int MAX_CODE_POINT = 0X10FFFF;
 
+    // BEGIN Android-added: Use ICU.
+    // The indices in int[] DIRECTIONALITY are based on icu4c's u_charDirection(),
+    // accessed via getDirectionalityImpl(), implemented in Character.cpp.
     private static final byte[] DIRECTIONALITY = new byte[] {
             DIRECTIONALITY_LEFT_TO_RIGHT, DIRECTIONALITY_RIGHT_TO_LEFT,
             DIRECTIONALITY_EUROPEAN_NUMBER,
@@ -595,6 +598,7 @@
             DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
             DIRECTIONALITY_POP_DIRECTIONAL_FORMAT,
             DIRECTIONALITY_NONSPACING_MARK, DIRECTIONALITY_BOUNDARY_NEUTRAL };
+    // END Android-added: Use ICU.
 
     /**
      * Instances of this class represent particular subsets of the Unicode
@@ -672,15 +676,19 @@
          * This name must be the same as the block identifier.
          */
         private UnicodeBlock(String idName) {
-            this(idName, true);
+            super(idName);
+            map.put(idName, this);
         }
 
+        // BEGIN Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+        // Add a (String, boolean) constructor for use by SURROGATES_AREA.
         private UnicodeBlock(String idName, boolean isMap) {
             super(idName);
             if (isMap) {
                 map.put(idName, this);
             }
         }
+        // END Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
 
         /**
          * Creates a UnicodeBlock with the given identifier name and
@@ -1260,6 +1268,8 @@
          */
         @Deprecated
         public static final UnicodeBlock SURROGATES_AREA =
+            // Android-changed: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+            // new UnicodeBlock("SURROGATES_AREA");
             new UnicodeBlock("SURROGATES_AREA", false);
 
         /**
@@ -5473,12 +5483,20 @@
      * @see     Character#getType(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLowerCase(int codePoint) {
+        return getType(codePoint) == Character.LOWERCASE_LETTER ||
+               CharacterData.of(codePoint).isOtherLowercase(codePoint);
+    }
+    */
     public static boolean isLowerCase(int codePoint) {
         return isLowerCaseImpl(codePoint);
     }
 
     @FastNative
     static native boolean isLowerCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is an uppercase character.
@@ -5541,13 +5559,20 @@
      * @see     Character#getType(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUpperCase(int codePoint) {
+        return getType(codePoint) == Character.UPPERCASE_LETTER ||
+               CharacterData.of(codePoint).isOtherUppercase(codePoint);
+    }
+    */
     public static boolean isUpperCase(int codePoint) {
         return isUpperCaseImpl(codePoint);
     }
 
     @FastNative
     static native boolean isUpperCaseImpl(int codePoint);
-
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is a titlecase character.
@@ -5622,12 +5647,19 @@
      * @see     Character#getType(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isTitleCase(int codePoint) {
+        return getType(codePoint) == Character.TITLECASE_LETTER;
+    }
+    */
     public static boolean isTitleCase(int codePoint) {
         return isTitleCaseImpl(codePoint);
     }
 
     @FastNative
     static native boolean isTitleCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is a digit.
@@ -5698,12 +5730,19 @@
      * @see     Character#getType(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isDigit(int codePoint) {
+        return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
+    }
+    */
     public static boolean isDigit(int codePoint) {
         return isDigitImpl(codePoint);
     }
 
     @FastNative
     static native boolean isDigitImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if a character is defined in Unicode.
@@ -5754,12 +5793,19 @@
      * @see     Character#isUpperCase(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isDefined(int codePoint) {
+        return getType(codePoint) != Character.UNASSIGNED;
+    }
+    */
     public static boolean isDefined(int codePoint) {
         return isDefinedImpl(codePoint);
     }
 
     @FastNative
     static native boolean isDefinedImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is a letter.
@@ -5829,12 +5875,24 @@
      * @see     Character#isUpperCase(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLetter(int codePoint) {
+        return ((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
     public static boolean isLetter(int codePoint) {
         return isLetterImpl(codePoint);
     }
 
     @FastNative
     static native boolean isLetterImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is a letter or digit.
@@ -5881,12 +5939,25 @@
      * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLetterOrDigit(int codePoint) {
+        return ((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER) |
+            (1 << Character.DECIMAL_DIGIT_NUMBER)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
     public static boolean isLetterOrDigit(int codePoint) {
         return isLetterOrDigitImpl(codePoint);
     }
 
     @FastNative
     static native boolean isLetterOrDigitImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is permissible as the first
@@ -5976,13 +6047,25 @@
      *          character, <code>false</code> otherwise.
      * @since   1.7
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isAlphabetic(int codePoint) {
+        return (((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER) |
+            (1 << Character.LETTER_NUMBER)) >> getType(codePoint)) & 1) != 0) ||
+            CharacterData.of(codePoint).isOtherAlphabetic(codePoint);
+    }
+    */
     public static boolean isAlphabetic(int codePoint) {
         return isAlphabeticImpl(codePoint);
     }
 
     @FastNative
     static native boolean isAlphabeticImpl(int codePoint);
-
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character (Unicode code point) is a CJKV
@@ -5994,12 +6077,21 @@
      *          character, <code>false</code> otherwise.
      * @since   1.7
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isIdeographic(int codePoint) {
+        return CharacterData.of(codePoint).isIdeographic(codePoint);
+    }
+    */
     public static boolean isIdeographic(int codePoint) {
         return isIdeographicImpl(codePoint);
     }
     @FastNative
     static native boolean isIdeographicImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
+    // 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 +6116,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,9 +6146,14 @@
      * @see     Character#isJavaIdentifierPart(int)
      * @see     Character#isLetter(int)
      * @see     Character#isUnicodeIdentifierStart(int)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
+    // BEGIN Android-changed: Use ICU.
+    /*
+    public static boolean isJavaIdentifierStart(int codePoint) {
+        return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint);
+    }
+    */
     public static boolean isJavaIdentifierStart(int codePoint) {
         // Use precomputed bitmasks to optimize the ASCII range.
         if (codePoint < 64) {
@@ -6073,7 +6171,10 @@
                    | (1  << CONNECTOR_PUNCTUATION)
                    | (1  << LETTER_NUMBER))) != 0;
     }
+    // END Android-changed: Use ICU.
 
+    // 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 +6205,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,9 +6239,14 @@
      * @see     Character#isJavaIdentifierStart(int)
      * @see     Character#isLetterOrDigit(int)
      * @see     Character#isUnicodeIdentifierPart(int)
-     * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
+    // BEGIN Android-changed: Use ICU.
+    /*
+    public static boolean isJavaIdentifierPart(int codePoint) {
+        return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint);
+    }
+    */
     public static boolean isJavaIdentifierPart(int codePoint) {
         // Use precomputed bitmasks to optimize the ASCII range.
         if (codePoint < 64) {
@@ -6163,6 +6270,7 @@
                 || (codePoint >= 0 && codePoint <= 8) || (codePoint >= 0xe && codePoint <= 0x1b)
                 || (codePoint >= 0x7f && codePoint <= 0x9f);
     }
+    // END Android-changed: Use ICU.
 
     /**
      * Determines if the specified character is permissible as the
@@ -6213,12 +6321,19 @@
      * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUnicodeIdentifierStart(int codePoint) {
+        return CharacterData.of(codePoint).isUnicodeIdentifierStart(codePoint);
+    }
+    */
     public static boolean isUnicodeIdentifierStart(int codePoint) {
         return isUnicodeIdentifierStartImpl(codePoint);
     }
 
     @FastNative
     static native boolean isUnicodeIdentifierStartImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character may be part of a Unicode
@@ -6280,12 +6395,19 @@
      * @see     Character#isUnicodeIdentifierStart(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUnicodeIdentifierPart(int codePoint) {
+        return CharacterData.of(codePoint).isUnicodeIdentifierPart(codePoint);
+    }
+    */
     public static boolean isUnicodeIdentifierPart(int codePoint) {
         return isUnicodeIdentifierPartImpl(codePoint);
     }
 
     @FastNative
     static native boolean isUnicodeIdentifierPartImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character should be regarded as
@@ -6348,12 +6470,19 @@
      * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isIdentifierIgnorable(int codePoint) {
+        return CharacterData.of(codePoint).isIdentifierIgnorable(codePoint);
+    }
+    */
     public static boolean isIdentifierIgnorable(int codePoint) {
         return isIdentifierIgnorableImpl(codePoint);
     }
 
     @FastNative
     static native boolean isIdentifierIgnorableImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Converts the character argument to lowercase using case
@@ -6411,6 +6540,12 @@
      *
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toLowerCase(int codePoint) {
+        return CharacterData.of(codePoint).toLowerCase(codePoint);
+    }
+    */
     public static int toLowerCase(int codePoint) {
         if (codePoint >= 'A' && codePoint <= 'Z') {
             return codePoint + ('a' - 'A');
@@ -6426,6 +6561,7 @@
 
     @FastNative
     static native int toLowerCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Converts the character argument to uppercase using case mapping
@@ -6483,6 +6619,12 @@
      *
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toUpperCase(int codePoint) {
+        return CharacterData.of(codePoint).toUpperCase(codePoint);
+    }
+    */
     public static int toUpperCase(int codePoint) {
         if (codePoint >= 'a' && codePoint <= 'z') {
             return codePoint - ('a' - 'A');
@@ -6498,6 +6640,7 @@
 
     @FastNative
     static native int toUpperCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Converts the character argument to titlecase using case mapping
@@ -6554,12 +6697,19 @@
      * @see     Character#toUpperCase(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toTitleCase(int codePoint) {
+        return CharacterData.of(codePoint).toTitleCase(codePoint);
+    }
+    */
     public static int toTitleCase(int codePoint) {
         return toTitleCaseImpl(codePoint);
     }
 
     @FastNative
     static native int toTitleCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Returns the numeric value of the character {@code ch} in the
@@ -6663,6 +6813,12 @@
      * @see     Character#isDigit(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int digit(int codePoint, int radix) {
+        return CharacterData.of(codePoint).digit(codePoint, radix);
+    }
+    */
     public static int digit(int codePoint, int radix) {
         if (radix < MIN_RADIX || radix > MAX_RADIX) {
             return -1;
@@ -6684,6 +6840,7 @@
 
     @FastNative
     native static int digitImpl(int codePoint, int radix);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Returns the {@code int} value that the specified Unicode
@@ -6752,6 +6909,12 @@
      * @see     Character#isDigit(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int getNumericValue(int codePoint) {
+        return CharacterData.of(codePoint).getNumericValue(codePoint);
+    }
+    */
     public static int getNumericValue(int codePoint) {
         // This is both an optimization and papers over differences between Java and ICU.
         if (codePoint < 128) {
@@ -6779,6 +6942,7 @@
 
     @FastNative
     native static int getNumericValueImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is ISO-LATIN-1 white space.
@@ -6861,6 +7025,15 @@
      * @see     Character#isWhitespace(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isSpaceChar(int codePoint) {
+        return ((((1 << Character.SPACE_SEPARATOR) |
+                  (1 << Character.LINE_SEPARATOR) |
+                  (1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
     public static boolean isSpaceChar(int codePoint) {
         // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
         // SPACE or NO-BREAK SPACE?
@@ -6888,6 +7061,7 @@
 
     @FastNative
     static native boolean isSpaceCharImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is white space according to Java.
@@ -6952,6 +7126,12 @@
      * @see     Character#isSpaceChar(int)
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isWhitespace(int codePoint) {
+        return CharacterData.of(codePoint).isWhitespace(codePoint);
+    }
+    */
     public static boolean isWhitespace(int codePoint) {
         // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
         // Any ASCII whitespace character?
@@ -6983,6 +7163,7 @@
 
     @FastNative
     native static boolean isWhitespaceImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines if the specified character is an ISO control
@@ -7115,6 +7296,12 @@
      * @see     Character#UPPERCASE_LETTER UPPERCASE_LETTER
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int getType(int codePoint) {
+        return CharacterData.of(codePoint).getType(codePoint);
+    }
+    */
     public static int getType(int codePoint) {
         int type = getTypeImpl(codePoint);
         // The type values returned by ICU are not RI-compatible. The RI skips the value 17.
@@ -7126,6 +7313,7 @@
 
     @FastNative
     static native int getTypeImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
 
     /**
      * Determines the character representation for a specific digit in
@@ -7238,6 +7426,12 @@
      * @see Character#DIRECTIONALITY_POP_DIRECTIONAL_FORMAT DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
      * @since    1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static byte getDirectionality(int codePoint) {
+        return CharacterData.of(codePoint).getDirectionality(codePoint);
+    }
+    */
     public static byte getDirectionality(int codePoint) {
         if (getType(codePoint) == Character.UNASSIGNED) {
             return Character.DIRECTIONALITY_UNDEFINED;
@@ -7252,6 +7446,8 @@
 
     @FastNative
     native static byte getDirectionalityImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
     /**
      * Determines whether the character is mirrored according to the
      * Unicode specification.  Mirrored characters should have their
@@ -7290,12 +7486,20 @@
      *          if the character is not mirrored or is not defined.
      * @since   1.5
      */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isMirrored(int codePoint) {
+        return CharacterData.of(codePoint).isMirrored(codePoint);
+    }
+    */
     public static boolean isMirrored(int codePoint) {
         return isMirroredImpl(codePoint);
     }
 
     @FastNative
     native static boolean isMirroredImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
     /**
      * Compares two {@code Character} objects numerically.
      *
@@ -7333,6 +7537,46 @@
         return x - y;
     }
 
+    // BEGIN Android-removed: Use ICU.
+    /**
+     * Converts the character (Unicode code point) argument to uppercase using
+     * information from the UnicodeData file.
+     * <p>
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return  either the uppercase equivalent of the character, if
+     *          any, or an error flag ({@code Character.ERROR})
+     *          that indicates that a 1:M {@code char} mapping exists.
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isUpperCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#toTitleCase(char)
+     * @since 1.4
+     *
+    static int toUpperCaseEx(int codePoint) {
+        assert isValidCodePoint(codePoint);
+        return CharacterData.of(codePoint).toUpperCaseEx(codePoint);
+    }
+
+    /**
+     * Converts the character (Unicode code point) argument to uppercase using case
+     * mapping information from the SpecialCasing file in the Unicode
+     * specification. If a character has no explicit uppercase
+     * mapping, then the {@code char} itself is returned in the
+     * {@code char[]}.
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return a {@code char[]} with the uppercased character.
+     * @since 1.4
+     *
+    static char[] toUpperCaseCharArray(int codePoint) {
+        // As of Unicode 6.0, 1:M uppercasings only happen in the BMP.
+        assert isBmpCodePoint(codePoint);
+        return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
+    }
+    */
+    // END Android-removed: Use ICU.
+
     /**
      * The number of bits used to represent a <tt>char</tt> value in unsigned
      * binary form, constant {@code 16}.
@@ -7394,6 +7638,8 @@
         if (!isValidCodePoint(codePoint)) {
             throw new IllegalArgumentException();
         }
+        // Android-changed: Use ICU.
+        // String name = CharacterName.get(codePoint);
         String name = getNameImpl(codePoint);
         if (name != null)
             return name;
@@ -7407,5 +7653,7 @@
         return Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
     }
 
+    // Android-added: Use ICU.
+    // Implement getNameImpl() natively.
     private static native String getNameImpl(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/Comparable.java b/ojluni/src/main/java/java/lang/Comparable.java
index c14e493..f0e4b38 100644
--- a/ojluni/src/main/java/java/lang/Comparable.java
+++ b/ojluni/src/main/java/java/lang/Comparable.java
@@ -84,7 +84,7 @@
  *     {(x, y) such that x.equals(y)}. </pre><p>
  *
  * This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <T> the type of objects that this object may be compared to
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/Iterable.java b/ojluni/src/main/java/java/lang/Iterable.java
index 10ff0bb..db0e767 100644
--- a/ojluni/src/main/java/java/lang/Iterable.java
+++ b/ojluni/src/main/java/java/lang/Iterable.java
@@ -35,7 +35,7 @@
  * Implementing this interface allows an object to be the target of
  * the "for-each loop" statement. See
  * <strong>
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/language/foreach.html">For-each Loop</a>
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html">For-each Loop</a>
  * </strong>
  *
  * @param <T> the type of elements returned by the iterator
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..bb0bcb4 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, fromClass, libname);
     }
 
     /**
@@ -992,16 +1021,42 @@
         checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)");
         java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" +
                               " is private and will be removed in a future Android release");
-        loadLibrary0(classLoader, libname);
+        // Pass null for callerClass, we don't know it at this point. Passing null preserved
+        // the behavior when we used to not pass the class.
+        loadLibrary0(classLoader, null, libname);
     }
 
-    synchronized void loadLibrary0(ClassLoader loader, String libname) {
+    // This overload exists for @UnsupportedAppUsage
+    void loadLibrary0(ClassLoader loader, String libname) {
+        // Pass null for callerClass, we don't know it at this point. Passing null preserved
+        // the behavior when we used to not pass the class.
+        loadLibrary0(loader, null, libname);
+    }
+    
+    /**
+     * Loads the shared library {@code libname} in the context of {@code loader} and
+     * {@code callerClass}.
+     *
+     * @param      loader    the class loader that initiated the loading. Used by the
+     *                       underlying linker to determine linker namespace. A {@code null}
+     *                       value represents the boot class loader.
+     * @param      fromClass the class that initiated the loading. Used when loader is
+     *                       {@code null} and ignored in all other cases. When used, it 
+     *                       determines the linker namespace from the class's .dex location.
+     *                       {@code null} indicates the default namespace for the boot 
+     *                       class loader.
+     * @param      libname   the name of the library.
+     */
+    private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) {
         if (libname.indexOf((int)File.separatorChar) != -1) {
             throw new UnsatisfiedLinkError(
     "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
@@ -1018,26 +1073,14 @@
             return;
         }
 
+        // We know some apps use mLibPaths directly, potentially assuming it's not null.
+        // Initialize it here to make sure apps see a non-null value.
+        getLibPaths();
         String filename = System.mapLibraryName(libraryName);
-        List<String> candidates = new ArrayList<String>();
-        String lastError = null;
-        for (String directory : getLibPaths()) {
-            String candidate = directory + filename;
-            candidates.add(candidate);
-
-            if (IoUtils.canOpenReadOnly(candidate)) {
-                String error = nativeLoad(candidate, loader);
-                if (error == null) {
-                    return; // We successfully loaded the library. Job done.
-                }
-                lastError = error;
-            }
+        String error = nativeLoad(filename, loader, callerClass);
+        if (error != null) {
+            throw new UnsatisfiedLinkError(error);
         }
-
-        if (lastError != null) {
-            throw new UnsatisfiedLinkError(lastError);
-        }
-        throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
     }
 
     private volatile String[] mLibPaths = null;
@@ -1068,7 +1111,12 @@
         return paths;
     }
 
-    private static native String nativeLoad(String filename, ClassLoader loader);
+    private static String nativeLoad(String filename, ClassLoader loader) {
+        return nativeLoad(filename, loader, null);
+    }
+
+    private static native String nativeLoad(String filename, ClassLoader loader, Class<?> caller);
+    // 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..58207eb 100644
--- a/ojluni/src/main/java/java/lang/String.java
+++ b/ojluni/src/main/java/java/lang/String.java
@@ -144,7 +144,7 @@
      * Class String is special cased within the Serialization Stream Protocol.
      *
      * A String instance is written into an ObjectOutputStream according to
-     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/output.html">
+     * <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/output.html">
      * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
      */
     private static final ObjectStreamField[] serialPersistentFields =
@@ -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..8235bf7 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;
@@ -41,9 +40,10 @@
 import java.util.PropertyPermission;
 import libcore.icu.ICU;
 import libcore.io.Libcore;
-import libcore.util.TimeZoneDataFiles;
+import libcore.timezone.TimeZoneDataFiles;
 
 import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 import sun.security.util.SecurityConstants;
 /**
  * The <code>System</code> class contains several useful class fields
@@ -994,11 +994,9 @@
 
         StructUtsname info = Libcore.os.uname();
         p.put("os.arch", info.machine);
-        if (p.get("os.name") != null && !p.get("os.name").equals(info.sysname)) {
-            logE("Wrong compile-time assumption for os.name: " + p.get("os.name") + " vs " +
-                    info.sysname);
-            p.put("os.name", info.sysname);
-        }
+        // os.name was previously hardcoded to "Linux", but was reverted due to support
+        // for Fuchsia. b/121268567 shows initialization regressions.
+        p.put("os.name", info.sysname);
         p.put("os.version", info.release);
 
         // Android-added: Undocumented properties that exist only on Android.
@@ -1630,7 +1628,7 @@
      */
     @CallerSensitive
     public static void load(String filename) {
-        Runtime.getRuntime().load0(VMStack.getStackClass1(), filename);
+        Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
     }
 
     /**
@@ -1666,7 +1664,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..54fd49a 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.
 
     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;
@@ -202,10 +213,20 @@
      */
     private long stackSize;
 
+    // BEGIN Android-changed: Keep track of whether this thread was unparked while not alive.
+    /*
     /*
      * JVM-private state that persists after native thread termination.
-     */
+     *
     private long nativeParkEventPointer;
+    */
+    /**
+     * Indicates whether this thread was unpark()ed while not alive, in which case start()ing
+     * it should leave it in unparked state. This field is read and written by native code in
+     * the runtime, guarded by thread_list_lock. See http://b/28845097#comment49
+     */
+    private boolean unparkedBeforeStart;
+    // END Android-changed: Keep track of whether this thread was unparked while not alive.
 
     /*
      * Thread ID
@@ -215,11 +236,31 @@
     /* For generating thread ID */
     private static long threadSeqNumber;
 
+
+    // Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /** True if this thread is managed by {@link Daemons}. */
+    private boolean systemDaemon = false;
+
     /* Java thread status for tools,
      * 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 +282,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 +351,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 +385,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 +405,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) {
@@ -362,12 +427,14 @@
             return;
         }
 
+        final int nanosPerMilli = 1000000;
         long start = System.nanoTime();
-        long duration = (millis * NANOS_PER_MILLI) + nanos;
+        long duration = (millis * nanosPerMilli) + nanos;
 
         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);
@@ -381,10 +448,20 @@
 
                 duration -= elapsed;
                 start = now;
-                millis = duration / NANOS_PER_MILLI;
-                nanos = (int) (duration % NANOS_PER_MILLI);
+                millis = duration / nanosPerMilli;
+                nanos = (int) (duration % nanosPerMilli);
             }
         }
+        // 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 +472,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 +592,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 +662,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 +683,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 +862,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 +872,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 +894,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 +939,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
@@ -847,12 +961,29 @@
      *       for example), the <code>interrupt</code> method should be used to
      *       interrupt the wait.
      *       For more information, see
-     *       <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *       <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
     @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();
     }
 
     /**
@@ -866,11 +997,11 @@
      *        could be used to generate exceptions that the target thread was
      *        not prepared to handle.
      *        For more information, see
-     *        <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *        <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *        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 +1051,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 +1076,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 +1105,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}.
      *
@@ -977,12 +1136,10 @@
      *     If another thread ever attempted to lock this resource, deadlock
      *     would result. Such deadlocks typically manifest themselves as
      *     "frozen" processes. For more information, see
-     *     <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">
+     *     <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html">
      *     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 +1152,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
@@ -1020,36 +1169,35 @@
      *   monitor prior to calling <code>resume</code>, deadlock results.  Such
      *   deadlocks typically manifest themselves as "frozen" processes.
      *   For more information, see
-     *   <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *   <a href="https://docs.oracle.com/javase/8/docs/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
+     *     <a href="https://docs.oracle.com/javase/8/docs/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 +1229,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 +1271,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 +1304,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 +1378,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 +1405,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 +1433,7 @@
         }
         }
     }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
 
     /**
      * Waits at most {@code millis} milliseconds plus
@@ -1299,8 +1460,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 +1482,7 @@
         join(millis);
         }
     }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
 
     /**
      * Waits for this thread to die.
@@ -1397,6 +1562,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 +1614,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 +1650,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 +1674,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 +1716,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 +1757,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 +1870,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 +1996,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 +2081,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 +2106,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 +2118,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 +2129,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 +2171,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,9 +2183,47 @@
                 // Throwables thrown by the initial handler are ignored
             }
         }
+        // END Android-added: uncaughtExceptionPreHandler for use by platform.
         getUncaughtExceptionHandler().uncaughtException(this, e);
     }
 
+    // BEGIN Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /**
+     * Marks this thread as either a special runtime-managed ("system daemon")
+     * thread or a normal (i.e. app code created) daemon thread.)
+     *
+     * <p>System daemon threads get special handling when starting up in some
+     * cases.
+     *
+     * <p>This method must be invoked before the thread is started.
+     *
+     * <p>This method must only be invoked on Thread instances that have already
+     * had {@code setDaemon(true)} called on them.
+     *
+     * <p>Package-private since only {@link java.lang.Daemons} needs to call
+     * this.
+     *
+     * @param  on if {@code true}, marks this thread as a system daemon thread
+     *
+     * @throws  IllegalThreadStateException
+     *          if this thread is {@linkplain #isAlive alive} or not a
+     *          {@linkplain #isDaemon daemon}
+     *
+     * @throws  SecurityException
+     *          if {@link #checkAccess} determines that the current
+     *          thread cannot modify this thread
+     *
+     * @hide For use by Daemons.java only.
+     */
+    final void setSystemDaemon(boolean on) {
+        checkAccess();
+        if (isAlive() || !isDaemon()) {
+            throw new IllegalThreadStateException();
+        }
+        systemDaemon = on;
+    }
+    // END Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+
     /**
      * Removes from the specified map any keys that have been enqueued
      * on the specified reference queue.
@@ -2024,6 +2293,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,178 +2305,23 @@
     /** 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);
 
-    /** Park states */
-    private static class ParkState {
-        /** park state indicating unparked */
-        private static final int UNPARKED = 1;
-
-        /** park state indicating preemptively unparked */
-        private static final int PREEMPTIVELY_UNPARKED = 2;
-
-        /** park state indicating parked */
-        private static final int PARKED = 3;
-    }
-
-    private static final int NANOS_PER_MILLI = 1000000;
-
-    /** the park state of the thread */
-    private int parkState = ParkState.UNPARKED;
-
-    /**
-     * Unparks this thread. This unblocks the thread it if it was
-     * previously parked, or indicates that the thread is "preemptively
-     * unparked" if it wasn't already parked. The latter means that the
-     * next time the thread is told to park, it will merely clear its
-     * latent park bit and carry on without blocking.
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * @hide for Unsafe
-     */
-    public final void unpark$() {
-        synchronized(lock) {
-        switch (parkState) {
-            case ParkState.PREEMPTIVELY_UNPARKED: {
-                /*
-                 * Nothing to do in this case: By definition, a
-                 * preemptively unparked thread is to remain in
-                 * the preemptively unparked state if it is told
-                 * to unpark.
-                 */
-                break;
-            }
-            case ParkState.UNPARKED: {
-                parkState = ParkState.PREEMPTIVELY_UNPARKED;
-                break;
-            }
-            default /*parked*/: {
-                parkState = ParkState.UNPARKED;
-                lock.notifyAll();
-                break;
-            }
-        }
-        }
-    }
-
-    /**
-     * Parks the current thread for a particular number of nanoseconds, or
-     * indefinitely. If not indefinitely, this method unparks the thread
-     * after the given number of nanoseconds if no other thread unparks it
-     * first. If the thread has been "preemptively unparked," this method
-     * cancels that unparking and returns immediately. This method may
-     * also return spuriously (that is, without the thread being told to
-     * unpark and without the indicated amount of time elapsing).
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * <p>This method must only be called when <code>this</code> is the current
-     * thread.
-     *
-     * @param nanos number of nanoseconds to park for or <code>0</code>
-     * to park indefinitely
-     * @throws IllegalArgumentException thrown if <code>nanos &lt; 0</code>
-     *
-     * @hide for Unsafe
-     */
-    public final void parkFor$(long nanos) {
-        synchronized(lock) {
-        switch (parkState) {
-            case ParkState.PREEMPTIVELY_UNPARKED: {
-                parkState = ParkState.UNPARKED;
-                break;
-            }
-            case ParkState.UNPARKED: {
-                long millis = nanos / NANOS_PER_MILLI;
-                nanos %= NANOS_PER_MILLI;
-
-                parkState = ParkState.PARKED;
-                try {
-                    lock.wait(millis, (int) nanos);
-                } catch (InterruptedException ex) {
-                    interrupt();
-                } finally {
-                    /*
-                     * Note: If parkState manages to become
-                     * PREEMPTIVELY_UNPARKED before hitting this
-                     * code, it should left in that state.
-                     */
-                    if (parkState == ParkState.PARKED) {
-                        parkState = ParkState.UNPARKED;
-                    }
-                }
-                break;
-            }
-            default /*parked*/: {
-                throw new AssertionError("Attempt to repark");
-            }
-        }
-        }
-    }
-
-    /**
-     * Parks the current thread until the specified system time. This
-     * method attempts to unpark the current thread immediately after
-     * <code>System.currentTimeMillis()</code> reaches the specified
-     * value, if no other thread unparks it first. If the thread has
-     * been "preemptively unparked," this method cancels that
-     * unparking and returns immediately. This method may also return
-     * spuriously (that is, without the thread being told to unpark
-     * and without the indicated amount of time elapsing).
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * <p>This method must only be called when <code>this</code> is the
-     * current thread.
-     *
-     * @param time the time after which the thread should be unparked,
-     * in absolute milliseconds-since-the-epoch
-     *
-     * @hide for Unsafe
-     */
-    public final void parkUntil$(long time) {
-        synchronized(lock) {
-        /*
-         * Note: This conflates the two time bases of "wall clock"
-         * time and "monotonic uptime" time. However, given that
-         * the underlying system can only wait on monotonic time,
-         * it is unclear if there is any way to avoid the
-         * conflation. The downside here is that if, having
-         * calculated the delay, the wall clock gets moved ahead,
-         * this method may not return until well after the wall
-         * clock has reached the originally designated time. The
-         * reverse problem (the wall clock being turned back)
-         * isn't a big deal, since this method is allowed to
-         * spuriously return for any reason, and this situation
-         * can safely be construed as just such a spurious return.
-         */
-        final long currentTime = System.currentTimeMillis();
-        if (time <= currentTime) {
-            parkState = ParkState.UNPARKED;
-        } else {
-            long delayMillis = time - currentTime;
-            // Long.MAX_VALUE / NANOS_PER_MILLI (0x8637BD05SF6) is the largest
-            // long value that won't overflow to negative value when
-            // multiplyed by NANOS_PER_MILLI (10^6).
-            long maxValue = (Long.MAX_VALUE / NANOS_PER_MILLI);
-            if (delayMillis > maxValue) {
-                delayMillis = maxValue;
-            }
-            parkFor$(delayMillis * NANOS_PER_MILLI);
-        }
-        }
-    }
+    // Android-added: Android specific nativeGetStatus() method.
+    private native int nativeGetStatus(boolean hasBeenStarted);
 }
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/Throwable.java b/ojluni/src/main/java/java/lang/Throwable.java
index 09de274..5a3f8a8 100644
--- a/ojluni/src/main/java/java/lang/Throwable.java
+++ b/ojluni/src/main/java/java/lang/Throwable.java
@@ -120,7 +120,7 @@
     /**
      * Native code saves some indication of the stack backtrace in this slot.
      */
-    private transient volatile Object backtrace;
+    private transient Object backtrace;
 
     /**
      * Specific details about the Throwable.  For example, for
@@ -155,6 +155,13 @@
             new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
     }
 
+    // Android-removed: Use libcore.util.EmptyArray for the empty stack trace
+    // Adding the constant UNASSIGNED_STACK breaks serialization of some subclasses
+    // /**
+    //  * A shared value for an empty stack.
+    //  */
+    // private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
+
     /*
      * To allow Throwable objects to be made immutable and safely
      * reused by the JVM, such as OutOfMemoryErrors, fields of
@@ -204,9 +211,19 @@
      * @serial
      * @since 1.4
      */
-    // Android-changed.
+    // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+    // private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
     private StackTraceElement[] stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
 
+    // Android-removed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // Adding this constant breaks serialization of some subclasses
+    /*
+    // Setting this static field introduces an acceptable
+    // initialization dependency on a few java.util classes.
+    private static final List<Throwable> SUPPRESSED_SENTINEL =
+        Collections.unmodifiableList(new ArrayList<Throwable>(0));
+    */
+
     /**
      * The list of suppressed exceptions, as returned by {@link
      * #getSuppressed()}.  The list is initialized to a zero-element
@@ -217,6 +234,8 @@
      * @serial
      * @since 1.7
      */
+    // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
     private List<Throwable> suppressedExceptions = Collections.emptyList();
 
     /** Message for trying to suppress a null exception. */
@@ -670,6 +689,9 @@
                                          String caption,
                                          String prefix,
                                          Set<Throwable> dejaVu) {
+        // Android-removed: Use of assert keyword which breaks serialization of some subclasses
+        // (Using assert adds a static field that determines whether assertions are enabled.)
+        // assert Thread.holdsLock(s.lock());
         if (dejaVu.contains(this)) {
             s.println("\t[CIRCULAR REFERENCE:" + this + "]");
         } else {
@@ -772,12 +794,18 @@
     public synchronized Throwable fillInStackTrace() {
         if (stackTrace != null ||
             backtrace != null /* Out of protocol state */ ) {
+            // Android-changed: Use Android-specific nativeFillInStackTrace
+            // fillInStackTrace(0);
             backtrace = nativeFillInStackTrace();
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // stackTrace = UNASSIGNED_STACK;
             stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
         }
         return this;
     }
 
+    // Android-changed: Use Android-specific nativeFillInStackTrace
+    // private native Throwable fillInStackTrace(int dummy);
     @FastNative
     private static native Object nativeFillInStackTrace();
 
@@ -812,21 +840,26 @@
     private synchronized StackTraceElement[] getOurStackTrace() {
         // Initialize stack trace field with information from
         // backtrace if this is the first call to this method
-        //
-        // Android-changed: test explicitly for equality with
-        // STACK_TRACE_ELEMENT
+        // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+        // if (stackTrace == UNASSIGNED_STACK ||
         if (stackTrace == libcore.util.EmptyArray.STACK_TRACE_ELEMENT ||
             (stackTrace == null && backtrace != null) /* Out of protocol state */) {
+            // BEGIN Android-changed: Use Android-specific nativeGetStackTrace
+            // int depth = getStackTraceDepth();
+            // stackTrace = new StackTraceElement[depth];
+            // for (int i=0; i < depth; i++)
+            //     stackTrace[i] = getStackTraceElement(i);
             stackTrace = nativeGetStackTrace(backtrace);
             backtrace = null;
-        }
-
-        // Android-changed: Return an empty element both when the stack trace
-        // isn't writeable and also when nativeGetStackTrace returns null.
-        if (stackTrace == null) {
+            if (stackTrace == null) {
+                return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+            }
+            // END Android-changed: Use Android-specific nativeGetStackTrace
+        } else if (stackTrace == null) {
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // return UNASSIGNED_STACK;
             return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
         }
-
         return stackTrace;
     }
 
@@ -874,6 +907,15 @@
         }
     }
 
+    // Android-removed: Unused native method getStackTraceDepth()
+    // /**
+    //  * Returns the number of elements in the stack trace (or 0 if the stack
+    //  * trace is unavailable).
+    //  *
+    //  * package-protection for use by SharedSecrets.
+    //  */
+    // native int getStackTraceDepth();
+
     /**
      * Returns the specified element of the stack trace.
      *
@@ -883,6 +925,8 @@
      * @throws IndexOutOfBoundsException if {@code index < 0 ||
      *         index >= getStackTraceDepth() }
      */
+    // Android-changed: Use Android-specific nativeGetStackTrace
+    // native StackTraceElement getStackTraceElement(int index);
     @FastNative
     private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
 
@@ -909,6 +953,8 @@
             List<Throwable> suppressed = null;
             if (suppressedExceptions.isEmpty()) {
                 // Use the sentinel for a zero-length list
+                // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+                // suppressed = SUPPRESSED_SENTINEL;
                 suppressed = Collections.emptyList();
             } else { // Copy Throwables to new list
                 suppressed = new ArrayList<>(1);
@@ -936,6 +982,8 @@
          */
         if (stackTrace != null) {
             if (stackTrace.length == 0) {
+                // Android-removed: clone() call not needed because of libcore.util.EmptyArray usage
+                // stackTrace = UNASSIGNED_STACK.clone();
             }  else if (stackTrace.length == 1 &&
                         // Check for the marker of an immutable stack trace
                         SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
@@ -951,6 +999,8 @@
             // from an exception serialized without that field in
             // older JDK releases; treat such exceptions as having
             // empty stack traces.
+            // Android-changed: Directly create empty array instead of cloning UNASSIGNED_STACK
+            // stackTrace = UNASSIGNED_STACK.clone();
             stackTrace = new StackTraceElement[0];
         }
     }
@@ -1040,12 +1090,16 @@
         if (suppressedExceptions == null) // Suppressed exceptions not recorded
             return;
 
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL)
         if (suppressedExceptions.isEmpty())
             suppressedExceptions = new ArrayList<>(1);
 
         suppressedExceptions.add(exception);
     }
 
+    // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY
+    // private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
     private static Throwable[] EMPTY_THROWABLE_ARRAY;
 
     /**
@@ -1064,10 +1118,14 @@
      * @since 1.7
      */
     public final synchronized Throwable[] getSuppressed() {
+        // Android-added: Lazily initialize EMPTY_THROWABLE_ARRAY
         if (EMPTY_THROWABLE_ARRAY == null) {
             EMPTY_THROWABLE_ARRAY = new Throwable[0];
         }
 
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL ||
+        //    suppressedExceptions == null)
         if (suppressedExceptions == null || suppressedExceptions.isEmpty())
             return EMPTY_THROWABLE_ARRAY;
         else
diff --git a/ojluni/src/main/java/java/lang/UnsupportedOperationException.java b/ojluni/src/main/java/java/lang/UnsupportedOperationException.java
index 15b7c6d..1de2508 100644
--- a/ojluni/src/main/java/java/lang/UnsupportedOperationException.java
+++ b/ojluni/src/main/java/java/lang/UnsupportedOperationException.java
@@ -29,7 +29,7 @@
  * Thrown to indicate that the requested operation is not supported.<p>
  *
  * This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
index cd09322..87911c2 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..356768d 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,40 @@
         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. They are now
+    // deprecated as a prelude to being removed from the public API.
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+     *             replacement is available but it is possible to replicate using information from
+     *             the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+     *             {@code refKind >= 1 && refKind <= 9}. There are no guarantees that this logic
+     *             will work if future versions extend the table.
+     */
+    @Deprecated
     static boolean refKindIsValid(int refKind) {
-        return (refKind >= REF_getField && refKind <= REF_invokeInterface);
+        return MethodHandleNatives.refKindIsValid(refKind);
     }
 
-    // Android-changed: Inlined from MethodHandleNatives.
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+     *             replacement is available but it is possible to replicate using information from
+     *             the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+     *             {@code refKind >= 1 && refKind <= 4}.  There are no guarantees that this logic
+     *             will work if future versions extend the table.
+     */
+    @Deprecated
     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'.
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. Use
+     *             {@link MethodHandleInfo#referenceKindToString(int)} instead.
+     */
+    @Deprecated
     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..305579f 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/VarHandle.java b/ojluni/src/main/java/java/lang/invoke/VarHandle.java
index aef10c8..7b5ac00 100644
--- a/ojluni/src/main/java/java/lang/invoke/VarHandle.java
+++ b/ojluni/src/main/java/java/lang/invoke/VarHandle.java
@@ -2250,7 +2250,7 @@
             this.accessModesBitMask = unalignedAccessModesBitMask(varType);
         }
     }
-    // END Android-changed: package private constructors.
+    // END Android-added: package private constructors.
 
     // BEGIN Android-added: helper state for VarHandle properties.
 
@@ -2382,5 +2382,5 @@
         }
         return bitMask;
     }
-    // END Android-added: helper class for VarHandle properties.
+    // END Android-added: helper state for VarHandle properties.
 }
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..cf8c8b5 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: 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/Proxy.java b/ojluni/src/main/java/java/lang/reflect/Proxy.java
index 531ca18..584d568 100644
--- a/ojluni/src/main/java/java/lang/reflect/Proxy.java
+++ b/ojluni/src/main/java/java/lang/reflect/Proxy.java
@@ -886,7 +886,7 @@
             final Constructor<?> cons = cl.getConstructor(constructorParams);
             final InvocationHandler ih = h;
             if (!Modifier.isPublic(cl.getModifiers())) {
-                // BEGIN Android-changed: Excluded AccessController.doPrivileged call.
+                // BEGIN Android-removed: Excluded AccessController.doPrivileged call.
                 /*
                 AccessController.doPrivileged(new PrivilegedAction<Void>() {
                     public Void run() {
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/CookieManager.java b/ojluni/src/main/java/java/net/CookieManager.java
index 1f49a62..dfd3b86 100644
--- a/ojluni/src/main/java/java/net/CookieManager.java
+++ b/ojluni/src/main/java/java/net/CookieManager.java
@@ -210,14 +210,14 @@
 
         boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
         List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
-        // BEGIN Android-removed: The logic of converting null path is moved into pathMatches
+        // BEGIN Android-removed: The logic of converting null path is moved into pathMatches.
         /*
         String path = uri.getPath();
         if (path == null || path.isEmpty()) {
             path = "/";
         }
         */
-        // BEGIN Android-removed: The logic of converting null path is moved into pathMatches
+        // END Android-removed: The logic of converting null path is moved into pathMatches.
         for (HttpCookie cookie : cookieJar.get(uri)) {
             // apply path-matches rule (RFC 2965 sec. 3.3.4)
             // and check for the possible "secure" tag (i.e. don't send
diff --git a/ojluni/src/main/java/java/net/DatagramPacket.java b/ojluni/src/main/java/java/net/DatagramPacket.java
index f6e81e0..c1bd692 100644
--- a/ojluni/src/main/java/java/net/DatagramPacket.java
+++ b/ojluni/src/main/java/java/net/DatagramPacket.java
@@ -43,7 +43,7 @@
 public final
 class DatagramPacket {
 
-    // BEGIN Android-removed: Android doesn't need to load native net library
+    // BEGIN Android-removed: Android doesn't need to load native net library.
     /**
      * Perform class initialization
      *
@@ -58,7 +58,7 @@
         init();
     }
     */
-    // END Android-removed: init method has been removed
+    // END Android-removed: Android doesn't need to load native net library.
 
     /*
      * The fields of this class are package-private since DatagramSocketImpl
diff --git a/ojluni/src/main/java/java/net/HttpCookie.java b/ojluni/src/main/java/java/net/HttpCookie.java
index ecf438d..3ff33c7 100644
--- a/ojluni/src/main/java/java/net/HttpCookie.java
+++ b/ojluni/src/main/java/java/net/HttpCookie.java
@@ -995,7 +995,7 @@
                                    String attrName,
                                    String attrValue) {
                     if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
-                        // BEGIN Android-changed: Use HttpDate for date parsing,
+                        // BEGIN Android-changed: Use HttpDate for date parsing.
                         // it accepts broader set of date formats.
                         // cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue));
                         // Android-changed: Altered max age calculation to avoid setting
@@ -1010,7 +1010,7 @@
                             }
                         }
                         cookie.setMaxAge(maxAgeInSeconds);
-                        // END Android-changed: Use HttpDate for date parsing
+                        // END Android-changed: Use HttpDate for date parsing.
                     }
                 }
             });
diff --git a/ojluni/src/main/java/java/net/IDN.java b/ojluni/src/main/java/java/net/IDN.java
index 4639c8f..a18c3a8 100644
--- a/ojluni/src/main/java/java/net/IDN.java
+++ b/ojluni/src/main/java/java/net/IDN.java
@@ -107,6 +107,11 @@
         try {
             return IDNA.convertIDNToASCII(input, flag).toString();
         } catch (android.icu.text.StringPrepParseException e) {
+            // b/113787610: "." is a valid IDN but is rejected by ICU.
+            // Usage is relatively uncommon, so only check for it if ICU throws.
+            if (".".equals(input)) {
+                return input;
+            }
             throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
         }
         // END Android-changed: Use ICU4J implementation
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/Inet6AddressImpl.java b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 1edfe34..bb722f3 100644
--- a/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -36,6 +36,7 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import libcore.net.InetAddressUtils;
 
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
@@ -43,6 +44,7 @@
 import static android.system.OsConstants.AI_ADDRCONFIG;
 import static android.system.OsConstants.EACCES;
 import static android.system.OsConstants.ECONNREFUSED;
+import static android.system.OsConstants.EPERM;
 import static android.system.OsConstants.NI_NAMEREQD;
 import static android.system.OsConstants.ICMP6_ECHO_REPLY;
 import static android.system.OsConstants.ICMP_ECHOREPLY;
@@ -93,12 +95,8 @@
         }
 
         // Is it a numeric address?
-        InetAddress result = InetAddress.parseNumericAddressNoThrow(host);
+        InetAddress result = InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(host);
         if (result != null) {
-            result = InetAddress.disallowDeprecatedFormats(host, result);
-            if (result == null) {
-                throw new UnknownHostException("Deprecated IPv4 address format: " + host);
-            }
             return new InetAddress[] { result };
         }
 
@@ -147,7 +145,8 @@
             // SecurityException to aid in debugging this common mistake.
             // http://code.google.com/p/android/issues/detail?id=15722
             if (gaiException.getCause() instanceof ErrnoException) {
-                if (((ErrnoException) gaiException.getCause()).errno == EACCES) {
+                int errno = ((ErrnoException) gaiException.getCause()).errno;
+                if (errno == EACCES || errno == EPERM) {
                     throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException);
                 }
             }
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index 94d32d3..e4f8660 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -33,12 +33,10 @@
 import java.io.ObjectInputStream.GetField;
 import java.io.ObjectOutputStream;
 import java.io.ObjectOutputStream.PutField;
+import libcore.net.InetAddressUtils;
 import sun.net.util.IPAddressUtil;
 import sun.net.spi.nameservice.*;
-import android.system.GaiException;
-import android.system.StructAddrinfo;
 import libcore.io.Libcore;
-import static android.system.OsConstants.*;
 
 /**
  * This class represents an Internet Protocol (IP) address.
@@ -1606,59 +1604,41 @@
     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}
-     * class documentation.
+     *
+     * <p>This copes with all forms of address that Java supports, detailed in the
+     * {@link InetAddress} class documentation. An empty string is not treated as numeric.
      *
      * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
+     * @deprecated Use {@link InetAddressUtils#isNumericAddress(String)} instead, if possible.
+     * @throws NullPointerException if the {@code address} is {@code null}.
      */
+    @Deprecated
     public static boolean isNumeric(String address) {
-        InetAddress inetAddress = parseNumericAddressNoThrow(address);
-        return inetAddress != null && disallowDeprecatedFormats(address, inetAddress) != null;
-    }
-
-    static InetAddress parseNumericAddressNoThrow(String address) {
-        // Accept IPv6 addresses (only) in square brackets for compatibility.
-        if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
-            address = address.substring(1, address.length() - 1);
-        }
-        StructAddrinfo hints = new StructAddrinfo();
-        hints.ai_flags = AI_NUMERICHOST;
-        InetAddress[] addresses = null;
-        try {
-            addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET);
-        } catch (GaiException ignored) {
-        }
-        return (addresses != null) ? addresses[0] : null;
-    }
-
-    static InetAddress disallowDeprecatedFormats(String address, InetAddress inetAddress) {
-        // Only IPv4 addresses are problematic.
-        if (!(inetAddress instanceof Inet4Address) || address.indexOf(':') != -1) {
-            return inetAddress;
-        }
-        // If inet_pton(3) can't parse it, it must have been a deprecated format.
-        // We need to return inet_pton(3)'s result to ensure that numbers assumed to be octal
-        // by getaddrinfo(3) are reinterpreted by inet_pton(3) as decimal.
-        return Libcore.os.inet_pton(AF_INET, address);
+        return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(address) != null;
     }
 
     /**
      * Returns an InetAddress corresponding to the given numeric address (such
      * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
-     * This method will never do a DNS lookup. Non-numeric addresses are errors.
+     *
+     * <p>This method will never do a DNS lookup. Non-numeric addresses are errors. Passing either
+     * an empty string or a {@code null} as the {@code numericAddress} will return the
+     * {@link Inet6Address#LOOPBACK} address.
      *
      * @hide used by frameworks/base's NetworkUtils.numericToInetAddress
      * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
+     * @deprecated Use {@link InetAddressUtils#parseNumericAddress(String)} instead, if possible.
      */
+    @Deprecated
     public static InetAddress parseNumericAddress(String numericAddress) {
         if (numericAddress == null || numericAddress.isEmpty()) {
             return Inet6Address.LOOPBACK;
         }
-        InetAddress result = parseNumericAddressNoThrow(numericAddress);
-        result = disallowDeprecatedFormats(numericAddress, result);
+        InetAddress result = InetAddressUtils
+                .parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
         if (result == null) {
             throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
         }
@@ -1673,7 +1653,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 +1683,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/MulticastSocket.java b/ojluni/src/main/java/java/net/MulticastSocket.java
index d14500a..83a18c3 100644
--- a/ojluni/src/main/java/java/net/MulticastSocket.java
+++ b/ojluni/src/main/java/java/net/MulticastSocket.java
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.util.Enumeration;
 
+// Android-changed: Updated example code to handle non-ASCII characters
 /**
  * The multicast datagram socket class is useful for sending
  * and receiving IP multicast packets.  A MulticastSocket is
@@ -50,7 +51,8 @@
  * InetAddress group = InetAddress.getByName("228.5.6.7");
  * MulticastSocket s = new MulticastSocket(6789);
  * s.joinGroup(group);
- * DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
+ * byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
+ * DatagramPacket hi = new DatagramPacket(bytes, bytes.length,
  *                             group, 6789);
  * s.send(hi);
  * // get their responses!
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 01862f6..dffc6d5 100644
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -543,6 +543,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
@@ -559,7 +561,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..56cb80b 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,116 @@
 
     // -- 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;
+    }
+    */
+    // END Android-removed: Direct memory management unused on Android.
+
     // -- 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 +774,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 +809,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 +836,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 +876,6 @@
                                          long length);
     static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
                                        long length);
-
+    */
+    // END Android-removed: Bulk get/put methods are unused on Android.
 }
diff --git a/ojluni/src/main/java/java/nio/Buffer.java b/ojluni/src/main/java/java/nio/Buffer.java
index c912aaa..e517560 100644
--- a/ojluni/src/main/java/java/nio/Buffer.java
+++ b/ojluni/src/main/java/java/nio/Buffer.java
@@ -253,7 +253,7 @@
      * @throws  IllegalArgumentException
      *          If the preconditions on <tt>newPosition</tt> do not hold
      */
-    public final Buffer position(int newPosition) {
+    public Buffer position(int newPosition) {
         if ((newPosition > limit) || (newPosition < 0))
             // Android-changed: Improved error message.
             throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
@@ -285,7 +285,7 @@
      * @throws  IllegalArgumentException
      *          If the preconditions on <tt>newLimit</tt> do not hold
      */
-    public final Buffer limit(int newLimit) {
+    public Buffer limit(int newLimit) {
         if ((newLimit > capacity) || (newLimit < 0))
             throw new IllegalArgumentException();
         limit = newLimit;
@@ -299,7 +299,7 @@
      *
      * @return  This buffer
      */
-    public final Buffer mark() {
+    public Buffer mark() {
         mark = position;
         return this;
     }
@@ -315,7 +315,7 @@
      * @throws  InvalidMarkException
      *          If the mark has not been set
      */
-    public final Buffer reset() {
+    public Buffer reset() {
         int m = mark;
         if (m < 0)
             throw new InvalidMarkException();
@@ -340,7 +340,7 @@
      *
      * @return  This buffer
      */
-    public final Buffer clear() {
+    public Buffer clear() {
         position = 0;
         limit = capacity;
         mark = -1;
@@ -368,7 +368,7 @@
      *
      * @return  This buffer
      */
-    public final Buffer flip() {
+    public Buffer flip() {
         limit = position;
         position = 0;
         mark = -1;
@@ -390,7 +390,7 @@
      *
      * @return  This buffer
      */
-    public final Buffer rewind() {
+    public Buffer rewind() {
         position = 0;
         mark = -1;
         return this;
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index e4a8d0f..b286cbd 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -30,6 +30,8 @@
 
 import libcore.io.Memory;
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * A byte buffer.
  *
@@ -221,7 +223,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 +253,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 +602,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
@@ -805,6 +805,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
@@ -1086,13 +1130,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 +1160,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 +1239,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 +1269,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 +1348,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 +1378,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 +1457,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 +1487,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 +1566,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 +1596,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 +1675,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 +1705,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 +1728,7 @@
      */
     public abstract DoubleBuffer asDoubleBuffer();
 
+    // BEGIN Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
     /**
      * @hide
      */
@@ -1733,4 +1742,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..6d73448 100644
--- a/ojluni/src/main/java/java/nio/CharBuffer.java
+++ b/ojluni/src/main/java/java/nio/CharBuffer.java
@@ -34,6 +34,8 @@
 import java.util.stream.StreamSupport;
 import java.util.stream.IntStream;
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 
 /**
  * A char buffer.
@@ -135,7 +137,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 +535,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 +595,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 +749,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;
@@ -858,6 +863,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
@@ -1219,8 +1268,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..3e06011 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -30,12 +30,11 @@
 
 import dalvik.system.VMRuntime;
 import libcore.io.Memory;
-import libcore.io.SizeOf;
 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 +249,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");
@@ -341,7 +348,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        int newPosition = position + SizeOf.CHAR;
+        int newPosition = position + Character.BYTES;
         if (newPosition > limit()) {
             throw new BufferUnderflowException();
         }
@@ -355,7 +362,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        checkIndex(i, SizeOf.CHAR);
+        checkIndex(i, Character.BYTES);
         return (char) Memory.peekShort(ix(i), !nativeByteOrder);
     }
 
@@ -389,7 +396,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putChar(ix(nextPutIndex(SizeOf.CHAR)), x);
+        putChar(ix(nextPutIndex(Character.BYTES)), x);
         return this;
     }
 
@@ -401,7 +408,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putChar(ix(checkIndex(i, SizeOf.CHAR)), x);
+        putChar(ix(checkIndex(i, Character.BYTES)), x);
         return this;
     }
 
@@ -450,7 +457,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getShort(ix(nextGetIndex(SizeOf.SHORT)));
+        return getShort(ix(nextGetIndex(Short.BYTES)));
     }
 
     @Override
@@ -458,7 +465,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getShort(ix(checkIndex(i, SizeOf.SHORT)));
+        return getShort(ix(checkIndex(i, Short.BYTES)));
     }
 
     @Override
@@ -491,7 +498,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putShort(ix(nextPutIndex(SizeOf.SHORT)), x);
+        putShort(ix(nextPutIndex(Short.BYTES)), x);
         return this;
     }
 
@@ -503,7 +510,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putShort(ix(checkIndex(i, SizeOf.SHORT)), x);
+        putShort(ix(checkIndex(i, Short.BYTES)), x);
         return this;
     }
 
@@ -552,7 +559,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getInt(ix(nextGetIndex(SizeOf.INT)));
+        return getInt(ix(nextGetIndex(Integer.BYTES)));
     }
 
     @Override
@@ -560,7 +567,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getInt(ix(checkIndex(i, (SizeOf.INT))));
+        return getInt(ix(checkIndex(i, (Integer.BYTES))));
     }
 
     @Override
@@ -593,7 +600,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putInt(ix(nextPutIndex(SizeOf.INT)), x);
+        putInt(ix(nextPutIndex(Integer.BYTES)), x);
         return this;
     }
 
@@ -605,7 +612,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putInt(ix(checkIndex(i, SizeOf.INT)), x);
+        putInt(ix(checkIndex(i, Integer.BYTES)), x);
         return this;
     }
 
@@ -654,7 +661,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getLong(ix(nextGetIndex(SizeOf.LONG)));
+        return getLong(ix(nextGetIndex(Long.BYTES)));
     }
 
     @Override
@@ -662,7 +669,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getLong(ix(checkIndex(i, SizeOf.LONG)));
+        return getLong(ix(checkIndex(i, Long.BYTES)));
     }
 
     @Override
@@ -695,7 +702,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putLong(ix(nextPutIndex(SizeOf.LONG)), x);
+        putLong(ix(nextPutIndex(Long.BYTES)), x);
         return this;
     }
 
@@ -707,7 +714,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putLong(ix(checkIndex(i, SizeOf.LONG)), x);
+        putLong(ix(checkIndex(i, Long.BYTES)), x);
         return this;
     }
 
@@ -757,7 +764,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getFloat(ix(nextGetIndex(SizeOf.FLOAT)));
+        return getFloat(ix(nextGetIndex(Float.BYTES)));
     }
 
     @Override
@@ -765,7 +772,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getFloat(ix(checkIndex(i, SizeOf.FLOAT)));
+        return getFloat(ix(checkIndex(i, Float.BYTES)));
     }
 
     @Override
@@ -799,7 +806,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putFloat(ix(nextPutIndex(SizeOf.FLOAT)), x);
+        putFloat(ix(nextPutIndex(Float.BYTES)), x);
         return this;
     }
 
@@ -811,7 +818,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putFloat(ix(checkIndex(i, SizeOf.FLOAT)), x);
+        putFloat(ix(checkIndex(i, Float.BYTES)), x);
         return this;
     }
 
@@ -861,7 +868,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getDouble(ix(nextGetIndex(SizeOf.DOUBLE)));
+        return getDouble(ix(nextGetIndex(Double.BYTES)));
     }
 
     @Override
@@ -869,7 +876,7 @@
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
-        return getDouble(ix(checkIndex(i, SizeOf.DOUBLE)));
+        return getDouble(ix(checkIndex(i, Double.BYTES)));
     }
 
     @Override
@@ -903,7 +910,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putDouble(ix(nextPutIndex(SizeOf.DOUBLE)), x);
+        putDouble(ix(nextPutIndex(Double.BYTES)), x);
         return this;
     }
 
@@ -915,7 +922,7 @@
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
-        putDouble(ix(checkIndex(i, SizeOf.DOUBLE)), x);
+        putDouble(ix(checkIndex(i, Double.BYTES)), x);
         return this;
     }
 
diff --git a/ojluni/src/main/java/java/nio/DoubleBuffer.java b/ojluni/src/main/java/java/nio/DoubleBuffer.java
index d0a0c15..bd80f4d 100644
--- a/ojluni/src/main/java/java/nio/DoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/DoubleBuffer.java
@@ -28,6 +28,8 @@
 package java.nio;
 
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * A double buffer.
  *
@@ -108,7 +110,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 +467,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();
@@ -632,6 +637,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
@@ -784,9 +833,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..3d34211 100644
--- a/ojluni/src/main/java/java/nio/FloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/FloatBuffer.java
@@ -28,6 +28,8 @@
 package java.nio;
 
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * A float buffer.
  *
@@ -108,7 +110,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 +467,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();
@@ -632,6 +637,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
diff --git a/ojluni/src/main/java/java/nio/IntBuffer.java b/ojluni/src/main/java/java/nio/IntBuffer.java
index a0004ba..7e34229 100644
--- a/ojluni/src/main/java/java/nio/IntBuffer.java
+++ b/ojluni/src/main/java/java/nio/IntBuffer.java
@@ -29,6 +29,8 @@
 package java.nio;
 
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * An int buffer.
  *
@@ -109,7 +111,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 +468,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();
@@ -633,6 +638,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
diff --git a/ojluni/src/main/java/java/nio/LongBuffer.java b/ojluni/src/main/java/java/nio/LongBuffer.java
index 80e506c..5e5fa18 100644
--- a/ojluni/src/main/java/java/nio/LongBuffer.java
+++ b/ojluni/src/main/java/java/nio/LongBuffer.java
@@ -28,6 +28,8 @@
 package java.nio;
 
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * A long buffer.
  *
@@ -108,7 +110,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 +467,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();
@@ -632,6 +637,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
diff --git a/ojluni/src/main/java/java/nio/ShortBuffer.java b/ojluni/src/main/java/java/nio/ShortBuffer.java
index 6903b54..b2a479c 100644
--- a/ojluni/src/main/java/java/nio/ShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ShortBuffer.java
@@ -28,6 +28,8 @@
 package java.nio;
 
 
+import dalvik.annotation.codegen.CovariantReturnType;
+
 /**
  * A short buffer.
  *
@@ -108,7 +110,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 +467,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();
@@ -632,6 +637,50 @@
         return offset;
     }
 
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
     /**
      * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
      *
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/AlgorithmParameterGenerator.java b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
index 7355405..4cab0c3 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
@@ -99,7 +99,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
  * AlgorithmParameterGenerator section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -164,7 +164,7 @@
      * @param algorithm the name of the algorithm this
      * parameter generator is associated with.
      * See the AlgorithmParameterGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -206,7 +206,7 @@
      * @param algorithm the name of the algorithm this
      * parameter generator is associated with.
      * See the AlgorithmParameterGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -252,7 +252,7 @@
      * @param algorithm the string name of the algorithm this
      * parameter generator is associated with.
      * See the AlgorithmParameterGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameterGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameters.java b/ojluni/src/main/java/java/security/AlgorithmParameters.java
index bca4a5c..989159e 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameters.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameters.java
@@ -153,7 +153,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameters">
  * AlgorithmParameters section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -223,7 +223,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the AlgorithmParameters section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameters">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -265,7 +265,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the AlgorithmParameters section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameters">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -314,7 +314,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the AlgorithmParameters section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#AlgorithmParameters">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#AlgorithmParameters">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/DigestOutputStream.java b/ojluni/src/main/java/java/security/DigestOutputStream.java
index 4d076ca..619faec 100644
--- a/ojluni/src/main/java/java/security/DigestOutputStream.java
+++ b/ojluni/src/main/java/java/security/DigestOutputStream.java
@@ -150,7 +150,7 @@
         if (off < 0 || len < 0) {
             throw new IndexOutOfBoundsException("wrong index for write");
         }
-        // END Android-added
+        // END Android-added: perform checks for parameters first.
         out.write(b, off, len);
         if (on) {
             digest.update(b, off, len);
diff --git a/ojluni/src/main/java/java/security/Key.java b/ojluni/src/main/java/java/security/Key.java
index c8132f4..37f4c84 100644
--- a/ojluni/src/main/java/java/security/Key.java
+++ b/ojluni/src/main/java/java/security/Key.java
@@ -82,7 +82,7 @@
  * <p> A Key should use KeyRep as its serialized representation.
  * Note that a serialized Key may contain sensitive information
  * which should not be exposed in untrusted environments.  See the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/security.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/security.html">
  * Security Appendix</a>
  * of the Serialization Specification for more information.
  *
@@ -114,7 +114,7 @@
      * Returns the standard algorithm name for this key. For
      * example, "DSA" would indicate that this key is a DSA key.
      * See Appendix A in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/KeyFactory.java b/ojluni/src/main/java/java/security/KeyFactory.java
index d01ce16..f687d61 100644
--- a/ojluni/src/main/java/java/security/KeyFactory.java
+++ b/ojluni/src/main/java/java/security/KeyFactory.java
@@ -100,7 +100,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyFactory">
  * KeyFactory section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -178,7 +178,7 @@
      *
      * @param algorithm the name of the requested key algorithm.
      * See the KeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -209,7 +209,7 @@
      *
      * @param algorithm the name of the requested key algorithm.
      * See the KeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -250,7 +250,7 @@
      *
      * @param algorithm the name of the requested key algorithm.
      * See the KeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/KeyPairGenerator.java b/ojluni/src/main/java/java/security/KeyPairGenerator.java
index 51a0ec9..1c4c2cb 100644
--- a/ojluni/src/main/java/java/security/KeyPairGenerator.java
+++ b/ojluni/src/main/java/java/security/KeyPairGenerator.java
@@ -133,7 +133,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
  * KeyPairGenerator section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -162,7 +162,7 @@
      *
      * @param algorithm the standard string name of the algorithm.
      * See the KeyPairGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      */
@@ -173,7 +173,7 @@
     /**
      * Returns the standard name of the algorithm for this key pair generator.
      * See the KeyPairGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -220,7 +220,7 @@
      *
      * @param algorithm the standard string name of the algorithm.
      * See the KeyPairGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -276,7 +276,7 @@
      *
      * @param algorithm the standard string name of the algorithm.
      * See the KeyPairGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -317,7 +317,7 @@
      *
      * @param algorithm the standard string name of the algorithm.
      * See the KeyPairGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/KeyRep.java b/ojluni/src/main/java/java/security/KeyRep.java
index 97a6c16..cae4c63 100644
--- a/ojluni/src/main/java/java/security/KeyRep.java
+++ b/ojluni/src/main/java/java/security/KeyRep.java
@@ -42,7 +42,7 @@
  *
  * Note that a serialized Key may contain sensitive information
  * which should not be exposed in untrusted environments.  See the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/platform/serialization/spec/security.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/platform/serialization/spec/security.html">
  * Security Appendix</a>
  * of the Serialization Specification for more information.
  *
diff --git a/ojluni/src/main/java/java/security/KeyStore.java b/ojluni/src/main/java/java/security/KeyStore.java
index 8fe46b8..924f14f 100644
--- a/ojluni/src/main/java/java/security/KeyStore.java
+++ b/ojluni/src/main/java/java/security/KeyStore.java
@@ -195,7 +195,7 @@
  * </table>
  *
  * These types are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">
  * KeyStore section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -311,7 +311,7 @@
          * @param protectionAlgorithm the encryption algorithm name, for
          *     example, {@code PBEWithHmacSHA256AndAES_256}.
          *     See the Cipher section in the <a href=
-         * "{@docRoot}/openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Cipher">
+         * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
          * Java Cryptography Architecture Standard Algorithm Name
          * Documentation</a>
          *     for information about standard encryption algorithm names.
@@ -868,7 +868,7 @@
      *
      * @param type the type of keystore.
      * See the KeyStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard keystore types.
      *
@@ -906,7 +906,7 @@
      *
      * @param type the type of keystore.
      * See the KeyStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard keystore types.
      *
@@ -949,7 +949,7 @@
      *
      * @param type the type of keystore.
      * See the KeyStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard keystore types.
      *
diff --git a/ojluni/src/main/java/java/security/MessageDigest.java b/ojluni/src/main/java/java/security/MessageDigest.java
index ab2614a..996339e 100644
--- a/ojluni/src/main/java/java/security/MessageDigest.java
+++ b/ojluni/src/main/java/java/security/MessageDigest.java
@@ -120,7 +120,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
  * MessageDigest section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -155,7 +155,7 @@
      *
      * @param algorithm the standard name of the digest algorithm.
      * See the MessageDigest section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      */
@@ -178,7 +178,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the MessageDigest section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -232,7 +232,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the MessageDigest section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -283,7 +283,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the MessageDigest section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -511,7 +511,7 @@
      * implementation details. The name should be a standard
      * Java Security name (such as "SHA", "MD5", and so on).
      * See the MessageDigest section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/Provider.java b/ojluni/src/main/java/java/security/Provider.java
index cbf37db..43bb23f 100644
--- a/ojluni/src/main/java/java/security/Provider.java
+++ b/ojluni/src/main/java/java/security/Provider.java
@@ -57,7 +57,7 @@
  * in each runtime it is installed in.
  *
  * <p>See <a href =
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
  * in the "Java Cryptography Architecture API Specification &amp; Reference"
  * for information about how a particular type of provider, the
  * cryptographic service provider, works and is installed. However,
@@ -817,14 +817,15 @@
             if (!checkLegacy(key)) {
                 return null;
             }
-            // BEGIN Android-changed: was
+            // BEGIN Android-changed: use compute() instead of computeIfAbsent() to avoid cast fails
+            // The upstream code cannot ever succeed as the cast from BiFunction to Function
+            // always fails.
             // legacyStrings.computeIfAbsent((String) key,
             //         (Function<? super String, ? extends String>) remappingFunction);
-            // which cannot ever succeed as the cast from BiFunction to Function always fails
             legacyStrings.compute((String) key,
                     (BiFunction<? super String, ? super String, ? extends String>)
                             remappingFunction);
-            // END Android-changed
+            // END Android-changed: use compute() instead of computeIfAbsent() to avoid cast fails
         }
         return super.compute(key, remappingFunction);
     }
@@ -1124,7 +1125,7 @@
      * it is replaced by the new service.
      * This method also places information about this service
      * in the provider's Hashtable values in the format described in the
-     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+     * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
      * Java Cryptography Architecture API Specification &amp; Reference </a>.
      *
      * <p>Also, if there is a security manager, its
@@ -1414,7 +1415,7 @@
      * suitable services and instantiates them. The valid arguments to those
      * methods depend on the type of service. For the service types defined
      * within Java SE, see the
-     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+     * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
      * for the valid values.
      * Note that components outside of Java SE can define additional types of
@@ -1590,7 +1591,7 @@
          * instantiation in a different way.
          * For details and the values of constructorParameter that are
          * valid for the various types of services see the
-         * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+         * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
          * Java Cryptography Architecture API Specification &amp;
          * Reference</a>.
          *
@@ -1739,7 +1740,7 @@
          *
          * <p>For details and the values of parameter that are valid for the
          * various types of services see the top of this class and the
-         * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+         * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
          * Java Cryptography Architecture API Specification &amp;
          * Reference</a>.
          * Security providers can override it to implement their own test.
diff --git a/ojluni/src/main/java/java/security/SecureRandom.java b/ojluni/src/main/java/java/security/SecureRandom.java
index 1e8707a..4da178d 100644
--- a/ojluni/src/main/java/java/security/SecureRandom.java
+++ b/ojluni/src/main/java/java/security/SecureRandom.java
@@ -151,7 +151,7 @@
      * the {@link Security#getProviders() Security.getProviders()} method.
      *
      * <p> See the SecureRandom section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard RNG algorithm names.
      *
@@ -189,7 +189,7 @@
      * the {@link Security#getProviders() Security.getProviders()} method.
      *
      * <p> See the SecureRandom section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard RNG algorithm names.
      *
@@ -253,7 +253,7 @@
                 " algorithm from: " + this.provider.getName());
         }
         */
-        // END Android-removed
+        // END Android-removed: this debugging mechanism is not supported in Android.
     }
 
     /**
@@ -278,7 +278,7 @@
      *
      * @param algorithm the name of the RNG algorithm.
      * See the SecureRandom section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard RNG algorithm names.
      *
@@ -321,7 +321,7 @@
      *
      * @param algorithm the name of the RNG algorithm.
      * See the SecureRandom section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard RNG algorithm names.
      *
@@ -369,7 +369,7 @@
      *
      * @param algorithm the name of the RNG algorithm.
      * See the SecureRandom section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecureRandom">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard RNG algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/Security.java b/ojluni/src/main/java/java/security/Security.java
index 743cf36..fda137e 100644
--- a/ojluni/src/main/java/java/security/Security.java
+++ b/ojluni/src/main/java/java/security/Security.java
@@ -207,7 +207,7 @@
     /**
      * Gets a specified property for an algorithm. The algorithm name
      * should be a standard name. See the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -443,7 +443,7 @@
      * </ul>
      *
      * <p> See the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard cryptographic service names, standard
      * algorithm names and standard attribute names.
@@ -514,7 +514,7 @@
      * </ul>
      *
      * <p> See the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard cryptographic service names, standard
      * algorithm names and standard attribute names.
@@ -1016,7 +1016,7 @@
      * an empty Set if there is no provider that supports the
      * specified service or if serviceName is null. For a complete list
      * of Java cryptographic services, please see the
-     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">Java
+     * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">Java
      * Cryptography Architecture API Specification &amp; Reference</a>.
      * Note: the returned set is immutable.
      *
diff --git a/ojluni/src/main/java/java/security/Signature.java b/ojluni/src/main/java/java/security/Signature.java
index 9deaf56..a09409f 100644
--- a/ojluni/src/main/java/java/security/Signature.java
+++ b/ojluni/src/main/java/java/security/Signature.java
@@ -238,7 +238,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature">
  * Signature section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -298,7 +298,7 @@
      *
      * @param algorithm the standard string name of the algorithm.
      * See the Signature section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      */
@@ -338,7 +338,7 @@
      *
      * @param algorithm the standard name of the algorithm requested.
      * See the Signature section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -464,7 +464,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the Signature section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -516,7 +516,7 @@
      *
      * @param algorithm the name of the algorithm requested.
      * See the Signature section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Signature">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/cert/CRL.java b/ojluni/src/main/java/java/security/cert/CRL.java
index 725d7b5..67ea6ef 100644
--- a/ojluni/src/main/java/java/security/cert/CRL.java
+++ b/ojluni/src/main/java/java/security/cert/CRL.java
@@ -53,7 +53,7 @@
      *
      * @param type the standard name of the CRL type.
      * See Appendix A in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
      * for information about standard CRL types.
      */
diff --git a/ojluni/src/main/java/java/security/cert/CertPath.java b/ojluni/src/main/java/java/security/cert/CertPath.java
index f742664..fa88c39 100644
--- a/ojluni/src/main/java/java/security/cert/CertPath.java
+++ b/ojluni/src/main/java/java/security/cert/CertPath.java
@@ -91,7 +91,7 @@
  * <li>{@code PkiPath}</li>
  * </ul>
  * These encodings are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathEncodings">
  * CertPath Encodings section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  * Consult the release documentation for your implementation to see if any
diff --git a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
index fd6cdc8..2d54292 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
@@ -83,7 +83,7 @@
  * </table>
  *
  * This algorithm is described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathBuilder">
  * CertPathBuilder section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  * Consult the release documentation for your implementation to see if any
@@ -155,7 +155,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathBuilder}
      *  algorithm.  See the CertPathBuilder section in the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathBuilder">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -190,7 +190,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathBuilder}
      *  algorithm.  See the CertPathBuilder section in the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathBuilder">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -230,7 +230,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathBuilder}
      *  algorithm.  See the CertPathBuilder section in the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathBuilder">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathBuilder">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/cert/CertPathValidator.java b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
index 3a4b053..bcb3488 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathValidator.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
@@ -85,7 +85,7 @@
  * </table>
  *
  * This algorithm is described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathValidator">
  * CertPathValidator section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -154,7 +154,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathValidator}
      *  algorithm. See the CertPathValidator section in the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathValidator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -189,7 +189,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathValidator}
      *  algorithm. See the CertPathValidator section in the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathValidator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -230,7 +230,7 @@
      *
      * @param algorithm the name of the requested {@code CertPathValidator}
      * algorithm. See the CertPathValidator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathValidator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathValidator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/java/security/cert/CertStore.java b/ojluni/src/main/java/java/security/cert/CertStore.java
index 047af77..7cfd0d2 100644
--- a/ojluni/src/main/java/java/security/cert/CertStore.java
+++ b/ojluni/src/main/java/java/security/cert/CertStore.java
@@ -77,7 +77,7 @@
  * </table>
  *
  * This type is described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertStore">
  * CertStore section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -212,7 +212,7 @@
      *
      * @param type the name of the requested {@code CertStore} type.
      * See the CertStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard types.
      *
@@ -272,7 +272,7 @@
      *
      * @param type the requested {@code CertStore} type.
      * See the CertStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard types.
      *
@@ -330,7 +330,7 @@
      *
      * @param type the requested {@code CertStore} type.
      * See the CertStore section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertStore">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard types.
      *
diff --git a/ojluni/src/main/java/java/security/cert/Certificate.java b/ojluni/src/main/java/java/security/cert/Certificate.java
index 5ded604..4056416 100644
--- a/ojluni/src/main/java/java/security/cert/Certificate.java
+++ b/ojluni/src/main/java/java/security/cert/Certificate.java
@@ -74,7 +74,7 @@
      *
      * @param type the standard name of the certificate type.
      * See the CertificateFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard certificate types.
      */
diff --git a/ojluni/src/main/java/java/security/cert/CertificateFactory.java b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
index 5ccbb33..e34fddd 100644
--- a/ojluni/src/main/java/java/security/cert/CertificateFactory.java
+++ b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
@@ -127,9 +127,9 @@
  * </table>
  *
  * The type and encodings are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
  * CertificateFactory section</a> and the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathEncodings">
  * CertPath Encodings section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -188,7 +188,7 @@
      *
      * @param type the name of the requested certificate type.
      * See the CertificateFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard certificate types.
      *
@@ -226,7 +226,7 @@
      *
      * @param type the certificate type.
      * See the CertificateFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard certificate types.
      *
@@ -272,7 +272,7 @@
      *
      * @param type the certificate type.
      * See the CertificateFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard certificate types.
      * @param provider the provider.
@@ -370,7 +370,7 @@
      * Returns an iteration of the {@code CertPath} encodings supported
      * by this certificate factory, with the default encoding first. See
      * the CertPath Encodings section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathEncodings">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard encoding names and their formats.
      * <p>
@@ -410,7 +410,7 @@
      * the data read from the {@code InputStream} inStream. The data
      * is assumed to be in the specified encoding. See
      * the CertPath Encodings section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathEncodings">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard encoding names and their formats.
      *
diff --git a/ojluni/src/main/java/java/security/cert/CertificateFactorySpi.java b/ojluni/src/main/java/java/security/cert/CertificateFactorySpi.java
index 5e13831..691777d 100644
--- a/ojluni/src/main/java/java/security/cert/CertificateFactorySpi.java
+++ b/ojluni/src/main/java/java/security/cert/CertificateFactorySpi.java
@@ -183,7 +183,7 @@
      * Returns an iteration of the {@code CertPath} encodings supported
      * by this certificate factory, with the default encoding first. See
      * the CertPath Encodings section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertPathEncodings">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard encoding names.
      * <p>
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/security/cert/package-info.java b/ojluni/src/main/java/java/security/cert/package-info.java
index 0c1cb1f..4830455 100644
--- a/ojluni/src/main/java/java/security/cert/package-info.java
+++ b/ojluni/src/main/java/java/security/cert/package-info.java
@@ -32,14 +32,14 @@
  * <h2>Package Specification</h2>
  *
  * <ul>
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
  *     <b>Java&trade;
  *     Cryptography Architecture (JCA) Reference Guide</b></a>
  *   <li>RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
  *     Certificate Revocation List (CRL) Profile
  *   <li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
  *     Status Protocol - OCSP
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
  *     <b>Java&trade;
  *     Cryptography Architecture Standard Algorithm Name
  *     Documentation</b></a></li>
@@ -52,10 +52,10 @@
  *   <li><a href="http://www.ietf.org/rfc/rfc5280.txt">
  *     http://www.ietf.org/rfc/rfc5280.txt</a>
  *   <li><a href=
- *     "{@docRoot}/openjdk-redirect.html?v=8&path=/technotes/guides/security/certpath/CertPathProgGuide.html">
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html">
  *     <b>Java&trade;
  *     PKI Programmer's Guide</b></a>
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/cert3.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/cert3.html">
  *     <b>X.509 Certificates and Certificate Revocation Lists (CRLs)</b></a>
  * </ul>
  *
diff --git a/ojluni/src/main/java/java/security/interfaces/package-info.java b/ojluni/src/main/java/java/security/interfaces/package-info.java
index a2d77da..8942340 100644
--- a/ojluni/src/main/java/java/security/interfaces/package-info.java
+++ b/ojluni/src/main/java/java/security/interfaces/package-info.java
@@ -43,7 +43,7 @@
  * to these cryptographic provider developer guides:
  * <ul>
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
  *     <b>How to Implement a Provider for the
  *     Java&trade; Cryptography Architecture
  *     </b></a></li>
@@ -63,7 +63,7 @@
  * <ul>
  *   <li>
  *     <a href=
- *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *       "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
  *       <b>Java&trade;
  *       Cryptography Architecture API Specification and Reference
  *       </b></a></li>
diff --git a/ojluni/src/main/java/java/security/package-info.java b/ojluni/src/main/java/java/security/package-info.java
index 50a1527..60e9b4b 100644
--- a/ojluni/src/main/java/java/security/package-info.java
+++ b/ojluni/src/main/java/java/security/package-info.java
@@ -46,14 +46,14 @@
  * <h2>Package Specification</h2>
  *
  * <ul>
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
  *     <b>Java&trade;
  *     Cryptography Architecture (JCA) Reference Guide</b></a></li>
  *
  *   <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
  *     November 1993</li>
  *
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
  *     <b>Java&trade;
  *     Cryptography Architecture Standard Algorithm Name
  *     Documentation</b></a></li>
@@ -64,44 +64,44 @@
  * For further documentation, please see:
  * <ul>
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/spec/security-spec.doc.html">
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc.html">
  *     <b>Java&trade;
  *     SE Platform Security Architecture</b></a></li>
  *
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
  *     <b>How to Implement a Provider in the
  *     Java&trade; Cryptography Architecture
  *     </b></a></li>
  *
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/PolicyFiles.html"><b>
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html"><b>
  *     Default Policy Implementation and Policy File Syntax
  *     </b></a></li>
  *
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/permissions.html"><b>
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html"><b>
  *     Permissions in the
  *     Java&trade; SE Development Kit (JDK)
  *     </b></a></li>
  *
  *   <li><a href=
- *     "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/SecurityToolsSummary.html"><b>
+ *     "https://docs.oracle.com/javase/8/docs/technotes/guides/security/SecurityToolsSummary.html"><b>
  *     Summary of Tools for
  *     Java&trade; Platform Security
  *     </b></a></li>
  *
  *   <li><b>keytool</b>
- *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/tools/unix/keytool.html">
+ *     (<a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html">
  *       for Solaris/Linux</a>)
- *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/tools/windows/keytool.html">
+ *     (<a href="https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html">
  *       for Windows</a>)
  *     </li>
  *
  *   <li><b>jarsigner</b>
- *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/tools/unix/jarsigner.html">
+ *     (<a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jarsigner.html">
  *       for Solaris/Linux</a>)
- *     (<a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/tools/windows/jarsigner.html">
+ *     (<a href="https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jarsigner.html">
  *       for Windows</a>)
  *     </li>
  *
diff --git a/ojluni/src/main/java/java/security/spec/package-info.java b/ojluni/src/main/java/java/security/spec/package-info.java
index 92f30be..68f0b8e 100644
--- a/ojluni/src/main/java/java/security/spec/package-info.java
+++ b/ojluni/src/main/java/java/security/spec/package-info.java
@@ -56,13 +56,13 @@
  * <ul>
  *   <li>
  *     <a href=
- *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+ *       "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
  *       <b>Java&trade;
  *       Cryptography Architecture API Specification and Reference
  *       </b></a></li>
  *   <li>
  *     <a href=
- *       "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+ *       "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
  *       <b>How to Implement a Provider for the
  *       Java&trade; Cryptography Architecture
  *       </b></a></li>
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..2fc6acc 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
@@ -53,7 +53,7 @@
  * </pre>
  *<P> The <code>DriverManager</code> methods <code>getConnection</code> and
  * <code>getDrivers</code> have been enhanced to support the Java Standard Edition
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#Service%20Provider">Service Provider</a> mechanism. JDBC 4.0 Drivers must
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Service%20Provider">Service Provider</a> mechanism. JDBC 4.0 Drivers must
  * include the file <code>META-INF/services/java.sql.Driver</code>. This file contains the name of the JDBC drivers
  * implementation of <code>java.sql.Driver</code>.  For example, to load the <code>my.sql.Driver</code> class,
  * the <code>META-INF/services/java.sql.Driver</code> file would contain the entry:
@@ -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/sql/package.html b/ojluni/src/main/java/java/sql/package.html
index 60acef6..74d6225 100644
--- a/ojluni/src/main/java/java/sql/package.html
+++ b/ojluni/src/main/java/java/sql/package.html
@@ -310,7 +310,7 @@
 <h2>Related Documentation</h2>
 
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/getstart/GettingStartedTOC.fm.html">Getting Started</a>--overviews of the major interfaces
 <P>
   <li><a href="http://java.sun.com/docs/books/tutorial/jdbc">Chapters on the JDBC 
      API</a>--from the online version of <i>The Java Tutorial Continued</i>
diff --git a/ojluni/src/main/java/java/text/DateFormatSymbols.java b/ojluni/src/main/java/java/text/DateFormatSymbols.java
index 946ab0d..97dc528 100644
--- a/ojluni/src/main/java/java/text/DateFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DateFormatSymbols.java
@@ -787,7 +787,7 @@
             return true;
         }
         return Arrays.deepEquals(getZoneStringsWrapper(), that.getZoneStringsWrapper());
-        // END Android-changed: Avoid populating zoneStrings just for the comparison.
+        // END Android-changed: Avoid populating zoneStrings just for the comparison, add fields.
     }
 
     // =======================privates===============================
diff --git a/ojluni/src/main/java/java/text/DecimalFormat.java b/ojluni/src/main/java/java/text/DecimalFormat.java
index 2cb1473..d62cb27 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;
@@ -422,7 +420,7 @@
 
         // Always applyPattern after the symbols are set
         this.symbols = DecimalFormatSymbols.getInstance(def);
-        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
+        // Android-changed: initPattern() and conversion methods between ICU and Java values.
         // applyPattern(all[0], false);
         initPattern(pattern);
     }
@@ -450,7 +448,8 @@
     public DecimalFormat(String pattern) {
         // Always applyPattern after the symbols are set
         this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
-        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
+        // Android-changed: initPattern() and conversion methods between ICU and Java values.
+        // applyPattern(pattern, false);
         initPattern(pattern);
     }
 
@@ -479,7 +478,7 @@
     public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
         // Always applyPattern after the symbols are set
         this.symbols = (DecimalFormatSymbols)symbols.clone();
-        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
+        // Android-changed: initPattern() and conversion methods between ICU and Java values.
         initPattern(pattern);
     }
 
@@ -656,6 +655,28 @@
     public StringBuffer format(double number, StringBuffer result,
                                FieldPosition fieldPosition) {
         // BEGIN Android-changed: Use ICU.
+        /*
+        // If fieldPosition is a DontCareFieldPosition instance we can
+        // try to go to fast-path code.
+        boolean tryFastPath = false;
+        if (fieldPosition == DontCareFieldPosition.INSTANCE)
+            tryFastPath = true;
+        else {
+            fieldPosition.setBeginIndex(0);
+            fieldPosition.setEndIndex(0);
+        }
+
+        if (tryFastPath) {
+            String tempResult = fastFormat(number);
+            if (tempResult != null) {
+                result.append(tempResult);
+                return result;
+            }
+        }
+
+        // if fast-path could not work, we fallback to standard code.
+        return format(number, result, fieldPosition.getFieldDelegate());
+        */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
         icuDecimalFormat.format(number, result, icuFieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
@@ -664,7 +685,93 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private StringBuffer format(double, StringBuffer, FieldDelegate).
+    // BEGIN Android-removed: Use ICU.
+    // Removed unused helper function that was only used from (unused on Android) code
+    // in format(double, StringBuffer, FieldPosition).
+    /*
+    /**
+     * Formats a double to produce a string.
+     * @param number    The double to format
+     * @param result    where the text is to be appended
+     * @param delegate notified of locations of sub fields
+     * @exception       ArithmeticException if rounding is needed with rounding
+     *                  mode being set to RoundingMode.UNNECESSARY
+     * @return The formatted number string
+     *
+    private StringBuffer format(double number, StringBuffer result,
+                                FieldDelegate delegate) {
+        if (Double.isNaN(number) ||
+           (Double.isInfinite(number) && multiplier == 0)) {
+            int iFieldStart = result.length();
+            result.append(symbols.getNaN());
+            delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
+                               iFieldStart, result.length(), result);
+            return result;
+        }
+
+        /* Detecting whether a double is negative is easy with the exception of
+         * the value -0.0.  This is a double which has a zero mantissa (and
+         * exponent), but a negative sign bit.  It is semantically distinct from
+         * a zero with a positive sign bit, and this distinction is important
+         * to certain kinds of computations.  However, it's a little tricky to
+         * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
+         * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
+         * -Infinity.  Proper detection of -0.0 is needed to deal with the
+         * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
+         *
+        boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
+
+        if (multiplier != 1) {
+            number *= multiplier;
+        }
+
+        if (Double.isInfinite(number)) {
+            if (isNegative) {
+                append(result, negativePrefix, delegate,
+                       getNegativePrefixFieldPositions(), Field.SIGN);
+            } else {
+                append(result, positivePrefix, delegate,
+                       getPositivePrefixFieldPositions(), Field.SIGN);
+            }
+
+            int iFieldStart = result.length();
+            result.append(symbols.getInfinity());
+            delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
+                               iFieldStart, result.length(), result);
+
+            if (isNegative) {
+                append(result, negativeSuffix, delegate,
+                       getNegativeSuffixFieldPositions(), Field.SIGN);
+            } else {
+                append(result, positiveSuffix, delegate,
+                       getPositiveSuffixFieldPositions(), Field.SIGN);
+            }
+
+            return result;
+        }
+
+        if (isNegative) {
+            number = -number;
+        }
+
+        // at this point we are guaranteed a nonnegative finite number.
+        assert(number >= 0 && !Double.isInfinite(number));
+
+        synchronized(digitList) {
+            int maxIntDigits = super.getMaximumIntegerDigits();
+            int minIntDigits = super.getMinimumIntegerDigits();
+            int maxFraDigits = super.getMaximumFractionDigits();
+            int minFraDigits = super.getMinimumFractionDigits();
+
+            digitList.set(isNegative, number, useExponentialNotation ?
+                          maxIntDigits + maxFraDigits : maxFraDigits,
+                          !useExponentialNotation);
+            return subformat(result, delegate, isNegative, false,
+                       maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
+        }
+    }
+    */
+    // END Android-removed: Use ICU.
 
     /**
      * Format a long to produce a string.
@@ -681,6 +788,12 @@
     public StringBuffer format(long number, StringBuffer result,
                                FieldPosition fieldPosition) {
         // BEGIN Android-changed: Use ICU.
+        /*
+        fieldPosition.setBeginIndex(0);
+        fieldPosition.setEndIndex(0);
+
+        return format(number, result, fieldPosition.getFieldDelegate());
+        */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
         icuDecimalFormat.format(number, result, icuFieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
@@ -689,7 +802,79 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private StringBuffer format(long, StringBuffer, FieldDelegate).
+    // BEGIN Android-removed: Use ICU.
+    // Removed unused helper function that was only used from (unused on Android) code
+    // in format(long, StringBuffer, FieldDelegate).
+    /*
+    /**
+     * Format a long to produce a string.
+     * @param number    The long to format
+     * @param result    where the text is to be appended
+     * @param delegate notified of locations of sub fields
+     * @return The formatted number string
+     * @exception        ArithmeticException if rounding is needed with rounding
+     *                   mode being set to RoundingMode.UNNECESSARY
+     * @see java.text.FieldPosition
+     *
+    private StringBuffer format(long number, StringBuffer result,
+                               FieldDelegate delegate) {
+        boolean isNegative = (number < 0);
+        if (isNegative) {
+            number = -number;
+        }
+
+        // In general, long values always represent real finite numbers, so
+        // we don't have to check for +/- Infinity or NaN.  However, there
+        // is one case we have to be careful of:  The multiplier can push
+        // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
+        // check for this before multiplying, and if it happens we use
+        // BigInteger instead.
+        boolean useBigInteger = false;
+        if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
+            if (multiplier != 0) {
+                useBigInteger = true;
+            }
+        } else if (multiplier != 1 && multiplier != 0) {
+            long cutoff = Long.MAX_VALUE / multiplier;
+            if (cutoff < 0) {
+                cutoff = -cutoff;
+            }
+            useBigInteger = (number > cutoff);
+        }
+
+        if (useBigInteger) {
+            if (isNegative) {
+                number = -number;
+            }
+            BigInteger bigIntegerValue = BigInteger.valueOf(number);
+            return format(bigIntegerValue, result, delegate, true);
+        }
+
+        number *= multiplier;
+        if (number == 0) {
+            isNegative = false;
+        } else {
+            if (multiplier < 0) {
+                number = -number;
+                isNegative = !isNegative;
+            }
+        }
+
+        synchronized(digitList) {
+            int maxIntDigits = super.getMaximumIntegerDigits();
+            int minIntDigits = super.getMinimumIntegerDigits();
+            int maxFraDigits = super.getMaximumFractionDigits();
+            int minFraDigits = super.getMinimumFractionDigits();
+
+            digitList.set(isNegative, number,
+                     useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
+
+            return subformat(result, delegate, isNegative, true,
+                       maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
+        }
+    }
+    */
+    // END Android-removed: Use ICU.
 
     /**
      * Formats a BigDecimal to produce a string.
@@ -705,6 +890,11 @@
     private StringBuffer format(BigDecimal number, StringBuffer result,
                                 FieldPosition fieldPosition) {
         // BEGIN Android-changed: Use ICU.
+        /*
+        fieldPosition.setBeginIndex(0);
+        fieldPosition.setEndIndex(0);
+        return format(number, result, fieldPosition.getFieldDelegate());
+        */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
         icuDecimalFormat.format(number, result, fieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
@@ -713,7 +903,46 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private StringBuffer format(BigDecimal, StringBuffer, FieldDelegate).
+    // BEGIN Android-removed: Use ICU.
+    // Removed unused helper function that was only used from (unused on Android) code
+    // in format(BigDecimal, StringBuffer, FieldDelegate).
+    /*
+    /**
+     * Formats a BigDecimal to produce a string.
+     * @param number    The BigDecimal to format
+     * @param result    where the text is to be appended
+     * @param delegate notified of locations of sub fields
+     * @exception        ArithmeticException if rounding is needed with rounding
+     *                   mode being set to RoundingMode.UNNECESSARY
+     * @return The formatted number string
+     *
+    private StringBuffer format(BigDecimal number, StringBuffer result,
+                                FieldDelegate delegate) {
+        if (multiplier != 1) {
+            number = number.multiply(getBigDecimalMultiplier());
+        }
+        boolean isNegative = number.signum() == -1;
+        if (isNegative) {
+            number = number.negate();
+        }
+
+        synchronized(digitList) {
+            int maxIntDigits = getMaximumIntegerDigits();
+            int minIntDigits = getMinimumIntegerDigits();
+            int maxFraDigits = getMaximumFractionDigits();
+            int minFraDigits = getMinimumFractionDigits();
+            int maximumDigits = maxIntDigits + maxFraDigits;
+
+            digitList.set(isNegative, number, useExponentialNotation ?
+                ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
+                maxFraDigits, !useExponentialNotation);
+
+            return subformat(result, delegate, isNegative, false,
+                maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
+        }
+    }
+    */
+    // END Android-removed: Use ICU.
 
     /**
      * Format a BigInteger to produce a string.
@@ -729,6 +958,12 @@
     private StringBuffer format(BigInteger number, StringBuffer result,
                                FieldPosition fieldPosition) {
         // BEGIN Android-changed: Use ICU.
+        /*
+        fieldPosition.setBeginIndex(0);
+        fieldPosition.setEndIndex(0);
+
+        return format(number, result, fieldPosition.getFieldDelegate(), false);
+        */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
         icuDecimalFormat.format(number, result, fieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
@@ -737,7 +972,58 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private StringBuffer format(BigInteger, StringBuffer, FieldDelegate).
+    // BEGIN Android-removed: Use ICU.
+    // Removed unused helper function that was only used from (unused on Android) code
+    // in format(BigInteger, StringBuffer, FieldDelegate).
+    /*
+    /**
+     * Format a BigInteger to produce a string.
+     * @param number    The BigInteger to format
+     * @param result    where the text is to be appended
+     * @param delegate notified of locations of sub fields
+     * @return The formatted number string
+     * @exception        ArithmeticException if rounding is needed with rounding
+     *                   mode being set to RoundingMode.UNNECESSARY
+     * @see java.text.FieldPosition
+     *
+    private StringBuffer format(BigInteger number, StringBuffer result,
+                               FieldDelegate delegate, boolean formatLong) {
+        if (multiplier != 1) {
+            number = number.multiply(getBigIntegerMultiplier());
+        }
+        boolean isNegative = number.signum() == -1;
+        if (isNegative) {
+            number = number.negate();
+        }
+
+        synchronized(digitList) {
+            int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
+            if (formatLong) {
+                maxIntDigits = super.getMaximumIntegerDigits();
+                minIntDigits = super.getMinimumIntegerDigits();
+                maxFraDigits = super.getMaximumFractionDigits();
+                minFraDigits = super.getMinimumFractionDigits();
+                maximumDigits = maxIntDigits + maxFraDigits;
+            } else {
+                maxIntDigits = getMaximumIntegerDigits();
+                minIntDigits = getMinimumIntegerDigits();
+                maxFraDigits = getMaximumFractionDigits();
+                minFraDigits = getMinimumFractionDigits();
+                maximumDigits = maxIntDigits + maxFraDigits;
+                if (maximumDigits < 0) {
+                    maximumDigits = Integer.MAX_VALUE;
+                }
+            }
+
+            digitList.set(isNegative, number,
+                          useExponentialNotation ? maximumDigits : 0);
+
+            return subformat(result, delegate, isNegative, true,
+                maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
+        }
+    }
+    */
+    // END Android-removed: Use ICU.
 
     /**
      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
@@ -761,6 +1047,30 @@
     @Override
     public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
         // BEGIN Android-changed: Use ICU.
+        /*
+        CharacterIteratorFieldDelegate delegate =
+                         new CharacterIteratorFieldDelegate();
+        StringBuffer sb = new StringBuffer();
+
+        if (obj instanceof Double || obj instanceof Float) {
+            format(((Number)obj).doubleValue(), sb, delegate);
+        } else if (obj instanceof Long || obj instanceof Integer ||
+                   obj instanceof Short || obj instanceof Byte ||
+                   obj instanceof AtomicInteger || obj instanceof AtomicLong) {
+            format(((Number)obj).longValue(), sb, delegate);
+        } else if (obj instanceof BigDecimal) {
+            format((BigDecimal)obj, sb, delegate);
+        } else if (obj instanceof BigInteger) {
+            format((BigInteger)obj, sb, delegate, false);
+        } else if (obj == null) {
+            throw new NullPointerException(
+                "formatToCharacterIterator must be passed non-null object");
+        } else {
+            throw new IllegalArgumentException(
+                "Cannot format given Object as a Number");
+        }
+        return delegate.getIterator(sb.toString());
+        */
         if (obj == null) {
             throw new NullPointerException("object == null");
         }
@@ -797,9 +1107,1066 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: "fast-path formating logic for double" (sic).
+    // BEGIN Android-removed: "fast-path formatting logic for double", subformat(), append().
+    /*
+    // ==== Begin fast-path formating logic for double =========================
 
-    // Android-removed: subformat(), append().
+    /* Fast-path formatting will be used for format(double ...) methods iff a
+     * number of conditions are met (see checkAndSetFastPathStatus()):
+     * - Only if instance properties meet the right predefined conditions.
+     * - The abs value of the double to format is <= Integer.MAX_VALUE.
+     *
+     * The basic approach is to split the binary to decimal conversion of a
+     * double value into two phases:
+     * * The conversion of the integer portion of the double.
+     * * The conversion of the fractional portion of the double
+     *   (limited to two or three digits).
+     *
+     * The isolation and conversion of the integer portion of the double is
+     * straightforward. The conversion of the fraction is more subtle and relies
+     * on some rounding properties of double to the decimal precisions in
+     * question.  Using the terminology of BigDecimal, this fast-path algorithm
+     * is applied when a double value has a magnitude less than Integer.MAX_VALUE
+     * and rounding is to nearest even and the destination format has two or
+     * three digits of *scale* (digits after the decimal point).
+     *
+     * Under a rounding to nearest even policy, the returned result is a digit
+     * string of a number in the (in this case decimal) destination format
+     * closest to the exact numerical value of the (in this case binary) input
+     * value.  If two destination format numbers are equally distant, the one
+     * with the last digit even is returned.  To compute such a correctly rounded
+     * value, some information about digits beyond the smallest returned digit
+     * position needs to be consulted.
+     *
+     * In general, a guard digit, a round digit, and a sticky *bit* are needed
+     * beyond the returned digit position.  If the discarded portion of the input
+     * is sufficiently large, the returned digit string is incremented.  In round
+     * to nearest even, this threshold to increment occurs near the half-way
+     * point between digits.  The sticky bit records if there are any remaining
+     * trailing digits of the exact input value in the new format; the sticky bit
+     * is consulted only in close to half-way rounding cases.
+     *
+     * Given the computation of the digit and bit values, rounding is then
+     * reduced to a table lookup problem.  For decimal, the even/odd cases look
+     * like this:
+     *
+     * Last   Round   Sticky
+     * 6      5       0      => 6   // exactly halfway, return even digit.
+     * 6      5       1      => 7   // a little bit more than halfway, round up.
+     * 7      5       0      => 8   // exactly halfway, round up to even.
+     * 7      5       1      => 8   // a little bit more than halfway, round up.
+     * With analogous entries for other even and odd last-returned digits.
+     *
+     * However, decimal negative powers of 5 smaller than 0.5 are *not* exactly
+     * representable as binary fraction.  In particular, 0.005 (the round limit
+     * for a two-digit scale) and 0.0005 (the round limit for a three-digit
+     * scale) are not representable. Therefore, for input values near these cases
+     * the sticky bit is known to be set which reduces the rounding logic to:
+     *
+     * Last   Round   Sticky
+     * 6      5       1      => 7   // a little bit more than halfway, round up.
+     * 7      5       1      => 8   // a little bit more than halfway, round up.
+     *
+     * In other words, if the round digit is 5, the sticky bit is known to be
+     * set.  If the round digit is something other than 5, the sticky bit is not
+     * relevant.  Therefore, some of the logic about whether or not to increment
+     * the destination *decimal* value can occur based on tests of *binary*
+     * computations of the binary input number.
+     *
+
+    /**
+     * Check validity of using fast-path for this instance. If fast-path is valid
+     * for this instance, sets fast-path state as true and initializes fast-path
+     * utility fields as needed.
+     *
+     * This method is supposed to be called rarely, otherwise that will break the
+     * fast-path performance. That means avoiding frequent changes of the
+     * properties of the instance, since for most properties, each time a change
+     * happens, a call to this method is needed at the next format call.
+     *
+     * FAST-PATH RULES:
+     *  Similar to the default DecimalFormat instantiation case.
+     *  More precisely:
+     *  - HALF_EVEN rounding mode,
+     *  - isGroupingUsed() is true,
+     *  - groupingSize of 3,
+     *  - multiplier is 1,
+     *  - Decimal separator not mandatory,
+     *  - No use of exponential notation,
+     *  - minimumIntegerDigits is exactly 1 and maximumIntegerDigits at least 10
+     *  - For number of fractional digits, the exact values found in the default case:
+     *     Currency : min = max = 2.
+     *     Decimal  : min = 0. max = 3.
+     *
+     *
+    private void checkAndSetFastPathStatus() {
+
+        boolean fastPathWasOn = isFastPath;
+
+        if ((roundingMode == RoundingMode.HALF_EVEN) &&
+            (isGroupingUsed()) &&
+            (groupingSize == 3) &&
+            (multiplier == 1) &&
+            (!decimalSeparatorAlwaysShown) &&
+            (!useExponentialNotation)) {
+
+            // The fast-path algorithm is semi-hardcoded against
+            //  minimumIntegerDigits and maximumIntegerDigits.
+            isFastPath = ((minimumIntegerDigits == 1) &&
+                          (maximumIntegerDigits >= 10));
+
+            // The fast-path algorithm is hardcoded against
+            //  minimumFractionDigits and maximumFractionDigits.
+            if (isFastPath) {
+                if (isCurrencyFormat) {
+                    if ((minimumFractionDigits != 2) ||
+                        (maximumFractionDigits != 2))
+                        isFastPath = false;
+                } else if ((minimumFractionDigits != 0) ||
+                           (maximumFractionDigits != 3))
+                    isFastPath = false;
+            }
+        } else
+            isFastPath = false;
+
+        // Since some instance properties may have changed while still falling
+        // in the fast-path case, we need to reinitialize fastPathData anyway.
+        if (isFastPath) {
+            // We need to instantiate fastPathData if not already done.
+            if (fastPathData == null)
+                fastPathData = new FastPathData();
+
+            // Sets up the locale specific constants used when formatting.
+            // '0' is our default representation of zero.
+            fastPathData.zeroDelta = symbols.getZeroDigit() - '0';
+            fastPathData.groupingChar = symbols.getGroupingSeparator();
+
+            // Sets up fractional constants related to currency/decimal pattern.
+            fastPathData.fractionalMaxIntBound = (isCurrencyFormat) ? 99 : 999;
+            fastPathData.fractionalScaleFactor = (isCurrencyFormat) ? 100.0d : 1000.0d;
+
+            // Records the need for adding prefix or suffix
+            fastPathData.positiveAffixesRequired =
+                (positivePrefix.length() != 0) || (positiveSuffix.length() != 0);
+            fastPathData.negativeAffixesRequired =
+                (negativePrefix.length() != 0) || (negativeSuffix.length() != 0);
+
+            // Creates a cached char container for result, with max possible size.
+            int maxNbIntegralDigits = 10;
+            int maxNbGroups = 3;
+            int containerSize =
+                Math.max(positivePrefix.length(), negativePrefix.length()) +
+                maxNbIntegralDigits + maxNbGroups + 1 + maximumFractionDigits +
+                Math.max(positiveSuffix.length(), negativeSuffix.length());
+
+            fastPathData.fastPathContainer = new char[containerSize];
+
+            // Sets up prefix and suffix char arrays constants.
+            fastPathData.charsPositiveSuffix = positiveSuffix.toCharArray();
+            fastPathData.charsNegativeSuffix = negativeSuffix.toCharArray();
+            fastPathData.charsPositivePrefix = positivePrefix.toCharArray();
+            fastPathData.charsNegativePrefix = negativePrefix.toCharArray();
+
+            // Sets up fixed index positions for integral and fractional digits.
+            // Sets up decimal point in cached result container.
+            int longestPrefixLength =
+                Math.max(positivePrefix.length(), negativePrefix.length());
+            int decimalPointIndex =
+                maxNbIntegralDigits + maxNbGroups + longestPrefixLength;
+
+            fastPathData.integralLastIndex    = decimalPointIndex - 1;
+            fastPathData.fractionalFirstIndex = decimalPointIndex + 1;
+            fastPathData.fastPathContainer[decimalPointIndex] =
+                isCurrencyFormat ?
+                symbols.getMonetaryDecimalSeparator() :
+                symbols.getDecimalSeparator();
+
+        } else if (fastPathWasOn) {
+            // Previous state was fast-path and is no more.
+            // Resets cached array constants.
+            fastPathData.fastPathContainer = null;
+            fastPathData.charsPositiveSuffix = null;
+            fastPathData.charsNegativeSuffix = null;
+            fastPathData.charsPositivePrefix = null;
+            fastPathData.charsNegativePrefix = null;
+        }
+
+        fastPathCheckNeeded = false;
+    }
+
+    /**
+     * Returns true if rounding-up must be done on {@code scaledFractionalPartAsInt},
+     * false otherwise.
+     *
+     * This is a utility method that takes correct half-even rounding decision on
+     * passed fractional value at the scaled decimal point (2 digits for currency
+     * case and 3 for decimal case), when the approximated fractional part after
+     * scaled decimal point is exactly 0.5d.  This is done by means of exact
+     * calculations on the {@code fractionalPart} floating-point value.
+     *
+     * This method is supposed to be called by private {@code fastDoubleFormat}
+     * method only.
+     *
+     * The algorithms used for the exact calculations are :
+     *
+     * The <b><i>FastTwoSum</i></b> algorithm, from T.J.Dekker, described in the
+     * papers  "<i>A  Floating-Point   Technique  for  Extending  the  Available
+     * Precision</i>"  by Dekker, and  in "<i>Adaptive  Precision Floating-Point
+     * Arithmetic and Fast Robust Geometric Predicates</i>" from J.Shewchuk.
+     *
+     * A modified version of <b><i>Sum2S</i></b> cascaded summation described in
+     * "<i>Accurate Sum and Dot Product</i>" from Takeshi Ogita and All.  As
+     * Ogita says in this paper this is an equivalent of the Kahan-Babuska's
+     * summation algorithm because we order the terms by magnitude before summing
+     * them. For this reason we can use the <i>FastTwoSum</i> algorithm rather
+     * than the more expensive Knuth's <i>TwoSum</i>.
+     *
+     * We do this to avoid a more expensive exact "<i>TwoProduct</i>" algorithm,
+     * like those described in Shewchuk's paper above. See comments in the code
+     * below.
+     *
+     * @param  fractionalPart The  fractional value  on which  we  take rounding
+     * decision.
+     * @param scaledFractionalPartAsInt The integral part of the scaled
+     * fractional value.
+     *
+     * @return the decision that must be taken regarding half-even rounding.
+     *
+    private boolean exactRoundUp(double fractionalPart,
+                                 int scaledFractionalPartAsInt) {
+
+        /* exactRoundUp() method is called by fastDoubleFormat() only.
+         * The precondition expected to be verified by the passed parameters is :
+         * scaledFractionalPartAsInt ==
+         *     (int) (fractionalPart * fastPathData.fractionalScaleFactor).
+         * This is ensured by fastDoubleFormat() code.
+         *
+
+        /* We first calculate roundoff error made by fastDoubleFormat() on
+         * the scaled fractional part. We do this with exact calculation on the
+         * passed fractionalPart. Rounding decision will then be taken from roundoff.
+         *
+
+        /* ---- TwoProduct(fractionalPart, scale factor (i.e. 1000.0d or 100.0d)).
+         *
+         * The below is an optimized exact "TwoProduct" calculation of passed
+         * fractional part with scale factor, using Ogita's Sum2S cascaded
+         * summation adapted as Kahan-Babuska equivalent by using FastTwoSum
+         * (much faster) rather than Knuth's TwoSum.
+         *
+         * We can do this because we order the summation from smallest to
+         * greatest, so that FastTwoSum can be used without any additional error.
+         *
+         * The "TwoProduct" exact calculation needs 17 flops. We replace this by
+         * a cascaded summation of FastTwoSum calculations, each involving an
+         * exact multiply by a power of 2.
+         *
+         * Doing so saves overall 4 multiplications and 1 addition compared to
+         * using traditional "TwoProduct".
+         *
+         * The scale factor is either 100 (currency case) or 1000 (decimal case).
+         * - when 1000, we replace it by (1024 - 16 - 8) = 1000.
+         * - when 100,  we replace it by (128  - 32 + 4) =  100.
+         * Every multiplication by a power of 2 (1024, 128, 32, 16, 8, 4) is exact.
+         *
+         *
+        double approxMax;    // Will always be positive.
+        double approxMedium; // Will always be negative.
+        double approxMin;
+
+        double fastTwoSumApproximation = 0.0d;
+        double fastTwoSumRoundOff = 0.0d;
+        double bVirtual = 0.0d;
+
+        if (isCurrencyFormat) {
+            // Scale is 100 = 128 - 32 + 4.
+            // Multiply by 2**n is a shift. No roundoff. No error.
+            approxMax    = fractionalPart * 128.00d;
+            approxMedium = - (fractionalPart * 32.00d);
+            approxMin    = fractionalPart * 4.00d;
+        } else {
+            // Scale is 1000 = 1024 - 16 - 8.
+            // Multiply by 2**n is a shift. No roundoff. No error.
+            approxMax    = fractionalPart * 1024.00d;
+            approxMedium = - (fractionalPart * 16.00d);
+            approxMin    = - (fractionalPart * 8.00d);
+        }
+
+        // Shewchuk/Dekker's FastTwoSum(approxMedium, approxMin).
+        assert(-approxMedium >= Math.abs(approxMin));
+        fastTwoSumApproximation = approxMedium + approxMin;
+        bVirtual = fastTwoSumApproximation - approxMedium;
+        fastTwoSumRoundOff = approxMin - bVirtual;
+        double approxS1 = fastTwoSumApproximation;
+        double roundoffS1 = fastTwoSumRoundOff;
+
+        // Shewchuk/Dekker's FastTwoSum(approxMax, approxS1);
+        assert(approxMax >= Math.abs(approxS1));
+        fastTwoSumApproximation = approxMax + approxS1;
+        bVirtual = fastTwoSumApproximation - approxMax;
+        fastTwoSumRoundOff = approxS1 - bVirtual;
+        double roundoff1000 = fastTwoSumRoundOff;
+        double approx1000 = fastTwoSumApproximation;
+        double roundoffTotal = roundoffS1 + roundoff1000;
+
+        // Shewchuk/Dekker's FastTwoSum(approx1000, roundoffTotal);
+        assert(approx1000 >= Math.abs(roundoffTotal));
+        fastTwoSumApproximation = approx1000 + roundoffTotal;
+        bVirtual = fastTwoSumApproximation - approx1000;
+
+        // Now we have got the roundoff for the scaled fractional
+        double scaledFractionalRoundoff = roundoffTotal - bVirtual;
+
+        // ---- TwoProduct(fractionalPart, scale (i.e. 1000.0d or 100.0d)) end.
+
+        /* ---- Taking the rounding decision
+         *
+         * We take rounding decision based on roundoff and half-even rounding
+         * rule.
+         *
+         * The above TwoProduct gives us the exact roundoff on the approximated
+         * scaled fractional, and we know that this approximation is exactly
+         * 0.5d, since that has already been tested by the caller
+         * (fastDoubleFormat).
+         *
+         * Decision comes first from the sign of the calculated exact roundoff.
+         * - Since being exact roundoff, it cannot be positive with a scaled
+         *   fractional less than 0.5d, as well as negative with a scaled
+         *   fractional greater than 0.5d. That leaves us with following 3 cases.
+         * - positive, thus scaled fractional == 0.500....0fff ==> round-up.
+         * - negative, thus scaled fractional == 0.499....9fff ==> don't round-up.
+         * - is zero,  thus scaled fractioanl == 0.5 ==> half-even rounding applies :
+         *    we round-up only if the integral part of the scaled fractional is odd.
+         *
+         *
+        if (scaledFractionalRoundoff > 0.0) {
+            return true;
+        } else if (scaledFractionalRoundoff < 0.0) {
+            return false;
+        } else if ((scaledFractionalPartAsInt & 1) != 0) {
+            return true;
+        }
+
+        return false;
+
+        // ---- Taking the rounding decision end
+    }
+
+    /**
+     * Collects integral digits from passed {@code number}, while setting
+     * grouping chars as needed. Updates {@code firstUsedIndex} accordingly.
+     *
+     * Loops downward starting from {@code backwardIndex} position (inclusive).
+     *
+     * @param number  The int value from which we collect digits.
+     * @param digitsBuffer The char array container where digits and grouping chars
+     *  are stored.
+     * @param backwardIndex the position from which we start storing digits in
+     *  digitsBuffer.
+     *
+     *
+    private void collectIntegralDigits(int number,
+                                       char[] digitsBuffer,
+                                       int backwardIndex) {
+        int index = backwardIndex;
+        int q;
+        int r;
+        while (number > 999) {
+            // Generates 3 digits per iteration.
+            q = number / 1000;
+            r = number - (q << 10) + (q << 4) + (q << 3); // -1024 +16 +8 = 1000.
+            number = q;
+
+            digitsBuffer[index--] = DigitArrays.DigitOnes1000[r];
+            digitsBuffer[index--] = DigitArrays.DigitTens1000[r];
+            digitsBuffer[index--] = DigitArrays.DigitHundreds1000[r];
+            digitsBuffer[index--] = fastPathData.groupingChar;
+        }
+
+        // Collects last 3 or less digits.
+        digitsBuffer[index] = DigitArrays.DigitOnes1000[number];
+        if (number > 9) {
+            digitsBuffer[--index]  = DigitArrays.DigitTens1000[number];
+            if (number > 99)
+                digitsBuffer[--index]   = DigitArrays.DigitHundreds1000[number];
+        }
+
+        fastPathData.firstUsedIndex = index;
+    }
+
+    /**
+     * Collects the 2 (currency) or 3 (decimal) fractional digits from passed
+     * {@code number}, starting at {@code startIndex} position
+     * inclusive.  There is no punctuation to set here (no grouping chars).
+     * Updates {@code fastPathData.lastFreeIndex} accordingly.
+     *
+     *
+     * @param number  The int value from which we collect digits.
+     * @param digitsBuffer The char array container where digits are stored.
+     * @param startIndex the position from which we start storing digits in
+     *  digitsBuffer.
+     *
+     *
+    private void collectFractionalDigits(int number,
+                                         char[] digitsBuffer,
+                                         int startIndex) {
+        int index = startIndex;
+
+        char digitOnes = DigitArrays.DigitOnes1000[number];
+        char digitTens = DigitArrays.DigitTens1000[number];
+
+        if (isCurrencyFormat) {
+            // Currency case. Always collects fractional digits.
+            digitsBuffer[index++] = digitTens;
+            digitsBuffer[index++] = digitOnes;
+        } else if (number != 0) {
+            // Decimal case. Hundreds will always be collected
+            digitsBuffer[index++] = DigitArrays.DigitHundreds1000[number];
+
+            // Ending zeros won't be collected.
+            if (digitOnes != '0') {
+                digitsBuffer[index++] = digitTens;
+                digitsBuffer[index++] = digitOnes;
+            } else if (digitTens != '0')
+                digitsBuffer[index++] = digitTens;
+
+        } else
+            // This is decimal pattern and fractional part is zero.
+            // We must remove decimal point from result.
+            index--;
+
+        fastPathData.lastFreeIndex = index;
+    }
+
+    /**
+     * Internal utility.
+     * Adds the passed {@code prefix} and {@code suffix} to {@code container}.
+     *
+     * @param container  Char array container which to prepend/append the
+     *  prefix/suffix.
+     * @param prefix     Char sequence to prepend as a prefix.
+     * @param suffix     Char sequence to append as a suffix.
+     *
+     *
+    //    private void addAffixes(boolean isNegative, char[] container) {
+    private void addAffixes(char[] container, char[] prefix, char[] suffix) {
+
+        // We add affixes only if needed (affix length > 0).
+        int pl = prefix.length;
+        int sl = suffix.length;
+        if (pl != 0) prependPrefix(prefix, pl, container);
+        if (sl != 0) appendSuffix(suffix, sl, container);
+
+    }
+
+    /**
+     * Prepends the passed {@code prefix} chars to given result
+     * {@code container}.  Updates {@code fastPathData.firstUsedIndex}
+     * accordingly.
+     *
+     * @param prefix The prefix characters to prepend to result.
+     * @param len The number of chars to prepend.
+     * @param container Char array container which to prepend the prefix
+     *
+    private void prependPrefix(char[] prefix,
+                               int len,
+                               char[] container) {
+
+        fastPathData.firstUsedIndex -= len;
+        int startIndex = fastPathData.firstUsedIndex;
+
+        // If prefix to prepend is only 1 char long, just assigns this char.
+        // If prefix is less or equal 4, we use a dedicated algorithm that
+        //  has shown to run faster than System.arraycopy.
+        // If more than 4, we use System.arraycopy.
+        if (len == 1)
+            container[startIndex] = prefix[0];
+        else if (len <= 4) {
+            int dstLower = startIndex;
+            int dstUpper = dstLower + len - 1;
+            int srcUpper = len - 1;
+            container[dstLower] = prefix[0];
+            container[dstUpper] = prefix[srcUpper];
+
+            if (len > 2)
+                container[++dstLower] = prefix[1];
+            if (len == 4)
+                container[--dstUpper] = prefix[2];
+        } else
+            System.arraycopy(prefix, 0, container, startIndex, len);
+    }
+
+    /**
+     * Appends the passed {@code suffix} chars to given result
+     * {@code container}.  Updates {@code fastPathData.lastFreeIndex}
+     * accordingly.
+     *
+     * @param suffix The suffix characters to append to result.
+     * @param len The number of chars to append.
+     * @param container Char array container which to append the suffix
+     *
+    private void appendSuffix(char[] suffix,
+                              int len,
+                              char[] container) {
+
+        int startIndex = fastPathData.lastFreeIndex;
+
+        // If suffix to append is only 1 char long, just assigns this char.
+        // If suffix is less or equal 4, we use a dedicated algorithm that
+        //  has shown to run faster than System.arraycopy.
+        // If more than 4, we use System.arraycopy.
+        if (len == 1)
+            container[startIndex] = suffix[0];
+        else if (len <= 4) {
+            int dstLower = startIndex;
+            int dstUpper = dstLower + len - 1;
+            int srcUpper = len - 1;
+            container[dstLower] = suffix[0];
+            container[dstUpper] = suffix[srcUpper];
+
+            if (len > 2)
+                container[++dstLower] = suffix[1];
+            if (len == 4)
+                container[--dstUpper] = suffix[2];
+        } else
+            System.arraycopy(suffix, 0, container, startIndex, len);
+
+        fastPathData.lastFreeIndex += len;
+    }
+
+    /**
+     * Converts digit chars from {@code digitsBuffer} to current locale.
+     *
+     * Must be called before adding affixes since we refer to
+     * {@code fastPathData.firstUsedIndex} and {@code fastPathData.lastFreeIndex},
+     * and do not support affixes (for speed reason).
+     *
+     * We loop backward starting from last used index in {@code fastPathData}.
+     *
+     * @param digitsBuffer The char array container where the digits are stored.
+     *
+    private void localizeDigits(char[] digitsBuffer) {
+
+        // We will localize only the digits, using the groupingSize,
+        // and taking into account fractional part.
+
+        // First take into account fractional part.
+        int digitsCounter =
+            fastPathData.lastFreeIndex - fastPathData.fractionalFirstIndex;
+
+        // The case when there is no fractional digits.
+        if (digitsCounter < 0)
+            digitsCounter = groupingSize;
+
+        // Only the digits remains to localize.
+        for (int cursor = fastPathData.lastFreeIndex - 1;
+             cursor >= fastPathData.firstUsedIndex;
+             cursor--) {
+            if (digitsCounter != 0) {
+                // This is a digit char, we must localize it.
+                digitsBuffer[cursor] += fastPathData.zeroDelta;
+                digitsCounter--;
+            } else {
+                // Decimal separator or grouping char. Reinit counter only.
+                digitsCounter = groupingSize;
+            }
+        }
+    }
+
+    /**
+     * This is the main entry point for the fast-path format algorithm.
+     *
+     * At this point we are sure to be in the expected conditions to run it.
+     * This algorithm builds the formatted result and puts it in the dedicated
+     * {@code fastPathData.fastPathContainer}.
+     *
+     * @param d the double value to be formatted.
+     * @param negative Flag precising if {@code d} is negative.
+     *
+    private void fastDoubleFormat(double d,
+                                  boolean negative) {
+
+        char[] container = fastPathData.fastPathContainer;
+
+        /*
+         * The principle of the algorithm is to :
+         * - Break the passed double into its integral and fractional parts
+         *    converted into integers.
+         * - Then decide if rounding up must be applied or not by following
+         *    the half-even rounding rule, first using approximated scaled
+         *    fractional part.
+         * - For the difficult cases (approximated scaled fractional part
+         *    being exactly 0.5d), we refine the rounding decision by calling
+         *    exactRoundUp utility method that both calculates the exact roundoff
+         *    on the approximation and takes correct rounding decision.
+         * - We round-up the fractional part if needed, possibly propagating the
+         *    rounding to integral part if we meet a "all-nine" case for the
+         *    scaled fractional part.
+         * - We then collect digits from the resulting integral and fractional
+         *   parts, also setting the required grouping chars on the fly.
+         * - Then we localize the collected digits if needed, and
+         * - Finally prepend/append prefix/suffix if any is needed.
+         *
+
+        // Exact integral part of d.
+        int integralPartAsInt = (int) d;
+
+        // Exact fractional part of d (since we subtract it's integral part).
+        double exactFractionalPart = d - (double) integralPartAsInt;
+
+        // Approximated scaled fractional part of d (due to multiplication).
+        double scaledFractional =
+            exactFractionalPart * fastPathData.fractionalScaleFactor;
+
+        // Exact integral part of scaled fractional above.
+        int fractionalPartAsInt = (int) scaledFractional;
+
+        // Exact fractional part of scaled fractional above.
+        scaledFractional = scaledFractional - (double) fractionalPartAsInt;
+
+        // Only when scaledFractional is exactly 0.5d do we have to do exact
+        // calculations and take fine-grained rounding decision, since
+        // approximated results above may lead to incorrect decision.
+        // Otherwise comparing against 0.5d (strictly greater or less) is ok.
+        boolean roundItUp = false;
+        if (scaledFractional >= 0.5d) {
+            if (scaledFractional == 0.5d)
+                // Rounding need fine-grained decision.
+                roundItUp = exactRoundUp(exactFractionalPart, fractionalPartAsInt);
+            else
+                roundItUp = true;
+
+            if (roundItUp) {
+                // Rounds up both fractional part (and also integral if needed).
+                if (fractionalPartAsInt < fastPathData.fractionalMaxIntBound) {
+                    fractionalPartAsInt++;
+                } else {
+                    // Propagates rounding to integral part since "all nines" case.
+                    fractionalPartAsInt = 0;
+                    integralPartAsInt++;
+                }
+            }
+        }
+
+        // Collecting digits.
+        collectFractionalDigits(fractionalPartAsInt, container,
+                                fastPathData.fractionalFirstIndex);
+        collectIntegralDigits(integralPartAsInt, container,
+                              fastPathData.integralLastIndex);
+
+        // Localizing digits.
+        if (fastPathData.zeroDelta != 0)
+            localizeDigits(container);
+
+        // Adding prefix and suffix.
+        if (negative) {
+            if (fastPathData.negativeAffixesRequired)
+                addAffixes(container,
+                           fastPathData.charsNegativePrefix,
+                           fastPathData.charsNegativeSuffix);
+        } else if (fastPathData.positiveAffixesRequired)
+            addAffixes(container,
+                       fastPathData.charsPositivePrefix,
+                       fastPathData.charsPositiveSuffix);
+    }
+
+    /**
+     * A fast-path shortcut of format(double) to be called by NumberFormat, or by
+     * format(double, ...) public methods.
+     *
+     * If instance can be applied fast-path and passed double is not NaN or
+     * Infinity, is in the integer range, we call {@code fastDoubleFormat}
+     * after changing {@code d} to its positive value if necessary.
+     *
+     * Otherwise returns null by convention since fast-path can't be exercized.
+     *
+     * @param d The double value to be formatted
+     *
+     * @return the formatted result for {@code d} as a string.
+     *
+    String fastFormat(double d) {
+        // (Re-)Evaluates fast-path status if needed.
+        if (fastPathCheckNeeded)
+            checkAndSetFastPathStatus();
+
+        if (!isFastPath )
+            // DecimalFormat instance is not in a fast-path state.
+            return null;
+
+        if (!Double.isFinite(d))
+            // Should not use fast-path for Infinity and NaN.
+            return null;
+
+        // Extracts and records sign of double value, possibly changing it
+        // to a positive one, before calling fastDoubleFormat().
+        boolean negative = false;
+        if (d < 0.0d) {
+            negative = true;
+            d = -d;
+        } else if (d == 0.0d) {
+            negative = (Math.copySign(1.0d, d) == -1.0d);
+            d = +0.0d;
+        }
+
+        if (d > MAX_INT_AS_DOUBLE)
+            // Filters out values that are outside expected fast-path range
+            return null;
+        else
+            fastDoubleFormat(d, negative);
+
+        // Returns a new string from updated fastPathContainer.
+        return new String(fastPathData.fastPathContainer,
+                          fastPathData.firstUsedIndex,
+                          fastPathData.lastFreeIndex - fastPathData.firstUsedIndex);
+
+    }
+
+    // ======== End fast-path formating logic for double =========================
+
+    /**
+     * Complete the formatting of a finite number.  On entry, the digitList must
+     * be filled in with the correct digits.
+     *
+    private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
+                                   boolean isNegative, boolean isInteger,
+                                   int maxIntDigits, int minIntDigits,
+                                   int maxFraDigits, int minFraDigits) {
+        // NOTE: This isn't required anymore because DigitList takes care of this.
+        //
+        //  // The negative of the exponent represents the number of leading
+        //  // zeros between the decimal and the first non-zero digit, for
+        //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
+        //  // is more than the maximum fraction digits, then we have an underflow
+        //  // for the printed representation.  We recognize this here and set
+        //  // the DigitList representation to zero in this situation.
+        //
+        //  if (-digitList.decimalAt >= getMaximumFractionDigits())
+        //  {
+        //      digitList.count = 0;
+        //  }
+
+        char zero = symbols.getZeroDigit();
+        int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
+        char grouping = symbols.getGroupingSeparator();
+        char decimal = isCurrencyFormat ?
+            symbols.getMonetaryDecimalSeparator() :
+            symbols.getDecimalSeparator();
+
+        /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
+         * format as zero.  This allows sensible computations and preserves
+         * relations such as signum(1/x) = signum(x), where x is +Infinity or
+         * -Infinity.  Prior to this fix, we always formatted zero values as if
+         * they were positive.  Liu 7/6/98.
+         *
+        if (digitList.isZero()) {
+            digitList.decimalAt = 0; // Normalize
+        }
+
+        if (isNegative) {
+            append(result, negativePrefix, delegate,
+                   getNegativePrefixFieldPositions(), Field.SIGN);
+        } else {
+            append(result, positivePrefix, delegate,
+                   getPositivePrefixFieldPositions(), Field.SIGN);
+        }
+
+        if (useExponentialNotation) {
+            int iFieldStart = result.length();
+            int iFieldEnd = -1;
+            int fFieldStart = -1;
+
+            // Minimum integer digits are handled in exponential format by
+            // adjusting the exponent.  For example, 0.01234 with 3 minimum
+            // integer digits is "123.4E-4".
+
+            // Maximum integer digits are interpreted as indicating the
+            // repeating range.  This is useful for engineering notation, in
+            // which the exponent is restricted to a multiple of 3.  For
+            // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
+            // If maximum integer digits are > 1 and are larger than
+            // minimum integer digits, then minimum integer digits are
+            // ignored.
+            int exponent = digitList.decimalAt;
+            int repeat = maxIntDigits;
+            int minimumIntegerDigits = minIntDigits;
+            if (repeat > 1 && repeat > minIntDigits) {
+                // A repeating range is defined; adjust to it as follows.
+                // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
+                // -3,-4,-5=>-6, etc. This takes into account that the
+                // exponent we have here is off by one from what we expect;
+                // it is for the format 0.MMMMMx10^n.
+                if (exponent >= 1) {
+                    exponent = ((exponent - 1) / repeat) * repeat;
+                } else {
+                    // integer division rounds towards 0
+                    exponent = ((exponent - repeat) / repeat) * repeat;
+                }
+                minimumIntegerDigits = 1;
+            } else {
+                // No repeating range is defined; use minimum integer digits.
+                exponent -= minimumIntegerDigits;
+            }
+
+            // We now output a minimum number of digits, and more if there
+            // are more digits, up to the maximum number of digits.  We
+            // place the decimal point after the "integer" digits, which
+            // are the first (decimalAt - exponent) digits.
+            int minimumDigits = minIntDigits + minFraDigits;
+            if (minimumDigits < 0) {    // overflow?
+                minimumDigits = Integer.MAX_VALUE;
+            }
+
+            // The number of integer digits is handled specially if the number
+            // is zero, since then there may be no digits.
+            int integerDigits = digitList.isZero() ? minimumIntegerDigits :
+                    digitList.decimalAt - exponent;
+            if (minimumDigits < integerDigits) {
+                minimumDigits = integerDigits;
+            }
+            int totalDigits = digitList.count;
+            if (minimumDigits > totalDigits) {
+                totalDigits = minimumDigits;
+            }
+            boolean addedDecimalSeparator = false;
+
+            for (int i=0; i<totalDigits; ++i) {
+                if (i == integerDigits) {
+                    // Record field information for caller.
+                    iFieldEnd = result.length();
+
+                    result.append(decimal);
+                    addedDecimalSeparator = true;
+
+                    // Record field information for caller.
+                    fFieldStart = result.length();
+                }
+                result.append((i < digitList.count) ?
+                              (char)(digitList.digits[i] + zeroDelta) :
+                              zero);
+            }
+
+            if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
+                // Record field information for caller.
+                iFieldEnd = result.length();
+
+                result.append(decimal);
+                addedDecimalSeparator = true;
+
+                // Record field information for caller.
+                fFieldStart = result.length();
+            }
+
+            // Record field information
+            if (iFieldEnd == -1) {
+                iFieldEnd = result.length();
+            }
+            delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
+                               iFieldStart, iFieldEnd, result);
+            if (addedDecimalSeparator) {
+                delegate.formatted(Field.DECIMAL_SEPARATOR,
+                                   Field.DECIMAL_SEPARATOR,
+                                   iFieldEnd, fFieldStart, result);
+            }
+            if (fFieldStart == -1) {
+                fFieldStart = result.length();
+            }
+            delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
+                               fFieldStart, result.length(), result);
+
+            // The exponent is output using the pattern-specified minimum
+            // exponent digits.  There is no maximum limit to the exponent
+            // digits, since truncating the exponent would result in an
+            // unacceptable inaccuracy.
+            int fieldStart = result.length();
+
+            result.append(symbols.getExponentSeparator());
+
+            delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
+                               fieldStart, result.length(), result);
+
+            // For zero values, we force the exponent to zero.  We
+            // must do this here, and not earlier, because the value
+            // is used to determine integer digit count above.
+            if (digitList.isZero()) {
+                exponent = 0;
+            }
+
+            boolean negativeExponent = exponent < 0;
+            if (negativeExponent) {
+                exponent = -exponent;
+                fieldStart = result.length();
+                result.append(symbols.getMinusSign());
+                delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
+                                   fieldStart, result.length(), result);
+            }
+            digitList.set(negativeExponent, exponent);
+
+            int eFieldStart = result.length();
+
+            for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
+                result.append(zero);
+            }
+            for (int i=0; i<digitList.decimalAt; ++i) {
+                result.append((i < digitList.count) ?
+                          (char)(digitList.digits[i] + zeroDelta) : zero);
+            }
+            delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
+                               result.length(), result);
+        } else {
+            int iFieldStart = result.length();
+
+            // Output the integer portion.  Here 'count' is the total
+            // number of integer digits we will display, including both
+            // leading zeros required to satisfy getMinimumIntegerDigits,
+            // and actual digits present in the number.
+            int count = minIntDigits;
+            int digitIndex = 0; // Index into digitList.fDigits[]
+            if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
+                count = digitList.decimalAt;
+            }
+
+            // Handle the case where getMaximumIntegerDigits() is smaller
+            // than the real number of integer digits.  If this is so, we
+            // output the least significant max integer digits.  For example,
+            // the value 1997 printed with 2 max integer digits is just "97".
+            if (count > maxIntDigits) {
+                count = maxIntDigits;
+                digitIndex = digitList.decimalAt - count;
+            }
+
+            int sizeBeforeIntegerPart = result.length();
+            for (int i=count-1; i>=0; --i) {
+                if (i < digitList.decimalAt && digitIndex < digitList.count) {
+                    // Output a real digit
+                    result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
+                } else {
+                    // Output a leading zero
+                    result.append(zero);
+                }
+
+                // Output grouping separator if necessary.  Don't output a
+                // grouping separator if i==0 though; that's at the end of
+                // the integer part.
+                if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
+                    (i % groupingSize == 0)) {
+                    int gStart = result.length();
+                    result.append(grouping);
+                    delegate.formatted(Field.GROUPING_SEPARATOR,
+                                       Field.GROUPING_SEPARATOR, gStart,
+                                       result.length(), result);
+                }
+            }
+
+            // Determine whether or not there are any printable fractional
+            // digits.  If we've used up the digits we know there aren't.
+            boolean fractionPresent = (minFraDigits > 0) ||
+                (!isInteger && digitIndex < digitList.count);
+
+            // If there is no fraction present, and we haven't printed any
+            // integer digits, then print a zero.  Otherwise we won't print
+            // _any_ digits, and we won't be able to parse this string.
+            if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
+                result.append(zero);
+            }
+
+            delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
+                               iFieldStart, result.length(), result);
+
+            // Output the decimal separator if we always do so.
+            int sStart = result.length();
+            if (decimalSeparatorAlwaysShown || fractionPresent) {
+                result.append(decimal);
+            }
+
+            if (sStart != result.length()) {
+                delegate.formatted(Field.DECIMAL_SEPARATOR,
+                                   Field.DECIMAL_SEPARATOR,
+                                   sStart, result.length(), result);
+            }
+            int fFieldStart = result.length();
+
+            for (int i=0; i < maxFraDigits; ++i) {
+                // Here is where we escape from the loop.  We escape if we've
+                // output the maximum fraction digits (specified in the for
+                // expression above).
+                // We also stop when we've output the minimum digits and either:
+                // we have an integer, so there is no fractional stuff to
+                // display, or we're out of significant digits.
+                if (i >= minFraDigits &&
+                    (isInteger || digitIndex >= digitList.count)) {
+                    break;
+                }
+
+                // Output leading fractional zeros. These are zeros that come
+                // after the decimal but before any significant digits. These
+                // are only output if abs(number being formatted) < 1.0.
+                if (-1-i > (digitList.decimalAt-1)) {
+                    result.append(zero);
+                    continue;
+                }
+
+                // Output a digit, if we have any precision left, or a
+                // zero if we don't.  We don't want to output noise digits.
+                if (!isInteger && digitIndex < digitList.count) {
+                    result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
+                } else {
+                    result.append(zero);
+                }
+            }
+
+            // Record field information for caller.
+            delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
+                               fFieldStart, result.length(), result);
+        }
+
+        if (isNegative) {
+            append(result, negativeSuffix, delegate,
+                   getNegativeSuffixFieldPositions(), Field.SIGN);
+        } else {
+            append(result, positiveSuffix, delegate,
+                   getPositiveSuffixFieldPositions(), Field.SIGN);
+        }
+
+        return result;
+    }
+
+    /**
+     * Appends the String <code>string</code> to <code>result</code>.
+     * <code>delegate</code> is notified of all  the
+     * <code>FieldPosition</code>s in <code>positions</code>.
+     * <p>
+     * If one of the <code>FieldPosition</code>s in <code>positions</code>
+     * identifies a <code>SIGN</code> attribute, it is mapped to
+     * <code>signAttribute</code>. This is used
+     * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
+     * attribute as necessary.
+     * <p>
+     * This is used by <code>subformat</code> to add the prefix/suffix.
+     *
+    private void append(StringBuffer result, String string,
+                        FieldDelegate delegate,
+                        FieldPosition[] positions,
+                        Format.Field signAttribute) {
+        int start = result.length();
+
+        if (string.length() > 0) {
+            result.append(string);
+            for (int counter = 0, max = positions.length; counter < max;
+                 counter++) {
+                FieldPosition fp = positions[counter];
+                Format.Field attribute = fp.getFieldAttribute();
+
+                if (attribute == Field.SIGN) {
+                    attribute = signAttribute;
+                }
+                delegate.formatted(attribute, attribute,
+                                   start + fp.getBeginIndex(),
+                                   start + fp.getEndIndex(), result);
+            }
+        }
+    }
+    */
+    // END Android-removed: "fast-path formatting logic for double", subformat(), append().
 
     /**
      * Parses text from a string to produce a <code>Number</code>.
@@ -861,6 +2228,111 @@
     public Number parse(String text, ParsePosition pos) {
         // BEGIN Android-changed: Use ICU.
         // Return early if the parse position is bogus.
+        /*
+        // special case NaN
+        if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
+            pos.index = pos.index + symbols.getNaN().length();
+            return new Double(Double.NaN);
+        }
+
+        boolean[] status = new boolean[STATUS_LENGTH];
+        if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
+            return null;
+        }
+
+        // special case INFINITY
+        if (status[STATUS_INFINITE]) {
+            if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
+                return new Double(Double.POSITIVE_INFINITY);
+            } else {
+                return new Double(Double.NEGATIVE_INFINITY);
+            }
+        }
+
+        if (multiplier == 0) {
+            if (digitList.isZero()) {
+                return new Double(Double.NaN);
+            } else if (status[STATUS_POSITIVE]) {
+                return new Double(Double.POSITIVE_INFINITY);
+            } else {
+                return new Double(Double.NEGATIVE_INFINITY);
+            }
+        }
+
+        if (isParseBigDecimal()) {
+            BigDecimal bigDecimalResult = digitList.getBigDecimal();
+
+            if (multiplier != 1) {
+                try {
+                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
+                }
+                catch (ArithmeticException e) {  // non-terminating decimal expansion
+                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
+                }
+            }
+
+            if (!status[STATUS_POSITIVE]) {
+                bigDecimalResult = bigDecimalResult.negate();
+            }
+            return bigDecimalResult;
+        } else {
+            boolean gotDouble = true;
+            boolean gotLongMinimum = false;
+            double  doubleResult = 0.0;
+            long    longResult = 0;
+
+            // Finally, have DigitList parse the digits into a value.
+            if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
+                gotDouble = false;
+                longResult = digitList.getLong();
+                if (longResult < 0) {  // got Long.MIN_VALUE
+                    gotLongMinimum = true;
+                }
+            } else {
+                doubleResult = digitList.getDouble();
+            }
+
+            // Divide by multiplier. We have to be careful here not to do
+            // unneeded conversions between double and long.
+            if (multiplier != 1) {
+                if (gotDouble) {
+                    doubleResult /= multiplier;
+                } else {
+                    // Avoid converting to double if we can
+                    if (longResult % multiplier == 0) {
+                        longResult /= multiplier;
+                    } else {
+                        doubleResult = ((double)longResult) / multiplier;
+                        gotDouble = true;
+                    }
+                }
+            }
+
+            if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
+                doubleResult = -doubleResult;
+                longResult = -longResult;
+            }
+
+            // At this point, if we divided the result by the multiplier, the
+            // result may fit into a long.  We check for this case and return
+            // a long if possible.
+            // We must do this AFTER applying the negative (if appropriate)
+            // in order to handle the case of LONG_MIN; otherwise, if we do
+            // this with a positive value -LONG_MIN, the double is > 0, but
+            // the long is < 0. We also must retain a double in the case of
+            // -0.0, which will compare as == to a long 0 cast to a double
+            // (bug 4162852).
+            if (multiplier != 1 && gotDouble) {
+                longResult = (long)doubleResult;
+                gotDouble = ((doubleResult != (double)longResult) ||
+                            (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
+                            !isParseIntegerOnly();
+            }
+
+            return gotDouble ?
+                (Number)new Double(doubleResult) : (Number)new Long(longResult);
+        }
+        */
         if (pos.index < 0 || pos.index >= text.length()) {
             return null;
         }
@@ -896,7 +2368,258 @@
         // END Android-changed: Use ICU.
     }
 
-    // Android-removed: STATUS_* constants, multiplier fields and methods and subparse(String, ...).
+    // BEGIN Android-removed: Unused private helpers.
+    /*
+    /**
+     * Return a BigInteger multiplier.
+     *
+    private BigInteger getBigIntegerMultiplier() {
+        if (bigIntegerMultiplier == null) {
+            bigIntegerMultiplier = BigInteger.valueOf(multiplier);
+        }
+        return bigIntegerMultiplier;
+    }
+    private transient BigInteger bigIntegerMultiplier;
+
+    /**
+     * Return a BigDecimal multiplier.
+     *
+    private BigDecimal getBigDecimalMultiplier() {
+        if (bigDecimalMultiplier == null) {
+            bigDecimalMultiplier = new BigDecimal(multiplier);
+        }
+        return bigDecimalMultiplier;
+    }
+    private transient BigDecimal bigDecimalMultiplier;
+
+    private static final int STATUS_INFINITE = 0;
+    private static final int STATUS_POSITIVE = 1;
+    private static final int STATUS_LENGTH   = 2;
+
+    /**
+     * Parse the given text into a number.  The text is parsed beginning at
+     * parsePosition, until an unparseable character is seen.
+     * @param text The string to parse.
+     * @param parsePosition The position at which to being parsing.  Upon
+     * return, the first unparseable character.
+     * @param digits The DigitList to set to the parsed value.
+     * @param isExponent If true, parse an exponent.  This means no
+     * infinite values and integer only.
+     * @param status Upon return contains boolean status flags indicating
+     * whether the value was infinite and whether it was positive.
+     *
+    private final boolean subparse(String text, ParsePosition parsePosition,
+                   String positivePrefix, String negativePrefix,
+                   DigitList digits, boolean isExponent,
+                   boolean status[]) {
+        int position = parsePosition.index;
+        int oldStart = parsePosition.index;
+        int backup;
+        boolean gotPositive, gotNegative;
+
+        // check for positivePrefix; take longest
+        gotPositive = text.regionMatches(position, positivePrefix, 0,
+                                         positivePrefix.length());
+        gotNegative = text.regionMatches(position, negativePrefix, 0,
+                                         negativePrefix.length());
+
+        if (gotPositive && gotNegative) {
+            if (positivePrefix.length() > negativePrefix.length()) {
+                gotNegative = false;
+            } else if (positivePrefix.length() < negativePrefix.length()) {
+                gotPositive = false;
+            }
+        }
+
+        if (gotPositive) {
+            position += positivePrefix.length();
+        } else if (gotNegative) {
+            position += negativePrefix.length();
+        } else {
+            parsePosition.errorIndex = position;
+            return false;
+        }
+
+        // process digits or Inf, find decimal position
+        status[STATUS_INFINITE] = false;
+        if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
+                          symbols.getInfinity().length())) {
+            position += symbols.getInfinity().length();
+            status[STATUS_INFINITE] = true;
+        } else {
+            // We now have a string of digits, possibly with grouping symbols,
+            // and decimal points.  We want to process these into a DigitList.
+            // We don't want to put a bunch of leading zeros into the DigitList
+            // though, so we keep track of the location of the decimal point,
+            // put only significant digits into the DigitList, and adjust the
+            // exponent as needed.
+
+            digits.decimalAt = digits.count = 0;
+            char zero = symbols.getZeroDigit();
+            char decimal = isCurrencyFormat ?
+                symbols.getMonetaryDecimalSeparator() :
+                symbols.getDecimalSeparator();
+            char grouping = symbols.getGroupingSeparator();
+            String exponentString = symbols.getExponentSeparator();
+            boolean sawDecimal = false;
+            boolean sawExponent = false;
+            boolean sawDigit = false;
+            int exponent = 0; // Set to the exponent value, if any
+
+            // We have to track digitCount ourselves, because digits.count will
+            // pin when the maximum allowable digits is reached.
+            int digitCount = 0;
+
+            backup = -1;
+            for (; position < text.length(); ++position) {
+                char ch = text.charAt(position);
+
+                /* We recognize all digit ranges, not only the Latin digit range
+                 * '0'..'9'.  We do so by using the Character.digit() method,
+                 * which converts a valid Unicode digit to the range 0..9.
+                 *
+                 * The character 'ch' may be a digit.  If so, place its value
+                 * from 0 to 9 in 'digit'.  First try using the locale digit,
+                 * which may or MAY NOT be a standard Unicode digit range.  If
+                 * this fails, try using the standard Unicode digit ranges by
+                 * calling Character.digit().  If this also fails, digit will
+                 * have a value outside the range 0..9.
+                 *
+                int digit = ch - zero;
+                if (digit < 0 || digit > 9) {
+                    digit = Character.digit(ch, 10);
+                }
+
+                if (digit == 0) {
+                    // Cancel out backup setting (see grouping handler below)
+                    backup = -1; // Do this BEFORE continue statement below!!!
+                    sawDigit = true;
+
+                    // Handle leading zeros
+                    if (digits.count == 0) {
+                        // Ignore leading zeros in integer part of number.
+                        if (!sawDecimal) {
+                            continue;
+                        }
+
+                        // If we have seen the decimal, but no significant
+                        // digits yet, then we account for leading zeros by
+                        // decrementing the digits.decimalAt into negative
+                        // values.
+                        --digits.decimalAt;
+                    } else {
+                        ++digitCount;
+                        digits.append((char)(digit + '0'));
+                    }
+                } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
+                    sawDigit = true;
+                    ++digitCount;
+                    digits.append((char)(digit + '0'));
+
+                    // Cancel out backup setting (see grouping handler below)
+                    backup = -1;
+                } else if (!isExponent && ch == decimal) {
+                    // If we're only parsing integers, or if we ALREADY saw the
+                    // decimal, then don't parse this one.
+                    if (isParseIntegerOnly() || sawDecimal) {
+                        break;
+                    }
+                    digits.decimalAt = digitCount; // Not digits.count!
+                    sawDecimal = true;
+                } else if (!isExponent && ch == grouping && isGroupingUsed()) {
+                    if (sawDecimal) {
+                        break;
+                    }
+                    // Ignore grouping characters, if we are using them, but
+                    // require that they be followed by a digit.  Otherwise
+                    // we backup and reprocess them.
+                    backup = position;
+                } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
+                             && !sawExponent) {
+                    // Process the exponent by recursively calling this method.
+                     ParsePosition pos = new ParsePosition(position + exponentString.length());
+                    boolean[] stat = new boolean[STATUS_LENGTH];
+                    DigitList exponentDigits = new DigitList();
+
+                    if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
+                        exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
+                        position = pos.index; // Advance past the exponent
+                        exponent = (int)exponentDigits.getLong();
+                        if (!stat[STATUS_POSITIVE]) {
+                            exponent = -exponent;
+                        }
+                        sawExponent = true;
+                    }
+                    break; // Whether we fail or succeed, we exit this loop
+                } else {
+                    break;
+                }
+            }
+
+            if (backup != -1) {
+                position = backup;
+            }
+
+            // If there was no decimal point we have an integer
+            if (!sawDecimal) {
+                digits.decimalAt = digitCount; // Not digits.count!
+            }
+
+            // Adjust for exponent, if any
+            digits.decimalAt += exponent;
+
+            // If none of the text string was recognized.  For example, parse
+            // "x" with pattern "#0.00" (return index and error index both 0)
+            // parse "$" with pattern "$#0.00". (return index 0 and error
+            // index 1).
+            if (!sawDigit && digitCount == 0) {
+                parsePosition.index = oldStart;
+                parsePosition.errorIndex = oldStart;
+                return false;
+            }
+        }
+
+        // check for suffix
+        if (!isExponent) {
+            if (gotPositive) {
+                gotPositive = text.regionMatches(position,positiveSuffix,0,
+                                                 positiveSuffix.length());
+            }
+            if (gotNegative) {
+                gotNegative = text.regionMatches(position,negativeSuffix,0,
+                                                 negativeSuffix.length());
+            }
+
+        // if both match, take longest
+        if (gotPositive && gotNegative) {
+            if (positiveSuffix.length() > negativeSuffix.length()) {
+                gotNegative = false;
+            } else if (positiveSuffix.length() < negativeSuffix.length()) {
+                gotPositive = false;
+            }
+        }
+
+        // fail if neither or both
+        if (gotPositive == gotNegative) {
+            parsePosition.errorIndex = position;
+            return false;
+        }
+
+        parsePosition.index = position +
+            (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
+        } else {
+            parsePosition.index = position;
+        }
+
+        status[STATUS_POSITIVE] = gotPositive;
+        if (parsePosition.index == oldStart) {
+            parsePosition.errorIndex = position;
+            return false;
+        }
+        return true;
+    }
+    */
+    // END Android-removed: Unused private helpers.
 
     /**
      * Returns a copy of the decimal format symbols, which is generally not
@@ -905,8 +2628,17 @@
      * @see java.text.DecimalFormatSymbols
      */
     public DecimalFormatSymbols getDecimalFormatSymbols() {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        try {
+            // don't allow multiple references
+            return (DecimalFormatSymbols) symbols.clone();
+        } catch (Exception foo) {
+            return null; // should never happen
+        }
+        */
         return DecimalFormatSymbols.fromIcuInstance(icuDecimalFormat.getDecimalFormatSymbols());
+        // END Android-changed: Use ICU.
     }
 
 
@@ -920,8 +2652,13 @@
         try {
             // don't allow multiple references
             symbols = (DecimalFormatSymbols) newSymbols.clone();
-            // Android-changed: Use ICU.
+            // BEGIN Android-changed: Use ICU.
+            /*
+            expandAffixes();
+            fastPathCheckNeeded = true;
+            */
             icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols());
+            // END Android-changed: Use ICU.
         } catch (Exception foo) {
             // should never happen
         }
@@ -935,6 +2672,7 @@
      */
     public String getPositivePrefix () {
         // Android-changed: Use ICU.
+        // return positivePrefix;
         return icuDecimalFormat.getPositivePrefix();
     }
 
@@ -945,20 +2683,49 @@
      * @param newValue the new positive prefix
      */
     public void setPositivePrefix (String newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        positivePrefix = newValue;
+        posPrefixPattern = null;
+        positivePrefixFieldPositions = null;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setPositivePrefix(newValue);
+        // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private helper getPositivePrefixFieldPositions().
+    // BEGIN Android-removed: private helper getPositivePrefixFieldPositions().
+    /*
+    /**
+     * Returns the FieldPositions of the fields in the prefix used for
+     * positive numbers. This is not used if the user has explicitly set
+     * a positive prefix via <code>setPositivePrefix</code>. This is
+     * lazily created.
+     *
+     * @return FieldPositions in positive prefix
+     *
+    private FieldPosition[] getPositivePrefixFieldPositions() {
+        if (positivePrefixFieldPositions == null) {
+            if (posPrefixPattern != null) {
+                positivePrefixFieldPositions = expandAffix(posPrefixPattern);
+            } else {
+                positivePrefixFieldPositions = EmptyFieldPositionArray;
+            }
+        }
+        return positivePrefixFieldPositions;
+    }
+    */
+    // END Android-removed: private helper getPositivePrefixFieldPositions().
 
     /**
-     * Get the  prefix.
+     * Get the negative prefix.
      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
      *
      * @return the negative prefix
      */
     public String getNegativePrefix () {
         // Android-changed: Use ICU.
+        // return negativePrefix;
         return icuDecimalFormat.getNegativePrefix();
     }
 
@@ -969,11 +2736,38 @@
      * @param newValue the new negative prefix
      */
     public void setNegativePrefix (String newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        negativePrefix = newValue;
+        negPrefixPattern = null;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setNegativePrefix(newValue);
+        // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private helper getNegativePrefixFieldPositions().
+    // BEGIN Android-removed: private helper getNegativePrefixFieldPositions().
+    /*
+    /**
+     * Returns the FieldPositions of the fields in the prefix used for
+     * negative numbers. This is not used if the user has explicitly set
+     * a negative prefix via <code>setNegativePrefix</code>. This is
+     * lazily created.
+     *
+     * @return FieldPositions in positive prefix
+     *
+    private FieldPosition[] getNegativePrefixFieldPositions() {
+        if (negativePrefixFieldPositions == null) {
+            if (negPrefixPattern != null) {
+                negativePrefixFieldPositions = expandAffix(negPrefixPattern);
+            } else {
+                negativePrefixFieldPositions = EmptyFieldPositionArray;
+            }
+        }
+        return negativePrefixFieldPositions;
+    }
+    */
+    // END Android-removed: private helper getNegativePrefixFieldPositions().
 
     /**
      * Get the positive suffix.
@@ -983,6 +2777,7 @@
      */
     public String getPositiveSuffix () {
         // Android-changed: Use ICU.
+        // return positiveSuffix;
         return icuDecimalFormat.getPositiveSuffix();
     }
 
@@ -993,11 +2788,38 @@
      * @param newValue the new positive suffix
      */
     public void setPositiveSuffix (String newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        positiveSuffix = newValue;
+        posSuffixPattern = null;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setPositiveSuffix(newValue);
+        // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private helper getPositiveSuffixFieldPositions().
+    // BEGIN Android-removed: private helper getPositiveSuffixFieldPositions().
+    /*
+    /**
+     * Returns the FieldPositions of the fields in the suffix used for
+     * positive numbers. This is not used if the user has explicitly set
+     * a positive suffix via <code>setPositiveSuffix</code>. This is
+     * lazily created.
+     *
+     * @return FieldPositions in positive prefix
+     *
+    private FieldPosition[] getPositiveSuffixFieldPositions() {
+        if (positiveSuffixFieldPositions == null) {
+            if (posSuffixPattern != null) {
+                positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
+            } else {
+                positiveSuffixFieldPositions = EmptyFieldPositionArray;
+            }
+        }
+        return positiveSuffixFieldPositions;
+    }
+    */
+    // END Android-removed: private helper getPositiveSuffixFieldPositions().
 
     /**
      * Get the negative suffix.
@@ -1007,6 +2829,7 @@
      */
     public String getNegativeSuffix () {
         // Android-changed: Use ICU.
+        // return negativeSuffix;
         return icuDecimalFormat.getNegativeSuffix();
     }
 
@@ -1017,11 +2840,38 @@
      * @param newValue the new negative suffix
      */
     public void setNegativeSuffix (String newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        negativeSuffix = newValue;
+        negSuffixPattern = null;
+        fastPathCheckNeeded = true;
+         */
         icuDecimalFormat.setNegativeSuffix(newValue);
+        // END Android-changed: Use ICU.
     }
 
-    // Android-removed: private helper getNegativeSuffixFieldPositions().
+    // BEGIN Android-removed: private helper getNegativeSuffixFieldPositions().
+    /*
+    /**
+     * Returns the FieldPositions of the fields in the suffix used for
+     * negative numbers. This is not used if the user has explicitly set
+     * a negative suffix via <code>setNegativeSuffix</code>. This is
+     * lazily created.
+     *
+     * @return FieldPositions in positive prefix
+     *
+    private FieldPosition[] getNegativeSuffixFieldPositions() {
+        if (negativeSuffixFieldPositions == null) {
+            if (negSuffixPattern != null) {
+                negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
+            } else {
+                negativeSuffixFieldPositions = EmptyFieldPositionArray;
+            }
+        }
+        return negativeSuffixFieldPositions;
+    }
+    */
+    // END Android-removed: private helper getNegativeSuffixFieldPositions().
 
     /**
      * Gets the multiplier for use in percent, per mille, and similar
@@ -1032,6 +2882,7 @@
      */
     public int getMultiplier () {
         // Android-changed: Use ICU.
+        // return multiplier;
         return icuDecimalFormat.getMultiplier();
     }
 
@@ -1050,7 +2901,15 @@
      * @see #getMultiplier
      */
     public void setMultiplier (int newValue) {
+        // BEGIN Android-changed: Use ICU.
+        /*
+        multiplier = newValue;
+        bigDecimalMultiplier = null;
+        bigIntegerMultiplier = null;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setMultiplier(newValue);
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -1058,10 +2917,13 @@
      */
     @Override
     public void setGroupingUsed(boolean newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        super.setGroupingUsed(newValue);
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setGroupingUsed(newValue);
-        // Android-removed: fast path related code.
-        // fastPathCheckNeeded = true;
+        // END Android-changed: Use ICU.
     }
 
     // BEGIN Android-added: isGroupingUsed() override delegating to ICU.
@@ -1086,6 +2948,7 @@
      */
     public int getGroupingSize () {
         // Android-changed: Use ICU.
+        // return groupingSize;
         return icuDecimalFormat.getGroupingSize();
     }
 
@@ -1102,10 +2965,13 @@
      * @see java.text.DecimalFormatSymbols#setGroupingSeparator
      */
     public void setGroupingSize (int newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        groupingSize = (byte)newValue;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setGroupingSize(newValue);
-        // Android-removed: fast path related code.
-        // fastPathCheckNeeded = true;
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -1118,6 +2984,7 @@
      */
     public boolean isDecimalSeparatorAlwaysShown() {
         // Android-changed: Use ICU.
+        // return decimalSeparatorAlwaysShown;
         return icuDecimalFormat.isDecimalSeparatorAlwaysShown();
     }
 
@@ -1130,8 +2997,13 @@
      *                 {@code false} otherwise
      */
     public void setDecimalSeparatorAlwaysShown(boolean newValue) {
-        // Android-changed: Use ICU.
+        // BEGIN Android-changed: Use ICU.
+        /*
+        decimalSeparatorAlwaysShown = newValue;
+        fastPathCheckNeeded = true;
+        */
         icuDecimalFormat.setDecimalSeparatorAlwaysShown(newValue);
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -1145,6 +3017,7 @@
      */
     public boolean isParseBigDecimal() {
         // Android-changed: Use ICU.
+        // return parseBigDecimal;
         return icuDecimalFormat.isParseBigDecimal();
     }
 
@@ -1159,6 +3032,7 @@
      */
     public void setParseBigDecimal(boolean newValue) {
         // Android-changed: Use ICU.
+        // parseBigDecimal = newValue;
         icuDecimalFormat.setParseBigDecimal(newValue);
     }
 
@@ -1187,6 +3061,26 @@
     @Override
     public Object clone() {
         // BEGIN Android-changed: Use ICU, remove fast path related code.
+        /*
+        DecimalFormat other = (DecimalFormat) super.clone();
+        other.symbols = (DecimalFormatSymbols) symbols.clone();
+        other.digitList = (DigitList) digitList.clone();
+
+        // Fast-path is almost stateless algorithm. The only logical state is the
+        // isFastPath flag. In addition fastPathCheckNeeded is a sentinel flag
+        // that forces recalculation of all fast-path fields when set to true.
+        //
+        // There is thus no need to clone all the fast-path fields.
+        // We just only need to set fastPathCheckNeeded to true when cloning,
+        // and init fastPathData to null as if it were a truly new instance.
+        // Every fast-path field will be recalculated (only once) at next usage of
+        // fast-path algorithm.
+        other.fastPathCheckNeeded = true;
+        other.isFastPath = false;
+        other.fastPathData = null;
+
+        return other;
+        */
         try {
             DecimalFormat other = (DecimalFormat) super.clone();
             other.icuDecimalFormat = (android.icu.text.DecimalFormat_ICU58_Android) icuDecimalFormat.clone();
@@ -1198,13 +3092,49 @@
         // END Android-changed: Use ICU, remove fast path related code.
     }
 
-    // BEGIN Android-changed: re-implement equals() using ICU fields.
     /**
      * Overrides equals
      */
     @Override
     public boolean equals(Object obj)
     {
+    // BEGIN Android-changed: re-implement equals() using ICU fields.
+        /*
+        if (obj == null)
+            return false;
+        if (!super.equals(obj))
+            return false; // super does class check
+        DecimalFormat other = (DecimalFormat) obj;
+        return ((posPrefixPattern == other.posPrefixPattern &&
+                 positivePrefix.equals(other.positivePrefix))
+                || (posPrefixPattern != null &&
+                    posPrefixPattern.equals(other.posPrefixPattern)))
+            && ((posSuffixPattern == other.posSuffixPattern &&
+                 positiveSuffix.equals(other.positiveSuffix))
+                || (posSuffixPattern != null &&
+                    posSuffixPattern.equals(other.posSuffixPattern)))
+            && ((negPrefixPattern == other.negPrefixPattern &&
+                 negativePrefix.equals(other.negativePrefix))
+                || (negPrefixPattern != null &&
+                    negPrefixPattern.equals(other.negPrefixPattern)))
+            && ((negSuffixPattern == other.negSuffixPattern &&
+                 negativeSuffix.equals(other.negativeSuffix))
+                || (negSuffixPattern != null &&
+                    negSuffixPattern.equals(other.negSuffixPattern)))
+            && multiplier == other.multiplier
+            && groupingSize == other.groupingSize
+            && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
+            && parseBigDecimal == other.parseBigDecimal
+            && useExponentialNotation == other.useExponentialNotation
+            && (!useExponentialNotation ||
+                minExponentDigits == other.minExponentDigits)
+            && maximumIntegerDigits == other.maximumIntegerDigits
+            && minimumIntegerDigits == other.minimumIntegerDigits
+            && maximumFractionDigits == other.maximumFractionDigits
+            && minimumFractionDigits == other.minimumFractionDigits
+            && roundingMode == other.roundingMode
+            && symbols.equals(other.symbols);
+        */
         if (obj == null) {
             return false;
         }
@@ -1235,6 +3165,7 @@
     @Override
     public int hashCode() {
         // Android-changed: use getPositivePrefix() instead of positivePrefix field.
+        // return super.hashCode() * 37 + positivePrefix.hashCode();
         return super.hashCode() * 37 + getPositivePrefix().hashCode();
         // just enough fields for a reasonable distribution
     }
@@ -1248,6 +3179,7 @@
      */
     public String toPattern() {
         // Android-changed: use ICU.
+        // return toPattern( false );
         return icuDecimalFormat.toPattern();
     }
 
@@ -1260,10 +3192,325 @@
      */
     public String toLocalizedPattern() {
         // Android-changed: use ICU.
+        // return toPattern( true );
         return icuDecimalFormat.toLocalizedPattern();
     }
 
-    // Android-removed: private helper methods expandAffixes(), expandAffix(), toPattern(boolean).
+    // BEGIN Android-removed: Unused private helpers.
+    /*
+    /**
+     * Expand the affix pattern strings into the expanded affix strings.  If any
+     * affix pattern string is null, do not expand it.  This method should be
+     * called any time the symbols or the affix patterns change in order to keep
+     * the expanded affix strings up to date.
+     *
+    private void expandAffixes() {
+        // Reuse one StringBuffer for better performance
+        StringBuffer buffer = new StringBuffer();
+        if (posPrefixPattern != null) {
+            positivePrefix = expandAffix(posPrefixPattern, buffer);
+            positivePrefixFieldPositions = null;
+        }
+        if (posSuffixPattern != null) {
+            positiveSuffix = expandAffix(posSuffixPattern, buffer);
+            positiveSuffixFieldPositions = null;
+        }
+        if (negPrefixPattern != null) {
+            negativePrefix = expandAffix(negPrefixPattern, buffer);
+            negativePrefixFieldPositions = null;
+        }
+        if (negSuffixPattern != null) {
+            negativeSuffix = expandAffix(negSuffixPattern, buffer);
+            negativeSuffixFieldPositions = null;
+        }
+    }
+
+    /**
+     * Expand an affix pattern into an affix string.  All characters in the
+     * pattern are literal unless prefixed by QUOTE.  The following characters
+     * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
+     * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
+     * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
+     * currency code.  Any other character after a QUOTE represents itself.
+     * QUOTE must be followed by another character; QUOTE may not occur by
+     * itself at the end of the pattern.
+     *
+     * @param pattern the non-null, possibly empty pattern
+     * @param buffer a scratch StringBuffer; its contents will be lost
+     * @return the expanded equivalent of pattern
+     *
+    private String expandAffix(String pattern, StringBuffer buffer) {
+        buffer.setLength(0);
+        for (int i=0; i<pattern.length(); ) {
+            char c = pattern.charAt(i++);
+            if (c == QUOTE) {
+                c = pattern.charAt(i++);
+                switch (c) {
+                case CURRENCY_SIGN:
+                    if (i<pattern.length() &&
+                        pattern.charAt(i) == CURRENCY_SIGN) {
+                        ++i;
+                        buffer.append(symbols.getInternationalCurrencySymbol());
+                    } else {
+                        buffer.append(symbols.getCurrencySymbol());
+                    }
+                    continue;
+                case PATTERN_PERCENT:
+                    c = symbols.getPercent();
+                    break;
+                case PATTERN_PER_MILLE:
+                    c = symbols.getPerMill();
+                    break;
+                case PATTERN_MINUS:
+                    c = symbols.getMinusSign();
+                    break;
+                }
+            }
+            buffer.append(c);
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Expand an affix pattern into an array of FieldPositions describing
+     * how the pattern would be expanded.
+     * All characters in the
+     * pattern are literal unless prefixed by QUOTE.  The following characters
+     * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
+     * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
+     * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
+     * currency code.  Any other character after a QUOTE represents itself.
+     * QUOTE must be followed by another character; QUOTE may not occur by
+     * itself at the end of the pattern.
+     *
+     * @param pattern the non-null, possibly empty pattern
+     * @return FieldPosition array of the resulting fields.
+     *
+    private FieldPosition[] expandAffix(String pattern) {
+        ArrayList<FieldPosition> positions = null;
+        int stringIndex = 0;
+        for (int i=0; i<pattern.length(); ) {
+            char c = pattern.charAt(i++);
+            if (c == QUOTE) {
+                int field = -1;
+                Format.Field fieldID = null;
+                c = pattern.charAt(i++);
+                switch (c) {
+                case CURRENCY_SIGN:
+                    String string;
+                    if (i<pattern.length() &&
+                        pattern.charAt(i) == CURRENCY_SIGN) {
+                        ++i;
+                        string = symbols.getInternationalCurrencySymbol();
+                    } else {
+                        string = symbols.getCurrencySymbol();
+                    }
+                    if (string.length() > 0) {
+                        if (positions == null) {
+                            positions = new ArrayList<>(2);
+                        }
+                        FieldPosition fp = new FieldPosition(Field.CURRENCY);
+                        fp.setBeginIndex(stringIndex);
+                        fp.setEndIndex(stringIndex + string.length());
+                        positions.add(fp);
+                        stringIndex += string.length();
+                    }
+                    continue;
+                case PATTERN_PERCENT:
+                    c = symbols.getPercent();
+                    field = -1;
+                    fieldID = Field.PERCENT;
+                    break;
+                case PATTERN_PER_MILLE:
+                    c = symbols.getPerMill();
+                    field = -1;
+                    fieldID = Field.PERMILLE;
+                    break;
+                case PATTERN_MINUS:
+                    c = symbols.getMinusSign();
+                    field = -1;
+                    fieldID = Field.SIGN;
+                    break;
+                }
+                if (fieldID != null) {
+                    if (positions == null) {
+                        positions = new ArrayList<>(2);
+                    }
+                    FieldPosition fp = new FieldPosition(fieldID, field);
+                    fp.setBeginIndex(stringIndex);
+                    fp.setEndIndex(stringIndex + 1);
+                    positions.add(fp);
+                }
+            }
+            stringIndex++;
+        }
+        if (positions != null) {
+            return positions.toArray(EmptyFieldPositionArray);
+        }
+        return EmptyFieldPositionArray;
+    }
+
+    /**
+     * Appends an affix pattern to the given StringBuffer, quoting special
+     * characters as needed.  Uses the internal affix pattern, if that exists,
+     * or the literal affix, if the internal affix pattern is null.  The
+     * appended string will generate the same affix pattern (or literal affix)
+     * when passed to toPattern().
+     *
+     * @param buffer the affix string is appended to this
+     * @param affixPattern a pattern such as posPrefixPattern; may be null
+     * @param expAffix a corresponding expanded affix, such as positivePrefix.
+     * Ignored unless affixPattern is null.  If affixPattern is null, then
+     * expAffix is appended as a literal affix.
+     * @param localized true if the appended pattern should contain localized
+     * pattern characters; otherwise, non-localized pattern chars are appended
+     *
+    private void appendAffix(StringBuffer buffer, String affixPattern,
+                             String expAffix, boolean localized) {
+        if (affixPattern == null) {
+            appendAffix(buffer, expAffix, localized);
+        } else {
+            int i;
+            for (int pos=0; pos<affixPattern.length(); pos=i) {
+                i = affixPattern.indexOf(QUOTE, pos);
+                if (i < 0) {
+                    appendAffix(buffer, affixPattern.substring(pos), localized);
+                    break;
+                }
+                if (i > pos) {
+                    appendAffix(buffer, affixPattern.substring(pos, i), localized);
+                }
+                char c = affixPattern.charAt(++i);
+                ++i;
+                if (c == QUOTE) {
+                    buffer.append(c);
+                    // Fall through and append another QUOTE below
+                } else if (c == CURRENCY_SIGN &&
+                           i<affixPattern.length() &&
+                           affixPattern.charAt(i) == CURRENCY_SIGN) {
+                    ++i;
+                    buffer.append(c);
+                    // Fall through and append another CURRENCY_SIGN below
+                } else if (localized) {
+                    switch (c) {
+                    case PATTERN_PERCENT:
+                        c = symbols.getPercent();
+                        break;
+                    case PATTERN_PER_MILLE:
+                        c = symbols.getPerMill();
+                        break;
+                    case PATTERN_MINUS:
+                        c = symbols.getMinusSign();
+                        break;
+                    }
+                }
+                buffer.append(c);
+            }
+        }
+    }
+
+    /**
+     * Append an affix to the given StringBuffer, using quotes if
+     * there are special characters.  Single quotes themselves must be
+     * escaped in either case.
+     *
+    private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
+        boolean needQuote;
+        if (localized) {
+            needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
+                || affix.indexOf(symbols.getGroupingSeparator()) >= 0
+                || affix.indexOf(symbols.getDecimalSeparator()) >= 0
+                || affix.indexOf(symbols.getPercent()) >= 0
+                || affix.indexOf(symbols.getPerMill()) >= 0
+                || affix.indexOf(symbols.getDigit()) >= 0
+                || affix.indexOf(symbols.getPatternSeparator()) >= 0
+                || affix.indexOf(symbols.getMinusSign()) >= 0
+                || affix.indexOf(CURRENCY_SIGN) >= 0;
+        } else {
+            needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
+                || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
+                || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
+                || affix.indexOf(PATTERN_PERCENT) >= 0
+                || affix.indexOf(PATTERN_PER_MILLE) >= 0
+                || affix.indexOf(PATTERN_DIGIT) >= 0
+                || affix.indexOf(PATTERN_SEPARATOR) >= 0
+                || affix.indexOf(PATTERN_MINUS) >= 0
+                || affix.indexOf(CURRENCY_SIGN) >= 0;
+        }
+        if (needQuote) buffer.append('\'');
+        if (affix.indexOf('\'') < 0) buffer.append(affix);
+        else {
+            for (int j=0; j<affix.length(); ++j) {
+                char c = affix.charAt(j);
+                buffer.append(c);
+                if (c == '\'') buffer.append(c);
+            }
+        }
+        if (needQuote) buffer.append('\'');
+    }
+
+    /**
+     * Does the real work of generating a pattern.  *
+    private String toPattern(boolean localized) {
+        StringBuffer result = new StringBuffer();
+        for (int j = 1; j >= 0; --j) {
+            if (j == 1)
+                appendAffix(result, posPrefixPattern, positivePrefix, localized);
+            else appendAffix(result, negPrefixPattern, negativePrefix, localized);
+            int i;
+            int digitCount = useExponentialNotation
+                        ? getMaximumIntegerDigits()
+                        : Math.max(groupingSize, getMinimumIntegerDigits())+1;
+            for (i = digitCount; i > 0; --i) {
+                if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
+                    i % groupingSize == 0) {
+                    result.append(localized ? symbols.getGroupingSeparator() :
+                                  PATTERN_GROUPING_SEPARATOR);
+                }
+                result.append(i <= getMinimumIntegerDigits()
+                    ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
+                    : (localized ? symbols.getDigit() : PATTERN_DIGIT));
+            }
+            if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
+                result.append(localized ? symbols.getDecimalSeparator() :
+                              PATTERN_DECIMAL_SEPARATOR);
+            for (i = 0; i < getMaximumFractionDigits(); ++i) {
+                if (i < getMinimumFractionDigits()) {
+                    result.append(localized ? symbols.getZeroDigit() :
+                                  PATTERN_ZERO_DIGIT);
+                } else {
+                    result.append(localized ? symbols.getDigit() :
+                                  PATTERN_DIGIT);
+                }
+            }
+        if (useExponentialNotation)
+        {
+            result.append(localized ? symbols.getExponentSeparator() :
+                  PATTERN_EXPONENT);
+        for (i=0; i<minExponentDigits; ++i)
+                    result.append(localized ? symbols.getZeroDigit() :
+                                  PATTERN_ZERO_DIGIT);
+        }
+            if (j == 1) {
+                appendAffix(result, posSuffixPattern, positiveSuffix, localized);
+                if ((negSuffixPattern == posSuffixPattern && // n == p == null
+                     negativeSuffix.equals(positiveSuffix))
+                    || (negSuffixPattern != null &&
+                        negSuffixPattern.equals(posSuffixPattern))) {
+                    if ((negPrefixPattern != null && posPrefixPattern != null &&
+                         negPrefixPattern.equals("'-" + posPrefixPattern)) ||
+                        (negPrefixPattern == posPrefixPattern && // n == p == null
+                         negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
+                        break;
+                }
+                result.append(localized ? symbols.getPatternSeparator() :
+                              PATTERN_SEPARATOR);
+            } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
+        }
+        return result.toString();
+    }
+    */
+    // END Android-removed: Unused private helpers.
 
     /**
      * Apply the given pattern to this Format object.  A pattern is a
@@ -1289,6 +3536,7 @@
      */
     public void applyPattern(String pattern) {
         // Android-changed: use ICU.
+        // applyPattern(pattern, false);
         icuDecimalFormat.applyPattern(pattern);
         updateFieldsFromIcu();
     }
@@ -1318,11 +3566,348 @@
      */
     public void applyLocalizedPattern(String pattern) {
         // Android-changed: use ICU.
+        // applyPattern(pattern, true);
         icuDecimalFormat.applyLocalizedPattern(pattern);
         updateFieldsFromIcu();
     }
 
-    // Android-removed: applyPattern(String, boolean) as apply[Localized]Pattern calls ICU directly.
+    // BEGIN Android-removed: applyPattern(String, boolean) as apply[Localized]Pattern calls ICU directly.
+    /*
+    /**
+     * Does the real work of applying a pattern.
+     *
+    private void applyPattern(String pattern, boolean localized) {
+        char zeroDigit         = PATTERN_ZERO_DIGIT;
+        char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
+        char decimalSeparator  = PATTERN_DECIMAL_SEPARATOR;
+        char percent           = PATTERN_PERCENT;
+        char perMill           = PATTERN_PER_MILLE;
+        char digit             = PATTERN_DIGIT;
+        char separator         = PATTERN_SEPARATOR;
+        String exponent          = PATTERN_EXPONENT;
+        char minus             = PATTERN_MINUS;
+        if (localized) {
+            zeroDigit         = symbols.getZeroDigit();
+            groupingSeparator = symbols.getGroupingSeparator();
+            decimalSeparator  = symbols.getDecimalSeparator();
+            percent           = symbols.getPercent();
+            perMill           = symbols.getPerMill();
+            digit             = symbols.getDigit();
+            separator         = symbols.getPatternSeparator();
+            exponent          = symbols.getExponentSeparator();
+            minus             = symbols.getMinusSign();
+        }
+        boolean gotNegative = false;
+        decimalSeparatorAlwaysShown = false;
+        isCurrencyFormat = false;
+        useExponentialNotation = false;
+
+        // Two variables are used to record the subrange of the pattern
+        // occupied by phase 1.  This is used during the processing of the
+        // second pattern (the one representing negative numbers) to ensure
+        // that no deviation exists in phase 1 between the two patterns.
+        int phaseOneStart = 0;
+        int phaseOneLength = 0;
+
+        int start = 0;
+        for (int j = 1; j >= 0 && start < pattern.length(); --j) {
+            boolean inQuote = false;
+            StringBuffer prefix = new StringBuffer();
+            StringBuffer suffix = new StringBuffer();
+            int decimalPos = -1;
+            int multiplier = 1;
+            int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
+            byte groupingCount = -1;
+
+            // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
+            // the section of the pattern with digits, decimal separator,
+            // grouping characters.  Phase 2 is the suffix.  In phases 0 and 2,
+            // percent, per mille, and currency symbols are recognized and
+            // translated.  The separation of the characters into phases is
+            // strictly enforced; if phase 1 characters are to appear in the
+            // suffix, for example, they must be quoted.
+            int phase = 0;
+
+            // The affix is either the prefix or the suffix.
+            StringBuffer affix = prefix;
+
+            for (int pos = start; pos < pattern.length(); ++pos) {
+                char ch = pattern.charAt(pos);
+                switch (phase) {
+                case 0:
+                case 2:
+                    // Process the prefix / suffix characters
+                    if (inQuote) {
+                        // A quote within quotes indicates either the closing
+                        // quote or two quotes, which is a quote literal. That
+                        // is, we have the second quote in 'do' or 'don''t'.
+                        if (ch == QUOTE) {
+                            if ((pos+1) < pattern.length() &&
+                                pattern.charAt(pos+1) == QUOTE) {
+                                ++pos;
+                                affix.append("''"); // 'don''t'
+                            } else {
+                                inQuote = false; // 'do'
+                            }
+                            continue;
+                        }
+                    } else {
+                        // Process unquoted characters seen in prefix or suffix
+                        // phase.
+                        if (ch == digit ||
+                            ch == zeroDigit ||
+                            ch == groupingSeparator ||
+                            ch == decimalSeparator) {
+                            phase = 1;
+                            if (j == 1) {
+                                phaseOneStart = pos;
+                            }
+                            --pos; // Reprocess this character
+                            continue;
+                        } else if (ch == CURRENCY_SIGN) {
+                            // Use lookahead to determine if the currency sign
+                            // is doubled or not.
+                            boolean doubled = (pos + 1) < pattern.length() &&
+                                pattern.charAt(pos + 1) == CURRENCY_SIGN;
+                            if (doubled) { // Skip over the doubled character
+                             ++pos;
+                            }
+                            isCurrencyFormat = true;
+                            affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
+                            continue;
+                        } else if (ch == QUOTE) {
+                            // A quote outside quotes indicates either the
+                            // opening quote or two quotes, which is a quote
+                            // literal. That is, we have the first quote in 'do'
+                            // or o''clock.
+                            if (ch == QUOTE) {
+                                if ((pos+1) < pattern.length() &&
+                                    pattern.charAt(pos+1) == QUOTE) {
+                                    ++pos;
+                                    affix.append("''"); // o''clock
+                                } else {
+                                    inQuote = true; // 'do'
+                                }
+                                continue;
+                            }
+                        } else if (ch == separator) {
+                            // Don't allow separators before we see digit
+                            // characters of phase 1, and don't allow separators
+                            // in the second pattern (j == 0).
+                            if (phase == 0 || j == 0) {
+                                throw new IllegalArgumentException("Unquoted special character '" +
+                                    ch + "' in pattern \"" + pattern + '"');
+                            }
+                            start = pos + 1;
+                            pos = pattern.length();
+                            continue;
+                        }
+
+                        // Next handle characters which are appended directly.
+                        else if (ch == percent) {
+                            if (multiplier != 1) {
+                                throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
+                                    pattern + '"');
+                            }
+                            multiplier = 100;
+                            affix.append("'%");
+                            continue;
+                        } else if (ch == perMill) {
+                            if (multiplier != 1) {
+                                throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
+                                    pattern + '"');
+                            }
+                            multiplier = 1000;
+                            affix.append("'\u2030");
+                            continue;
+                        } else if (ch == minus) {
+                            affix.append("'-");
+                            continue;
+                        }
+                    }
+                    // Note that if we are within quotes, or if this is an
+                    // unquoted, non-special character, then we usually fall
+                    // through to here.
+                    affix.append(ch);
+                    break;
+
+                case 1:
+                    // Phase one must be identical in the two sub-patterns. We
+                    // enforce this by doing a direct comparison. While
+                    // processing the first sub-pattern, we just record its
+                    // length. While processing the second, we compare
+                    // characters.
+                    if (j == 1) {
+                        ++phaseOneLength;
+                    } else {
+                        if (--phaseOneLength == 0) {
+                            phase = 2;
+                            affix = suffix;
+                        }
+                        continue;
+                    }
+
+                    // Process the digits, decimal, and grouping characters. We
+                    // record five pieces of information. We expect the digits
+                    // to occur in the pattern ####0000.####, and we record the
+                    // number of left digits, zero (central) digits, and right
+                    // digits. The position of the last grouping character is
+                    // recorded (should be somewhere within the first two blocks
+                    // of characters), as is the position of the decimal point,
+                    // if any (should be in the zero digits). If there is no
+                    // decimal point, then there should be no right digits.
+                    if (ch == digit) {
+                        if (zeroDigitCount > 0) {
+                            ++digitRightCount;
+                        } else {
+                            ++digitLeftCount;
+                        }
+                        if (groupingCount >= 0 && decimalPos < 0) {
+                            ++groupingCount;
+                        }
+                    } else if (ch == zeroDigit) {
+                        if (digitRightCount > 0) {
+                            throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
+                                pattern + '"');
+                        }
+                        ++zeroDigitCount;
+                        if (groupingCount >= 0 && decimalPos < 0) {
+                            ++groupingCount;
+                        }
+                    } else if (ch == groupingSeparator) {
+                        groupingCount = 0;
+                    } else if (ch == decimalSeparator) {
+                        if (decimalPos >= 0) {
+                            throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
+                                pattern + '"');
+                        }
+                        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
+                    } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
+                        if (useExponentialNotation) {
+                            throw new IllegalArgumentException("Multiple exponential " +
+                                "symbols in pattern \"" + pattern + '"');
+                        }
+                        useExponentialNotation = true;
+                        minExponentDigits = 0;
+
+                        // Use lookahead to parse out the exponential part
+                        // of the pattern, then jump into phase 2.
+                        pos = pos+exponent.length();
+                         while (pos < pattern.length() &&
+                               pattern.charAt(pos) == zeroDigit) {
+                            ++minExponentDigits;
+                            ++phaseOneLength;
+                            ++pos;
+                        }
+
+                        if ((digitLeftCount + zeroDigitCount) < 1 ||
+                            minExponentDigits < 1) {
+                            throw new IllegalArgumentException("Malformed exponential " +
+                                "pattern \"" + pattern + '"');
+                        }
+
+                        // Transition to phase 2
+                        phase = 2;
+                        affix = suffix;
+                        --pos;
+                        continue;
+                    } else {
+                        phase = 2;
+                        affix = suffix;
+                        --pos;
+                        --phaseOneLength;
+                        continue;
+                    }
+                    break;
+                }
+            }
+
+            // Handle patterns with no '0' pattern character. These patterns
+            // are legal, but must be interpreted.  "##.###" -> "#0.###".
+            // ".###" -> ".0##".
+            /* We allow patterns of the form "####" to produce a zeroDigitCount
+             * of zero (got that?); although this seems like it might make it
+             * possible for format() to produce empty strings, format() checks
+             * for this condition and outputs a zero digit in this situation.
+             * Having a zeroDigitCount of zero yields a minimum integer digits
+             * of zero, which allows proper round-trip patterns.  That is, we
+             * don't want "#" to become "#0" when toPattern() is called (even
+             * though that's what it really is, semantically).
+             *
+            if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
+                // Handle "###.###" and "###." and ".###"
+                int n = decimalPos;
+                if (n == 0) { // Handle ".###"
+                    ++n;
+                }
+                digitRightCount = digitLeftCount - n;
+                digitLeftCount = n - 1;
+                zeroDigitCount = 1;
+            }
+
+            // Do syntax checking on the digits.
+            if ((decimalPos < 0 && digitRightCount > 0) ||
+                (decimalPos >= 0 && (decimalPos < digitLeftCount ||
+                 decimalPos > (digitLeftCount + zeroDigitCount))) ||
+                 groupingCount == 0 || inQuote) {
+                throw new IllegalArgumentException("Malformed pattern \"" +
+                    pattern + '"');
+            }
+
+            if (j == 1) {
+                posPrefixPattern = prefix.toString();
+                posSuffixPattern = suffix.toString();
+                negPrefixPattern = posPrefixPattern;   // assume these for now
+                negSuffixPattern = posSuffixPattern;
+                int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
+                /* The effectiveDecimalPos is the position the decimal is at or
+                 * would be at if there is no decimal. Note that if decimalPos<0,
+                 * then digitTotalCount == digitLeftCount + zeroDigitCount.
+                 *
+                int effectiveDecimalPos = decimalPos >= 0 ?
+                    decimalPos : digitTotalCount;
+                setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
+                setMaximumIntegerDigits(useExponentialNotation ?
+                    digitLeftCount + getMinimumIntegerDigits() :
+                    MAXIMUM_INTEGER_DIGITS);
+                setMaximumFractionDigits(decimalPos >= 0 ?
+                    (digitTotalCount - decimalPos) : 0);
+                setMinimumFractionDigits(decimalPos >= 0 ?
+                    (digitLeftCount + zeroDigitCount - decimalPos) : 0);
+                setGroupingUsed(groupingCount > 0);
+                this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
+                this.multiplier = multiplier;
+                setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
+                    decimalPos == digitTotalCount);
+            } else {
+                negPrefixPattern = prefix.toString();
+                negSuffixPattern = suffix.toString();
+                gotNegative = true;
+            }
+        }
+
+        if (pattern.length() == 0) {
+            posPrefixPattern = posSuffixPattern = "";
+            setMinimumIntegerDigits(0);
+            setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
+            setMinimumFractionDigits(0);
+            setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
+        }
+
+        // If there was no negative pattern, or if the negative pattern is
+        // identical to the positive pattern, then prepend the minus sign to
+        // the positive pattern to form the negative pattern.
+        if (!gotNegative ||
+            (negPrefixPattern.equals(posPrefixPattern)
+             && negSuffixPattern.equals(posSuffixPattern))) {
+            negSuffixPattern = posSuffixPattern;
+            negPrefixPattern = "'-" + posPrefixPattern;
+        }
+
+        expandAffixes();
+    }
+    */
+    // END Android-removed: applyPattern(String, boolean) as apply[Localized]Pattern calls ICU directly.
 
     /**
      * Sets the maximum number of digits allowed in the integer portion of a
@@ -1342,7 +3927,7 @@
             super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
                 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
         }
-        // Android-changed: use ICU.
+        // Android-added: use ICU.
         icuDecimalFormat.setMaximumIntegerDigits(getMaximumIntegerDigits());
         // Android-removed: fast path related code.
         // fastPathCheckNeeded = true;
@@ -1366,7 +3951,7 @@
             super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
                 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
         }
-        // Android-changed: use ICU.
+        // Android-added: use ICU.
         icuDecimalFormat.setMinimumIntegerDigits(getMinimumIntegerDigits());
         // Android-removed: fast path related code.
         // fastPathCheckNeeded = true;
@@ -1390,7 +3975,7 @@
             super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
                 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
         }
-        // Android-changed: use ICU.
+        // Android-added: use ICU.
         icuDecimalFormat.setMaximumFractionDigits(getMaximumFractionDigits());
         // Android-removed: fast path related code.
         // fastPathCheckNeeded = true;
@@ -1414,7 +3999,7 @@
             super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
                 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
         }
-        // Android-changed: use ICU.
+        // Android-added: use ICU.
         icuDecimalFormat.setMinimumFractionDigits(getMinimumFractionDigits());
         // Android-removed: fast path related code.
         // fastPathCheckNeeded = true;
@@ -1504,6 +4089,14 @@
         // BEGIN Android-changed: use ICU.
         // Set the international currency symbol, and currency symbol on the DecimalFormatSymbols
         // object and tell ICU to use that.
+        /*
+        if (currency != symbols.getCurrency()) {
+            symbols.setCurrency(currency);
+            if (isCurrencyFormat) {
+                expandAffixes();
+            }
+        }
+        */
         if (currency != symbols.getCurrency()
             || !currency.getSymbol().equals(symbols.getCurrencySymbol())) {
             symbols.setCurrency(currency);
@@ -1530,7 +4123,7 @@
         return roundingMode;
     }
 
-    // Android-added: convertRoundingMode() to convert between Java and ICU RoundingMode enums.
+    // BEGIN Android-added: convertRoundingMode() to convert between Java and ICU RoundingMode enums.
     private static int convertRoundingMode(RoundingMode rm) {
         switch (rm) {
         case UP:
@@ -1552,6 +4145,7 @@
         }
         throw new IllegalArgumentException("Invalid rounding mode specified");
     }
+    // END Android-added: convertRoundingMode() to convert between Java and ICU RoundingMode enums.
 
     /**
      * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
@@ -1569,12 +4163,13 @@
 
         this.roundingMode = roundingMode;
         // Android-changed: use ICU.
+        // digitList.setRoundingMode(roundingMode);
         icuDecimalFormat.setRoundingMode(convertRoundingMode(roundingMode));
         // Android-removed: fast path related code.
         // fastPathCheckNeeded = true;
     }
 
-    // BEGIN Android-added: 7u40 version of adjustForCurrencyDefaultFractionDigits().
+    // BEGIN Android-added: Upstream code from OpenJDK 7u40 release.
     // This method was removed in OpenJDK 8 in favor of doing equivalent work in the provider. Since
     // Android removed support for providers for NumberFormat we keep this method around as an
     // "Android addition".
@@ -1606,7 +4201,7 @@
             }
         }
     }
-    // END Android-added: Upstream code from earlier OpenJDK release.
+    // END Android-added: Upstream code from OpenJDK 7u40 release.
 
     // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
     // the fields list to be serialized
@@ -1661,7 +4256,7 @@
         fields.put("serialVersionOnStream", currentSerialVersion);
         stream.writeFields();
     }
-    // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
+    // END Android-added: Custom serialization code for compatibility with RI serialization.
 
     /**
      * Reads the default serializable fields from the stream and performs
@@ -1706,9 +4301,44 @@
      * literal values.  This is exactly what we want, since that corresponds to
      * the pre-version-2 behavior.
      */
-    // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
     private void readObject(ObjectInputStream stream)
-            throws IOException, ClassNotFoundException {
+         throws IOException, ClassNotFoundException {
+        // BEGIN Android-changed: Custom serialization code for compatibility with RI serialization.
+        /*
+        stream.defaultReadObject();
+        digitList = new DigitList();
+
+        // We force complete fast-path reinitialization when the instance is
+        // deserialized. See clone() comment on fastPathCheckNeeded.
+        fastPathCheckNeeded = true;
+        isFastPath = false;
+        fastPathData = null;
+
+        if (serialVersionOnStream < 4) {
+            setRoundingMode(RoundingMode.HALF_EVEN);
+        } else {
+            setRoundingMode(getRoundingMode());
+        }
+
+        // We only need to check the maximum counts because NumberFormat
+        // .readObject has already ensured that the maximum is greater than the
+        // minimum count.
+        if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
+            super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
+            throw new InvalidObjectException("Digit count out of range");
+        }
+        if (serialVersionOnStream < 3) {
+            setMaximumIntegerDigits(super.getMaximumIntegerDigits());
+            setMinimumIntegerDigits(super.getMinimumIntegerDigits());
+            setMaximumFractionDigits(super.getMaximumFractionDigits());
+            setMinimumFractionDigits(super.getMinimumFractionDigits());
+        }
+        if (serialVersionOnStream < 1) {
+            // Didn't have exponential fields
+            useExponentialNotation = false;
+        }
+        serialVersionOnStream = currentSerialVersion;
+        */
         ObjectInputStream.GetField fields = stream.readFields();
         this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
 
@@ -1800,14 +4430,146 @@
             setMaximumFractionDigits(super.getMaximumFractionDigits());
             setMinimumFractionDigits(super.getMinimumFractionDigits());
         }
+        // END Android-changed: Custom serialization code for compatibility with RI serialization.
     }
-    // END Android-added: Custom serialization code for compatibility with RI serialization.
 
     //----------------------------------------------------------------------
     // INSTANCE VARIABLES
     //----------------------------------------------------------------------
 
-    // Android-removed: various fields now stored in icuDecimalFormat.
+    // BEGIN Android-removed: various fields now stored in icuDecimalFormat.
+    /*
+    private transient DigitList digitList = new DigitList();
+
+    /**
+     * The symbol used as a prefix when formatting positive numbers, e.g. "+".
+     *
+     * @serial
+     * @see #getPositivePrefix
+     *
+    private String  positivePrefix = "";
+
+    /**
+     * The symbol used as a suffix when formatting positive numbers.
+     * This is often an empty string.
+     *
+     * @serial
+     * @see #getPositiveSuffix
+     *
+    private String  positiveSuffix = "";
+
+    /**
+     * The symbol used as a prefix when formatting negative numbers, e.g. "-".
+     *
+     * @serial
+     * @see #getNegativePrefix
+     *
+    private String  negativePrefix = "-";
+
+    /**
+     * The symbol used as a suffix when formatting negative numbers.
+     * This is often an empty string.
+     *
+     * @serial
+     * @see #getNegativeSuffix
+     *
+    private String  negativeSuffix = "";
+
+    /**
+     * The prefix pattern for non-negative numbers.  This variable corresponds
+     * to <code>positivePrefix</code>.
+     *
+     * <p>This pattern is expanded by the method <code>expandAffix()</code> to
+     * <code>positivePrefix</code> to update the latter to reflect changes in
+     * <code>symbols</code>.  If this variable is <code>null</code> then
+     * <code>positivePrefix</code> is taken as a literal value that does not
+     * change when <code>symbols</code> changes.  This variable is always
+     * <code>null</code> for <code>DecimalFormat</code> objects older than
+     * stream version 2 restored from stream.
+     *
+     * @serial
+     * @since 1.3
+     *
+    private String posPrefixPattern;
+
+    /**
+     * The suffix pattern for non-negative numbers.  This variable corresponds
+     * to <code>positiveSuffix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     * @since 1.3
+     *
+    private String posSuffixPattern;
+
+    /**
+     * The prefix pattern for negative numbers.  This variable corresponds
+     * to <code>negativePrefix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     * @since 1.3
+     *
+    private String negPrefixPattern;
+
+    /**
+     * The suffix pattern for negative numbers.  This variable corresponds
+     * to <code>negativeSuffix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     * @since 1.3
+     *
+    private String negSuffixPattern;
+
+    /**
+     * The multiplier for use in percent, per mille, etc.
+     *
+     * @serial
+     * @see #getMultiplier
+     *
+    private int     multiplier = 1;
+
+    /**
+     * The number of digits between grouping separators in the integer
+     * portion of a number.  Must be greater than 0 if
+     * <code>NumberFormat.groupingUsed</code> is true.
+     *
+     * @serial
+     * @see #getGroupingSize
+     * @see java.text.NumberFormat#isGroupingUsed
+     *
+    private byte    groupingSize = 3;  // invariant, > 0 if useThousands
+
+    /**
+     * If true, forces the decimal separator to always appear in a formatted
+     * number, even if the fractional part of the number is zero.
+     *
+     * @serial
+     * @see #isDecimalSeparatorAlwaysShown
+     *
+    private boolean decimalSeparatorAlwaysShown = false;
+
+    /**
+     * If true, parse returns BigDecimal wherever possible.
+     *
+     * @serial
+     * @see #isParseBigDecimal
+     * @since 1.5
+     *
+    private boolean parseBigDecimal = false;
+
+
+    /**
+     * True if this object represents a currency format.  This determines
+     * whether the monetary decimal separator is used instead of the normal one.
+     *
+    private transient boolean isCurrencyFormat = false;
+    */
+    // END Android-removed: various fields now stored in icuDecimalFormat.
 
     /**
      * The <code>DecimalFormatSymbols</code> object used by this format.
@@ -1820,7 +4582,58 @@
      */
     private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
 
-    // Android-removed: useExponentialNotation, *FieldPositions, minExponentDigits.
+    // BEGIN Android-removed: useExponentialNotation, *FieldPositions, minExponentDigits.
+    /*
+    /**
+     * True to force the use of exponential (i.e. scientific) notation when formatting
+     * numbers.
+     *
+     * @serial
+     * @since 1.2
+     *
+    private boolean useExponentialNotation;  // Newly persistent in the Java 2 platform v.1.2
+
+    /**
+     * FieldPositions describing the positive prefix String. This is
+     * lazily created. Use <code>getPositivePrefixFieldPositions</code>
+     * when needed.
+     *
+    private transient FieldPosition[] positivePrefixFieldPositions;
+
+    /**
+     * FieldPositions describing the positive suffix String. This is
+     * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
+     * when needed.
+     *
+    private transient FieldPosition[] positiveSuffixFieldPositions;
+
+    /**
+     * FieldPositions describing the negative prefix String. This is
+     * lazily created. Use <code>getNegativePrefixFieldPositions</code>
+     * when needed.
+     *
+    private transient FieldPosition[] negativePrefixFieldPositions;
+
+    /**
+     * FieldPositions describing the negative suffix String. This is
+     * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
+     * when needed.
+     *
+    private transient FieldPosition[] negativeSuffixFieldPositions;
+
+    /**
+     * The minimum number of digits used to display the exponent when a number is
+     * formatted in exponential notation.  This field is ignored if
+     * <code>useExponentialNotation</code> is not true.
+     *
+     * @serial
+     * @since 1.2
+     *
+    private byte    minExponentDigits;       // Newly persistent in the Java 2 platform v.1.2
+
+
+    */
+    // END Android-removed: useExponentialNotation, *FieldPositions, minExponentDigits.
 
     /**
      * The maximum number of digits allowed in the integer portion of a
@@ -1832,7 +4645,7 @@
      * @see #getMaximumIntegerDigits
      * @since 1.5
      */
-    // Android-changed: removed initialisation.
+    // Android-changed: removed initialization.
     private int    maximumIntegerDigits /* = super.getMaximumIntegerDigits() */;
 
     /**
@@ -1845,7 +4658,7 @@
      * @see #getMinimumIntegerDigits
      * @since 1.5
      */
-    // Android-changed: removed initialisation.
+    // Android-changed: removed initialization.
     private int    minimumIntegerDigits /* = super.getMinimumIntegerDigits() */;
 
     /**
@@ -1858,7 +4671,7 @@
      * @see #getMaximumFractionDigits
      * @since 1.5
      */
-    // Android-changed: removed initialisation.
+    // Android-changed: removed initialization.
     private int    maximumFractionDigits /* = super.getMaximumFractionDigits() */;
 
     /**
@@ -1871,7 +4684,7 @@
      * @see #getMinimumFractionDigits
      * @since 1.5
      */
-    // Android-changed: removed initialisation.
+    // Android-changed: removed initialization.
     private int    minimumFractionDigits /* = super.getMinimumFractionDigits() */;
 
     /**
@@ -1882,19 +4695,194 @@
      */
     private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
 
-    // Android-removed: FastPathData, isFastPath, fastPathCheckNeeded and fastPathData.
+    // BEGIN Android-removed: FastPathData, isFastPath, fastPathCheckNeeded and fastPathData.
+    /*
+    // ------ DecimalFormat fields for fast-path for double algorithm  ------
+
+    /**
+     * Helper inner utility class for storing the data used in the fast-path
+     * algorithm. Almost all fields related to fast-path are encapsulated in
+     * this class.
+     *
+     * Any {@code DecimalFormat} instance has a {@code fastPathData}
+     * reference field that is null unless both the properties of the instance
+     * are such that the instance is in the "fast-path" state, and a format call
+     * has been done at least once while in this state.
+     *
+     * Almost all fields are related to the "fast-path" state only and don't
+     * change until one of the instance properties is changed.
+     *
+     * {@code firstUsedIndex} and {@code lastFreeIndex} are the only
+     * two fields that are used and modified while inside a call to
+     * {@code fastDoubleFormat}.
+     *
+     *
+    private static class FastPathData {
+        // --- Temporary fields used in fast-path, shared by several methods.
+
+        /** The first unused index at the end of the formatted result. *
+        int lastFreeIndex;
+
+        /** The first used index at the beginning of the formatted result *
+        int firstUsedIndex;
+
+        // --- State fields related to fast-path status. Changes due to a
+        //     property change only. Set by checkAndSetFastPathStatus() only.
+
+        /** Difference between locale zero and default zero representation. *
+        int  zeroDelta;
+
+        /** Locale char for grouping separator. *
+        char groupingChar;
+
+        /**  Fixed index position of last integral digit of formatted result *
+        int integralLastIndex;
+
+        /**  Fixed index position of first fractional digit of formatted result *
+        int fractionalFirstIndex;
+
+        /** Fractional constants depending on decimal|currency state *
+        double fractionalScaleFactor;
+        int fractionalMaxIntBound;
+
+
+        /** The char array buffer that will contain the formatted result *
+        char[] fastPathContainer;
+
+        /** Suffixes recorded as char array for efficiency. *
+        char[] charsPositivePrefix;
+        char[] charsNegativePrefix;
+        char[] charsPositiveSuffix;
+        char[] charsNegativeSuffix;
+        boolean positiveAffixesRequired = true;
+        boolean negativeAffixesRequired = true;
+    }
+
+    /** The format fast-path status of the instance. Logical state. *
+    private transient boolean isFastPath = false;
+
+    /** Flag stating need of check and reinit fast-path status on next format call. *
+    private transient boolean fastPathCheckNeeded = true;
+
+    /** DecimalFormat reference to its FastPathData *
+    private transient FastPathData fastPathData;
+    */
+    // END Android-removed: FastPathData, isFastPath, fastPathCheckNeeded and fastPathData.
 
     //----------------------------------------------------------------------
 
     static final int currentSerialVersion = 4;
 
-    // Android-removed: serialVersionOnStream.
+    // BEGIN Android-removed: serialVersionOnStream.
+
+    /**
+     * The internal serial version which says which version was written.
+     * Possible values are:
+     * <ul>
+     * <li><b>0</b> (default): versions before the Java 2 platform v1.2
+     * <li><b>1</b>: version for 1.2, which includes the two new fields
+     *      <code>useExponentialNotation</code> and
+     *      <code>minExponentDigits</code>.
+     * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
+     *      <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
+     *      <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
+     * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
+     *      <code>maximumIntegerDigits</code>,
+     *      <code>minimumIntegerDigits</code>,
+     *      <code>maximumFractionDigits</code>,
+     *      <code>minimumFractionDigits</code>, and
+     *      <code>parseBigDecimal</code>.
+     * <li><b>4</b>: version for 1.6 and later, which adds one new field:
+     *      <code>roundingMode</code>.
+     * </ul>
+     * @since 1.2
+     * @serial
+     *
+    private int serialVersionOnStream = currentSerialVersion;
+    */
+    // END Android-removed: serialVersionOnStream.
 
     //----------------------------------------------------------------------
     // CONSTANTS
     //----------------------------------------------------------------------
 
-    // Android-removed: Fast-Path for double Constants, various constants.
+    // BEGIN Android-removed: Fast-Path for double Constants, various constants.
+    /*
+    // ------ Fast-Path for double Constants ------
+
+    /** Maximum valid integer value for applying fast-path algorithm *
+    private static final double MAX_INT_AS_DOUBLE = (double) Integer.MAX_VALUE;
+
+    /**
+     * The digit arrays used in the fast-path methods for collecting digits.
+     * Using 3 constants arrays of chars ensures a very fast collection of digits
+     *
+    private static class DigitArrays {
+        static final char[] DigitOnes1000 = new char[1000];
+        static final char[] DigitTens1000 = new char[1000];
+        static final char[] DigitHundreds1000 = new char[1000];
+
+        // initialize on demand holder class idiom for arrays of digits
+        static {
+            int tenIndex = 0;
+            int hundredIndex = 0;
+            char digitOne = '0';
+            char digitTen = '0';
+            char digitHundred = '0';
+            for (int i = 0;  i < 1000; i++ ) {
+
+                DigitOnes1000[i] = digitOne;
+                if (digitOne == '9')
+                    digitOne = '0';
+                else
+                    digitOne++;
+
+                DigitTens1000[i] = digitTen;
+                if (i == (tenIndex + 9)) {
+                    tenIndex += 10;
+                    if (digitTen == '9')
+                        digitTen = '0';
+                    else
+                        digitTen++;
+                }
+
+                DigitHundreds1000[i] = digitHundred;
+                if (i == (hundredIndex + 99)) {
+                    digitHundred++;
+                    hundredIndex += 100;
+                }
+            }
+        }
+    }
+    // ------ Fast-Path for double Constants end ------
+
+    // Constants for characters used in programmatic (unlocalized) patterns.
+    private static final char       PATTERN_ZERO_DIGIT         = '0';
+    private static final char       PATTERN_GROUPING_SEPARATOR = ',';
+    private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';
+    private static final char       PATTERN_PER_MILLE          = '\u2030';
+    private static final char       PATTERN_PERCENT            = '%';
+    private static final char       PATTERN_DIGIT              = '#';
+    private static final char       PATTERN_SEPARATOR          = ';';
+    private static final String     PATTERN_EXPONENT           = "E";
+    private static final char       PATTERN_MINUS              = '-';
+
+    /**
+     * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
+     * is used in patterns and substituted with either the currency symbol,
+     * or if it is doubled, with the international currency symbol.  If the
+     * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
+     * replaced with the monetary decimal separator.
+     *
+     * The CURRENCY_SIGN is not localized.
+     *
+    private static final char       CURRENCY_SIGN = '\u00A4';
+
+    private static final char       QUOTE = '\'';
+
+    private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
+    */
+    // END Android-removed: Fast-Path for double Constants, various constants.
 
     // Upper limit on integer and fraction digits for a Java double
     static final int DOUBLE_INTEGER_DIGITS  = 309;
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/text/RuleBasedCollator.java b/ojluni/src/main/java/java/text/RuleBasedCollator.java
index 3f3c5bc0..a3234c8 100644
--- a/ojluni/src/main/java/java/text/RuleBasedCollator.java
+++ b/ojluni/src/main/java/java/text/RuleBasedCollator.java
@@ -298,7 +298,7 @@
              */
             throw new ParseException(e.getMessage(), -1);
         }
-        // BEGIN Android-changed: Switched to ICU.
+        // END Android-changed: Switched to ICU.
     }
 
     // Android-removed: (String rules, int decomp) constructor and copy constructor.
diff --git a/ojluni/src/main/java/java/text/SimpleDateFormat.java b/ojluni/src/main/java/java/text/SimpleDateFormat.java
index d8e2d90a..0f6321a 100644
--- a/ojluni/src/main/java/java/text/SimpleDateFormat.java
+++ b/ojluni/src/main/java/java/text/SimpleDateFormat.java
@@ -137,6 +137,12 @@
  *         <td><code>July</code>; <code>Jul</code>; <code>07</code>
  *         <td>1+</td>
  *     <tr>
+ *         <td><code>L</code>
+ *         <td>Month in year (standalone form)
+ *         <td><a href="#month">Month</a>
+ *         <td><code>July</code>; <code>Jul</code>; <code>07</code>
+ *         <td>TBD</td>
+ *     <tr style="background-color: rgb(238, 238, 255);">
  *         <td><code>w</code>
  *         <td>Week in year
  *         <td><a href="#number">Number</a>
@@ -304,7 +310,17 @@
  * <li><strong><a name="month">Month:</a></strong>
  *     If the number of pattern letters is 3 or more, the month is
  *     interpreted as <a href="#text">text</a>; otherwise,
- *     it is interpreted as a <a href="#number">number</a>.</li>
+ *     it is interpreted as a <a href="#number">number</a>.
+ *     <ul>
+ *     <li>Letter <em>M</em> produces context-sensitive month names, such as the
+ *         embedded form of names. If a {@code DateFormatSymbols} has been set
+ *         explicitly with constructor {@link #SimpleDateFormat(String,
+ *         DateFormatSymbols)} or method {@link
+ *         #setDateFormatSymbols(DateFormatSymbols)}, the month names given by
+ *         the {@code DateFormatSymbols} are used.</li>
+ *     <li>Letter <em>L</em> produces the standalone form of month names.</li>
+ *     </ul>
+ *     <br></li>
  * <li><strong><a name="timezone">General time zone:</a></strong>
  *     Time zones are interpreted as <a href="#text">text</a> if they have
  *     names. For time zones representing a GMT offset value, the
@@ -491,6 +507,18 @@
      */
     transient private boolean hasFollowingMinusSign = false;
 
+    // BEGIN Android-removed: App compat for formatting pattern letter M.
+    // OpenJDK forces the standalone form of month when patterns contain pattern M only.
+    // This feature is not incorporated for app compatibility and because the feature is
+    // not documented in OpenJDK or Android.
+    /*
+    /**
+     * True if standalone form needs to be used.
+     *
+    transient private boolean forceStandaloneForm = false;
+    */
+    // END Android-removed: App compat for formatting pattern letter M.
+
     /**
      * The compiled pattern.
      */
@@ -575,11 +603,14 @@
      * class.
      */
     public SimpleDateFormat() {
-        // Android-changed: Android has no LocaleProviderAdapter. Use ICU locale data.
-        // this("", Locale.getDefault(Locale.Category.FORMAT));
-        // applyPatternImpl(LocaleProviderAdapter.getResourceBundleBased().getLocaleResources(locale)
-        //                  .getDateTimePattern(SHORT, SHORT, calendar));
+        // BEGIN Android-changed: Android has no LocaleProviderAdapter. Use ICU locale data.
+        /*
+        this("", Locale.getDefault(Locale.Category.FORMAT));
+        applyPatternImpl(LocaleProviderAdapter.getResourceBundleBased().getLocaleResources(locale)
+                         .getDateTimePattern(SHORT, SHORT, calendar));
+        */
         this(SHORT, SHORT, Locale.getDefault(Locale.Category.FORMAT));
+        // END Android-changed: Android has no LocaleProviderAdapter. Use ICU locale data.
     }
 
     // BEGIN Android-added: Ctor used by DateFormat to remove use of LocaleProviderAdapter.
@@ -780,8 +811,15 @@
         boolean inQuote = false;
         StringBuilder compiledCode = new StringBuilder(length * 2);
         StringBuilder tmpBuffer = null;
+        // BEGIN Android-removed: App compat for formatting pattern letter M.
+        // See forceStandaloneForm field
+        /*
+        int count = 0, tagcount = 0;
+        int lastTag = -1, prevTag = -1;
+        */
         int count = 0;
         int lastTag = -1;
+        // END Android-removed: App compat for formatting pattern letter M.
 
         for (int i = 0; i < length; i++) {
             char c = pattern.charAt(i);
@@ -795,6 +833,13 @@
                         i++;
                         if (count != 0) {
                             encode(lastTag, count, compiledCode);
+                            // BEGIN Android-removed: App compat for formatting pattern letter M.
+                            // See forceStandaloneForm field
+                            /*
+                            tagcount++;
+                            prevTag = lastTag;
+                            */
+                            // END Android-removed: App compat for formatting pattern letter M.
                             lastTag = -1;
                             count = 0;
                         }
@@ -809,6 +854,13 @@
                 if (!inQuote) {
                     if (count != 0) {
                         encode(lastTag, count, compiledCode);
+                        // BEGIN Android-removed: App compat for formatting pattern letter M.
+                        // See forceStandaloneForm field
+                        /*
+                        tagcount++;
+                        prevTag = lastTag;
+                        */
+                        // END Android-removed: App compat for formatting pattern letter M.
                         lastTag = -1;
                         count = 0;
                     }
@@ -843,6 +895,13 @@
             if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
                 if (count != 0) {
                     encode(lastTag, count, compiledCode);
+                    // BEGIN Android-removed: App compat for formatting pattern letter M.
+                    // See forceStandaloneForm field
+                    /*
+                    tagcount++;
+                    prevTag = lastTag;
+                    */
+                    // END Android-removed: App compat for formatting pattern letter M.
                     lastTag = -1;
                     count = 0;
                 }
@@ -879,6 +938,13 @@
                 continue;
             }
             encode(lastTag, count, compiledCode);
+            // BEGIN Android-removed: App compat for formatting pattern letter M.
+            // See forceStandaloneForm field
+            /*
+            tagcount++;
+            prevTag = lastTag;
+            */
+            // END Android-removed: App compat for formatting pattern letter M.
             lastTag = tag;
             count = 1;
         }
@@ -889,8 +955,19 @@
 
         if (count != 0) {
             encode(lastTag, count, compiledCode);
+            // BEGIN Android-removed: App compat for formatting pattern letter M.
+            // See forceStandaloneForm field
+            /*
+            tagcount++;
+            prevTag = lastTag;
+            */
+            // END Android-removed: App compat for formatting pattern letter M.
         }
 
+        // Android-removed: App compat for formatting pattern letter M.
+        // See forceStandaloneForm field
+        // forceStandaloneForm = (tagcount == 1 && prevTag == PATTERN_MONTH);
+
         // Copy the compiled pattern to a char array
         int len = compiledCode.length();
         char[] r = new char[len];
@@ -1216,18 +1293,62 @@
             }
             break;
 
-        case PATTERN_MONTH: // 'M'
+        case PATTERN_MONTH:            // 'M' (context seinsive)
+            // BEGIN Android-changed: formatMonth() method to format using ICU data.
+            /*
             if (useDateFormatSymbols) {
-                current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols,
-                        false /* standalone */);
+                String[] months;
+                if (count >= 4) {
+                    months = formatData.getMonths();
+                    current = months[value];
+                } else if (count == 3) {
+                    months = formatData.getShortMonths();
+                    current = months[value];
+                }
+            } else {
+                if (count < 3) {
+                    current = null;
+                } else if (forceStandaloneForm) {
+                    current = calendar.getDisplayName(field, style | 0x8000, locale);
+                    if (current == null) {
+                        current = calendar.getDisplayName(field, style, locale);
+                    }
+                }
             }
+            if (current == null) {
+                zeroPaddingNumber(value+1, count, maxIntCount, buffer);
+            }
+            */
+            current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols,
+                false /* standalone */, field, style);
+            // END Android-changed: formatMonth() method to format using ICU data.
             break;
 
         case PATTERN_MONTH_STANDALONE: // 'L'
-            if (useDateFormatSymbols) {
-                current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols,
-                        true /* standalone */);
+            // BEGIN Android-changed: formatMonth() method to format using ICU data.
+            /*
+            assert current == null;
+            if (locale == null) {
+                String[] months;
+                if (count >= 4) {
+                    months = formatData.getMonths();
+                    current = months[value];
+                } else if (count == 3) {
+                    months = formatData.getShortMonths();
+                    current = months[value];
+                }
+            } else {
+                if (count >= 3) {
+                    current = calendar.getDisplayName(field, style | 0x8000, locale);
+                }
             }
+            if (current == null) {
+                zeroPaddingNumber(value+1, count, maxIntCount, buffer);
+            }
+            */
+            current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols,
+                   true /* standalone */, field, style);
+            // END Android-changed: formatMonth() method to format using ICU data.
             break;
 
         case PATTERN_HOUR_OF_DAY1: // 'k' 1-based.  eg, 23:59 + 1 hour =>> 24:59
@@ -1242,16 +1363,29 @@
             break;
 
         case PATTERN_DAY_OF_WEEK: // 'E'
+            // BEGIN Android-removed: App compat for formatting pattern letter M.
+            // See forceStandaloneForm field
+            /*
+            if (useDateFormatSymbols) {
+                String[] weekdays;
+                if (count >= 4) {
+                    weekdays = formatData.getWeekdays();
+                    current = weekdays[value];
+                } else { // count < 4, use abbreviated form if exists
+                    weekdays = formatData.getShortWeekdays();
+                    current = weekdays[value];
+                }
+            }
+            */
             if (current == null) {
-                // Android-changed: extract formatWeekday() method.
                 current = formatWeekday(count, value, useDateFormatSymbols, false /* standalone */);
             }
+            // END Android-removed: App compat for formatting pattern letter M.
             break;
 
         // BEGIN Android-added: support for 'c' (standalone day of week).
         case PATTERN_STANDALONE_DAY_OF_WEEK: // 'c'
             if (current == null) {
-                // Android-changed: extract formatWeekday() method.
                 current = formatWeekday(count, value, useDateFormatSymbols, true /* standalone */);
             }
             break;
@@ -1284,7 +1418,31 @@
 
         case PATTERN_ZONE_NAME: // 'z'
             if (current == null) {
-                // BEGIN Android-changed: format time zone name using ICU.
+                // BEGIN Android-changed: Format time zone name using ICU.
+                /*
+                if (formatData.locale == null || formatData.isZoneStringsSet) {
+                    int zoneIndex =
+                        formatData.getZoneIndex(calendar.getTimeZone().getID());
+                    if (zoneIndex == -1) {
+                        value = calendar.get(Calendar.ZONE_OFFSET) +
+                            calendar.get(Calendar.DST_OFFSET);
+                        buffer.append(ZoneInfoFile.toCustomID(value));
+                    } else {
+                        int index = (calendar.get(Calendar.DST_OFFSET) == 0) ? 1: 3;
+                        if (count < 4) {
+                            // Use the short name
+                            index++;
+                        }
+                        String[][] zoneStrings = formatData.getZoneStringsWrapper();
+                        buffer.append(zoneStrings[zoneIndex][index]);
+                    }
+                } else {
+                    TimeZone tz = calendar.getTimeZone();
+                    boolean daylight = (calendar.get(Calendar.DST_OFFSET) != 0);
+                    int tzstyle = (count < 4 ? TimeZone.SHORT : TimeZone.LONG);
+                    buffer.append(tz.getDisplayName(daylight, tzstyle, formatData.locale));
+                }
+                */
                 TimeZone tz = calendar.getTimeZone();
                 boolean daylight = (calendar.get(Calendar.DST_OFFSET) != 0);
                 String zoneString;
@@ -1316,21 +1474,33 @@
                         calendar.get(Calendar.DST_OFFSET);
                     buffer.append(TimeZone.createGmtOffsetString(true, true, offsetMillis));
                 }
-                // END Android-changed: format time zone name using ICU.
+                // END Android-changed: Format time zone name using ICU.
             }
             break;
 
         case PATTERN_ZONE_VALUE: // 'Z' ("-/+hhmm" form)
-        // BEGIN Android-changed: use shared code in TimeZone for zone offset string.
-        {
+            // BEGIN Android-changed: Use shared code in TimeZone for zone offset string.
+            /*
+            value = (calendar.get(Calendar.ZONE_OFFSET) +
+                     calendar.get(Calendar.DST_OFFSET)) / 60000;
+
+            int width = 4;
+            if (value >= 0) {
+                buffer.append('+');
+            } else {
+                width++;
+            }
+
+            int num = (value / 60) * 100 + (value % 60);
+            CalendarUtils.sprintf0d(buffer, num, width);
+            */
             value = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
             final boolean includeSeparator = (count >= 4);
             final boolean includeGmt = (count == 4);
             buffer.append(TimeZone.createGmtOffsetString(includeGmt, includeSeparator, value));
 
             break;
-        }
-        // END Android-changed: use shared code in TimeZone for zone offset string.
+            // END Android-changed: Use shared code in TimeZone for zone offset string.
 
         case PATTERN_ISO_ZONE:   // 'X'
             value = calendar.get(Calendar.ZONE_OFFSET)
@@ -1402,7 +1572,7 @@
         delegate.formatted(fieldID, f, f, beginOffset, buffer.length(), buffer);
     }
 
-    // BEGIN Android-added: formatWeekday and formatMonth methods to format using ICU data.
+    // BEGIN Android-added: formatWeekday() and formatMonth() methods to format using ICU data.
     private String formatWeekday(int count, int value, boolean useDateFormatSymbols,
                                  boolean standalone) {
         if (useDateFormatSymbols) {
@@ -1424,7 +1594,8 @@
     }
 
     private String formatMonth(int count, int value, int maxIntCount, StringBuffer buffer,
-                               boolean useDateFormatSymbols, boolean standalone) {
+                               boolean useDateFormatSymbols, boolean standalone,
+                               int field, int style) {
         String current = null;
         if (useDateFormatSymbols) {
             final String[] months;
@@ -1444,6 +1615,11 @@
         } else {
             if (count < 3) {
                 current = null;
+            } else {
+                if (standalone) {
+                    style = Calendar.toStandaloneStyle(style);
+                }
+                current = calendar.getDisplayName(field, style, locale);
             }
         }
 
@@ -1453,7 +1629,7 @@
 
         return current;
     }
-    // END Android-added: formatWeekday and formatMonth methods to format using ICU data.
+    // END Android-added: formatWeekday() and formatMonth() methods to format using ICU data.
 
     /**
      * Formats a number with the specified minimum and maximum number of digits.
@@ -1735,6 +1911,22 @@
     private int matchString(String text, int start, int field,
                             Map<String,Integer> data, CalendarBuilder calb) {
         if (data != null) {
+            // BEGIN Android-removed: SortedMap instance lookup optimization in matchString().
+            // RI returns not the longest match as matchString(String[]) does. http://b/119913354
+            /*
+            // TODO: make this default when it's in the spec.
+            if (data instanceof SortedMap) {
+                for (String name : data.keySet()) {
+                    if (text.regionMatches(true, start, name, 0, name.length())) {
+                        calb.set(field, data.get(name));
+                        return start + name.length();
+                    }
+                }
+                return -start;
+            }
+            */
+            // END Android-removed: SortedMap instance lookup optimization in matchString().
+
             String bestMatch = null;
 
             for (String name : data.keySet()) {
@@ -1767,7 +1959,20 @@
         return -1;
     }
 
-    // Android-removed: unused private method matchDSTString.
+    // BEGIN Android-removed: Unused private method matchDSTString.
+    /*
+    private boolean matchDSTString(String text, int start, int zoneIndex, int standardIndex,
+                                   String[][] zoneStrings) {
+        int index = standardIndex + 2;
+        String zoneName  = zoneStrings[zoneIndex][index];
+        if (text.regionMatches(true, start,
+                               zoneName, 0, zoneName.length())) {
+            return true;
+        }
+        return false;
+    }
+    */
+    // END Android-removed: Unused private method matchDSTString.
 
     // BEGIN Android-changed: Parse time zone strings using ICU TimeZoneNames.
     // Note that this change falls back to the upstream zone names parsing code if the zoneStrings
@@ -1962,12 +2167,12 @@
      * @param start the character position to start parsing
      * @param sign  1: positive; -1: negative
      * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's
-     * @param colonRequired true - colon required between hh and mm; false - no colon required
+     * @param colon true - colon required between hh and mm; false - no colon required
      * @param calb  a CalendarBuilder in which the parsed value is stored
      * @return updated parsed position, or its negative value to indicate a parsing error
      */
     private int subParseNumericZone(String text, int start, int sign, int count,
-                                    boolean colonRequired, CalendarBuilder calb) {
+                                    boolean colon, CalendarBuilder calb) {
         int index = start;
 
       parse:
@@ -1983,6 +2188,15 @@
             if (isDigit(c)) {
                 hours = hours * 10 + (c - '0');
             } else {
+                // BEGIN Android-removed: Be more tolerant of colon. b/26426526
+                /*
+                // If no colon in RFC 822 or 'X' (ISO), two digits are
+                // required.
+                if (count > 0 || !colon) {
+                    break parse;
+                }
+                */
+                // END Android-removed: Be more tolerant of colon. b/26426526
                 --index;
             }
             if (hours > 23) {
@@ -1992,21 +2206,27 @@
             if (count != 1) {
                 // Proceed with parsing mm
                 c = text.charAt(index++);
-                // BEGIN Android-changed: Intentional change in behavior from OpenJDK.
+                // BEGIN Android-changed: Be more tolerant of colon. b/26426526
                 // OpenJDK will return an error code if a : is found and colonRequired is false,
                 // this will return an error code if a : is not found and colonRequired is true.
                 //
-                // colonRequired | c == ':' | OpenJDK | this
+                //   colon       | c == ':' | OpenJDK | this
                 //   false       |  false   |   ok    |  ok
                 //   false       |  true    |  error  |  ok
                 //   true        |  false   |   ok    | error
                 //   true        |  true    |   ok    |  ok
+                /*
+                if (colon) {
+                    if (c != ':') {
+                        break parse;
+                    }
+                */
                 if (c == ':') {
                     c = text.charAt(index++);
-                } else if (colonRequired) {
+                } else if (colon) {
                     break parse;
                 }
-                // END Android-changed: Intentional change in behavior from OpenJDK.
+                // END Android-changed: Be more tolerant of colon. b/26426526
                 if (!isDigit(c)) {
                     break parse;
                 }
@@ -2077,6 +2297,8 @@
             }
             ++pos.index;
         }
+        // Remember the actual start index
+        int actualStart = pos.index;
 
       parsing:
         {
@@ -2127,9 +2349,7 @@
                         return index;
                     }
                 } else {
-                    Map<String, Integer> map = calendar.getDisplayNames(field,
-                                                                        Calendar.ALL_STYLES,
-                                                                        locale);
+                    Map<String, Integer> map = getDisplayNamesMap(field, locale);
                     if ((index = matchString(text, start, field, map, calb)) > 0) {
                         return index;
                     }
@@ -2158,9 +2378,9 @@
                 // we made adjustments to place the 2-digit year in the proper
                 // century, for parsed strings from "00" to "99".  Any other string
                 // is treated literally:  "2250", "-1", "1", "002".
-                if (count <= 2 && (pos.index - start) == 2
-                    && Character.isDigit(text.charAt(start))
-                    && Character.isDigit(text.charAt(start+1))) {
+                if (count <= 2 && (pos.index - actualStart) == 2
+                    && Character.isDigit(text.charAt(actualStart))
+                    && Character.isDigit(text.charAt(actualStart + 1))) {
                     // Assume for example that the defaultCenturyStart is 6/18/1903.
                     // This means that two-digit years will be forced into the range
                     // 6/18/1903 to 6/17/2003.  As a result, years 00, 01, and 02
@@ -2179,6 +2399,37 @@
 
             case PATTERN_MONTH: // 'M'
             // BEGIN Android-changed: extract parseMonth method.
+            /*
+                if (count <= 2) // i.e., M or MM.
+                {
+                    // Don't want to parse the month if it is a string
+                    // while pattern uses numeric style: M or MM.
+                    // [We computed 'value' above.]
+                    calb.set(Calendar.MONTH, value - 1);
+                    return pos.index;
+                }
+
+                if (useDateFormatSymbols) {
+                    // count >= 3 // i.e., MMM or MMMM
+                    // Want to be able to parse both short and long forms.
+                    // Try count == 4 first:
+                    int newStart;
+                    if ((newStart = matchString(text, start, Calendar.MONTH,
+                                                formatData.getMonths(), calb)) > 0) {
+                        return newStart;
+                    }
+                    // count == 4 failed, now try count == 3
+                    if ((index = matchString(text, start, Calendar.MONTH,
+                                             formatData.getShortMonths(), calb)) > 0) {
+                        return index;
+                    }
+                } else {
+                    Map<String, Integer> map = getDisplayNamesMap(field, locale);
+                    if ((index = matchString(text, start, field, map, calb)) > 0) {
+                        return index;
+                    }
+                }
+            */
             {
                 final int idx = parseMonth(text, count, value, start, field, pos,
                         useDateFormatSymbols, false /* isStandalone */, calb);
@@ -2216,6 +2467,32 @@
 
             case PATTERN_DAY_OF_WEEK:  // 'E'
             // BEGIN Android-changed: extract parseWeekday method.
+            /*
+                {
+                    if (useDateFormatSymbols) {
+                        // Want to be able to parse both short and long forms.
+                        // Try count == 4 (DDDD) first:
+                        int newStart;
+                        if ((newStart=matchString(text, start, Calendar.DAY_OF_WEEK,
+                                                  formatData.getWeekdays(), calb)) > 0) {
+                            return newStart;
+                        }
+                        // DDDD failed, now try DDD
+                        if ((index = matchString(text, start, Calendar.DAY_OF_WEEK,
+                                                 formatData.getShortWeekdays(), calb)) > 0) {
+                            return index;
+                        }
+                    } else {
+                        int[] styles = { Calendar.LONG, Calendar.SHORT };
+                        for (int style : styles) {
+                            Map<String,Integer> map = calendar.getDisplayNames(field, style, locale);
+                            if ((index = matchString(text, start, field, map, calb)) > 0) {
+                                return index;
+                            }
+                        }
+                    }
+                }
+            */
             {
                 final int idx = parseWeekday(text, start, field, useDateFormatSymbols,
                         false /* standalone */, calb);
@@ -2246,7 +2523,7 @@
                         return index;
                     }
                 } else {
-                    Map<String,Integer> map = calendar.getDisplayNames(field, Calendar.ALL_STYLES, locale);
+                    Map<String,Integer> map = getDisplayNamesMap(field, locale);
                     if ((index = matchString(text, start, field, map, calb)) > 0) {
                         return index;
                     }
@@ -2299,10 +2576,17 @@
                                         .set(Calendar.DST_OFFSET, 0);
                                     return pos.index;
                                 }
-                                // Android-changed: tolerate colon in zone offset.
+
+                                // BEGIN Android-changed: Be more tolerant of colon. b/26426526
+                                /*
+                                // Parse the rest as "hh:mm"
+                                int i = subParseNumericZone(text, ++pos.index,
+                                                            sign, 0, true, calb);
+                                */
                                 // Parse the rest as "hh[:]?mm"
                                 int i = subParseNumericZone(text, ++pos.index, sign, 0,
                                         false, calb);
+                                // END Android-changed: Be more tolerant of colon. b/26426526
                                 if (i > 0) {
                                     return i;
                                 }
@@ -2317,10 +2601,16 @@
                                 pos.index = -i;
                             }
                         } else {
-                            // Android-changed: tolerate colon in zone offset.
+                            // BEGIN Android-changed: Be more tolerant of colon. b/26426526
                             // Parse the rest as "hh[:]?mm" (RFC 822)
+                            /*
+                            // Parse the rest as "hhmm" (RFC 822)
+                            int i = subParseNumericZone(text, ++pos.index,
+                                                        sign, 0, false, calb);
+                            */
                             int i = subParseNumericZone(text, ++pos.index, sign, 0,
                                     false, calb);
+                            // END Android-changed: Be more tolerant of colon. b/26426526
                             if (i > 0) {
                                 return i;
                             }
@@ -2376,7 +2666,10 @@
          // case PATTERN_ISO_DAY_OF_WEEK:      // 'u' (pseudo field);
 
                 // Handle "generic" fields
+                // BEGIN Android-changed: Better UTS#35 conformity for fractional seconds.
+                // http://b/25863120
                 int parseStart = pos.getIndex();
+                // END Android-changed: Better UTS#35 conformity for fractional seconds.
                 if (obeyCount) {
                     if ((start+count) > text.length()) {
                         break parsing;
@@ -2387,6 +2680,9 @@
                 }
                 if (number != null) {
                     // BEGIN Android-changed: Better UTS#35 conformity for fractional seconds.
+                    /*
+                    value = number.intValue();
+                    */
                     if (patternCharIndex == PATTERN_MILLISECOND) {
                         // Fractional seconds must be treated specially. We must always
                         // normalize them to their fractional second value [0, 1) before we attempt
@@ -2457,9 +2753,7 @@
                 return index;
             }
         } else {
-            Map<String, Integer> map = calendar.getDisplayNames(field,
-                    Calendar.ALL_STYLES,
-                    locale);
+            Map<String, Integer> map = getDisplayNamesMap(field, locale);
             if ((index = matchString(text, start, field, map, out)) > 0) {
                 return index;
             }
@@ -2502,19 +2796,18 @@
     }
     // END Android-added: parseMonth and parseWeekday methods to parse using ICU data.
 
-    private final String getCalendarName() {
-        return calendar.getClass().getName();
-    }
-
+    // Android-changed: Always useDateFormatSymbols() for GregorianCalendar.
+    /**
+     * Returns true if the DateFormatSymbols has been set explicitly or locale
+     * is null or calendar is Gregorian.
+     */
     private boolean useDateFormatSymbols() {
-        if (useDateFormatSymbols) {
-            return true;
-        }
-        return isGregorianCalendar() || locale == null;
-    }
-
-    private boolean isGregorianCalendar() {
-        return "java.util.GregorianCalendar".equals(getCalendarName());
+        // Android-changed: Always useDateFormatSymbols() for GregorianCalendar.
+        // This is for app compat. http://b/66411240#comment14
+        // return useDateFormatSymbols || locale == null;
+      return useDateFormatSymbols
+          || "java.util.GregorianCalendar".equals(calendar.getClass().getName())
+          || locale == null;
     }
 
     /**
@@ -2589,6 +2882,10 @@
      */
     public void applyPattern(String pattern)
     {
+        applyPatternImpl(pattern);
+    }
+
+    private void applyPatternImpl(String pattern) {
         compiledPattern = compile(pattern);
         this.pattern = pattern;
     }
@@ -2676,6 +2973,21 @@
                 && formatData.equals(that.formatData));
     }
 
+    private static final int[] REST_OF_STYLES = {
+        Calendar.SHORT_STANDALONE, Calendar.LONG_FORMAT, Calendar.LONG_STANDALONE,
+    };
+    private Map<String, Integer> getDisplayNamesMap(int field, Locale locale) {
+        Map<String, Integer> map = calendar.getDisplayNames(field, Calendar.SHORT_FORMAT, locale);
+        // Get all SHORT and LONG styles (avoid NARROW styles).
+        for (int style : REST_OF_STYLES) {
+            Map<String, Integer> m = calendar.getDisplayNames(field, style, locale);
+            if (m != null) {
+                map.putAll(m);
+            }
+        }
+        return map;
+    }
+
     /**
      * After reading an object from the input stream, the format
      * pattern in the object is verified.
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/AbstractCollection.java b/ojluni/src/main/java/java/util/AbstractCollection.java
index 3317d9d..19c15f8 100644
--- a/ojluni/src/main/java/java/util/AbstractCollection.java
+++ b/ojluni/src/main/java/java/util/AbstractCollection.java
@@ -49,7 +49,7 @@
  * the collection being implemented admits a more efficient implementation.<p>
  *
  * This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/AbstractList.java b/ojluni/src/main/java/java/util/AbstractList.java
index 92ce04c..a156ec6 100644
--- a/ojluni/src/main/java/java/util/AbstractList.java
+++ b/ojluni/src/main/java/java/util/AbstractList.java
@@ -60,7 +60,7 @@
  * collection being implemented admits a more efficient implementation.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/AbstractMap.java b/ojluni/src/main/java/java/util/AbstractMap.java
index bdcfcc8..09c2f94 100644
--- a/ojluni/src/main/java/java/util/AbstractMap.java
+++ b/ojluni/src/main/java/java/util/AbstractMap.java
@@ -52,7 +52,7 @@
  * map being implemented admits a more efficient implementation.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <K> the type of keys maintained by this map
diff --git a/ojluni/src/main/java/java/util/AbstractSequentialList.java b/ojluni/src/main/java/java/util/AbstractSequentialList.java
index 1ee5e21..37292df 100644
--- a/ojluni/src/main/java/java/util/AbstractSequentialList.java
+++ b/ojluni/src/main/java/java/util/AbstractSequentialList.java
@@ -54,7 +54,7 @@
  * specification.<p>
  *
  * This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/AbstractSet.java b/ojluni/src/main/java/java/util/AbstractSet.java
index 66721f7..620f672 100644
--- a/ojluni/src/main/java/java/util/AbstractSet.java
+++ b/ojluni/src/main/java/java/util/AbstractSet.java
@@ -42,7 +42,7 @@
  * for <tt>equals</tt> and <tt>hashCode</tt>.<p>
  *
  * This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/ArrayDeque.java b/ojluni/src/main/java/java/util/ArrayDeque.java
index ecaf0e8..b1fb41e 100644
--- a/ojluni/src/main/java/java/util/ArrayDeque.java
+++ b/ojluni/src/main/java/java/util/ArrayDeque.java
@@ -159,6 +159,12 @@
         Object[] a = new Object[newCapacity];
         System.arraycopy(elements, p, a, 0, r);
         System.arraycopy(elements, 0, a, r, p);
+        // Android-added: Clear old array instance that's about to become eligible for GC.
+        // This ensures that array elements can be eligible for garbage collection even
+        // before the array itself is recognized as being eligible; the latter might
+        // take a while in some GC implementations, if the array instance is longer lived
+        // (its liveness rarely checked) than some of its contents.
+        Arrays.fill(elements, null);
         elements = a;
         head = 0;
         tail = n;
diff --git a/ojluni/src/main/java/java/util/ArrayList.java b/ojluni/src/main/java/java/util/ArrayList.java
index d65bf1f..02f9479 100644
--- a/ojluni/src/main/java/java/util/ArrayList.java
+++ b/ojluni/src/main/java/java/util/ArrayList.java
@@ -92,7 +92,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/Arrays.java b/ojluni/src/main/java/java/util/Arrays.java
index 72c5f93..3f7b1bc 100644
--- a/ojluni/src/main/java/java/util/Arrays.java
+++ b/ojluni/src/main/java/java/util/Arrays.java
@@ -61,7 +61,7 @@
  * a MergeSort, but it does have to be <i>stable</i>.)
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author Josh Bloch
@@ -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
 
     /**
@@ -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/Calendar.java b/ojluni/src/main/java/java/util/Calendar.java
index b846211..3a0343b 100644
--- a/ojluni/src/main/java/java/util/Calendar.java
+++ b/ojluni/src/main/java/java/util/Calendar.java
@@ -2574,7 +2574,12 @@
         return style & ~STANDALONE_MASK;
     }
 
-    private int toStandaloneStyle(int style) {
+    // BEGIN Android-changed: Make toStandaloneStyle() public to use in java.text.SimpleDateFormat
+    /**
+     * @hide
+     */
+    public static int toStandaloneStyle(int style) {
+    // END Android-changed: Make toStandaloneStyle() public to use in java.text.SimpleDateFormat
         return style | STANDALONE_MASK;
     }
 
diff --git a/ojluni/src/main/java/java/util/Collection.java b/ojluni/src/main/java/java/util/Collection.java
index e4c6b4c..279ec9e 100644
--- a/ojluni/src/main/java/java/util/Collection.java
+++ b/ojluni/src/main/java/java/util/Collection.java
@@ -112,7 +112,7 @@
  * however most current implementations do not do so.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @implSpec
diff --git a/ojluni/src/main/java/java/util/Collections.java b/ojluni/src/main/java/java/util/Collections.java
index af5237d..e7e8e72 100644
--- a/ojluni/src/main/java/java/util/Collections.java
+++ b/ojluni/src/main/java/java/util/Collections.java
@@ -70,7 +70,7 @@
  * already sorted may or may not throw <tt>UnsupportedOperationException</tt>.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
@@ -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/Comparator.java b/ojluni/src/main/java/java/util/Comparator.java
index 4447351..27cfdd5 100644
--- a/ojluni/src/main/java/java/util/Comparator.java
+++ b/ojluni/src/main/java/java/util/Comparator.java
@@ -94,7 +94,7 @@
  * an equivalence relation.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <T> the type of objects that may be compared by this comparator
diff --git a/ojluni/src/main/java/java/util/Currency.java b/ojluni/src/main/java/java/util/Currency.java
index 88606aa..94629c7 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;
+    */
+    // END Android-removed: Use ICU.
 
     /**
      * 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/EnumMap.java b/ojluni/src/main/java/java/util/EnumMap.java
index 207ce62..30a8dce 100644
--- a/ojluni/src/main/java/java/util/EnumMap.java
+++ b/ojluni/src/main/java/java/util/EnumMap.java
@@ -69,7 +69,7 @@
  * {@link HashMap} counterparts.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author Josh Bloch
diff --git a/ojluni/src/main/java/java/util/EnumSet.java b/ojluni/src/main/java/java/util/EnumSet.java
index 2443f1e..f1b0329 100644
--- a/ojluni/src/main/java/java/util/EnumSet.java
+++ b/ojluni/src/main/java/java/util/EnumSet.java
@@ -68,7 +68,7 @@
  * constant time if their argument is also an enum set.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author Josh Bloch
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index 5e9c028..0b0c095 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,
@@ -4460,14 +4461,15 @@
                     grpSep = dfs.getGroupingSeparator();
                     DecimalFormat df = (DecimalFormat) NumberFormat.getIntegerInstance(l);
                     grpSize = df.getGroupingSize();
-                    // BEGIN Android-changed: http://b/33245708
+                    // BEGIN Android-changed: Fix division by zero if group separator is not clear.
+                    // http://b/33245708
                     // Some locales have a group separator but also patterns without groups.
                     // If we do not clear the group separator in these cases a divide by zero
                     // is thrown when determining where to place the separators.
                     if (!df.isGroupingUsed() || df.getGroupingSize() == 0) {
                         grpSep = '\0';
                     }
-                    // END Android-changed: http://b/33245708.
+                    // END Android-changed: Fix division by zero if group separator is not clear.
                 }
             }
 
diff --git a/ojluni/src/main/java/java/util/HashMap.java b/ojluni/src/main/java/java/util/HashMap.java
index 08023d8..360f736 100644
--- a/ojluni/src/main/java/java/util/HashMap.java
+++ b/ojluni/src/main/java/java/util/HashMap.java
@@ -117,7 +117,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <K> the type of keys maintained by this map
diff --git a/ojluni/src/main/java/java/util/HashSet.java b/ojluni/src/main/java/java/util/HashSet.java
index ebbe43c..5805331 100644
--- a/ojluni/src/main/java/java/util/HashSet.java
+++ b/ojluni/src/main/java/java/util/HashSet.java
@@ -72,7 +72,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/Hashtable.java b/ojluni/src/main/java/java/util/Hashtable.java
index 6061290..fc163a7 100644
--- a/ojluni/src/main/java/java/util/Hashtable.java
+++ b/ojluni/src/main/java/java/util/Hashtable.java
@@ -105,7 +105,7 @@
  *
  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
  * implement the {@link Map} interface, making it a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  *
  * Java Collections Framework</a>.  Unlike the new collection
  * implementations, {@code Hashtable} is synchronized.  If a
diff --git a/ojluni/src/main/java/java/util/IdentityHashMap.java b/ojluni/src/main/java/java/util/IdentityHashMap.java
index 94dce19..1ed9d76 100644
--- a/ojluni/src/main/java/java/util/IdentityHashMap.java
+++ b/ojluni/src/main/java/java/util/IdentityHashMap.java
@@ -122,7 +122,7 @@
  * {@link HashMap} (which uses <i>chaining</i> rather than linear-probing).
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @see     System#identityHashCode(Object)
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/Iterator.java b/ojluni/src/main/java/java/util/Iterator.java
index f9826c0..02777b6 100644
--- a/ojluni/src/main/java/java/util/Iterator.java
+++ b/ojluni/src/main/java/java/util/Iterator.java
@@ -40,7 +40,7 @@
  * </ul>
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements returned by this iterator
diff --git a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
index 9bca22a..a0ee15e 100644
--- a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
+++ b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
@@ -1595,14 +1595,17 @@
             zoneOffsets = new int[2];
         }
         if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
-            // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            // BEGIN Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
             // if (tz instanceof ZoneInfo) {
             //     zoneOffset = ((ZoneInfo)tz).getOffsets(time, zoneOffsets);
-            // } else {
+            if (tz instanceof libcore.util.ZoneInfo) {
+                zoneOffset = ((libcore.util.ZoneInfo)tz).getOffsetsByUtcTime(time, zoneOffsets);
+            // END Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            } else {
                 zoneOffset = tz.getOffset(time);
                 zoneOffsets[0] = tz.getRawOffset();
                 zoneOffsets[1] = zoneOffset - zoneOffsets[0];
-            // }
+            }
         }
         if (tzMask != 0) {
             if (isFieldSet(tzMask, ZONE_OFFSET)) {
diff --git a/ojluni/src/main/java/java/util/LinkedHashMap.java b/ojluni/src/main/java/java/util/LinkedHashMap.java
index 7c8cad0..a60c7e5 100644
--- a/ojluni/src/main/java/java/util/LinkedHashMap.java
+++ b/ojluni/src/main/java/java/util/LinkedHashMap.java
@@ -146,10 +146,10 @@
  * to obtain a correctly ordered Spliterator on API level 24 and 25:
  * <ul>
  *     <li>For a Collection view {@code c = lhm.keySet()},
- *         {@code c = lhm.keySet()} or {@code c = lhm.values()}, use
+ *         {@code c = lhm.entrySet()} or {@code c = lhm.values()}, use
  *         {@code java.util.Spliterators.spliterator(c, c.spliterator().characteristics())}
  *         instead of {@code c.spliterator()}.
- *     <li>Instead of {@code lhm.stream()} or {@code lhm.parallelStream()}, use
+ *     <li>Instead of {@code c.stream()} or {@code c.parallelStream()}, use
  *         {@code java.util.stream.StreamSupport.stream(spliterator, false)}
  *         to construct a (nonparallel) {@link java.util.stream.Stream} from
  *         such a {@code Spliterator}.
@@ -158,7 +158,7 @@
  * {@code LinkedHashMap}.
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}/openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @implNote
diff --git a/ojluni/src/main/java/java/util/LinkedHashSet.java b/ojluni/src/main/java/java/util/LinkedHashSet.java
index 5d3cec9..c573d7c 100644
--- a/ojluni/src/main/java/java/util/LinkedHashSet.java
+++ b/ojluni/src/main/java/java/util/LinkedHashSet.java
@@ -100,7 +100,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/LinkedList.java b/ojluni/src/main/java/java/util/LinkedList.java
index 4920aaf..2683a90 100644
--- a/ojluni/src/main/java/java/util/LinkedList.java
+++ b/ojluni/src/main/java/java/util/LinkedList.java
@@ -70,7 +70,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/List.java b/ojluni/src/main/java/java/util/List.java
index 9cadac1..f32d9ed 100644
--- a/ojluni/src/main/java/java/util/List.java
+++ b/ojluni/src/main/java/java/util/List.java
@@ -88,7 +88,7 @@
  * interface.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements in this list
@@ -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/ListIterator.java b/ojluni/src/main/java/java/util/ListIterator.java
index b324679..85a2f25 100644
--- a/ojluni/src/main/java/java/util/ListIterator.java
+++ b/ojluni/src/main/java/java/util/ListIterator.java
@@ -46,7 +46,7 @@
  * {@link #previous()}.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @author  Josh Bloch
diff --git a/ojluni/src/main/java/java/util/Locale.java b/ojluni/src/main/java/java/util/Locale.java
index 434922a..3908fa3 100644
--- a/ojluni/src/main/java/java/util/Locale.java
+++ b/ojluni/src/main/java/java/util/Locale.java
@@ -524,6 +524,10 @@
  *     <td><a href="http://site.icu-project.org/download/60">ICU 60.2</a></td>
  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-32">CLDR 32.0.1</a></td>
  *     <td><a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a></td></tr>
+ * <tr><td>Android Q</td>
+ *     <td><a href="http://site.icu-project.org/download/63">ICU 63.1</a></td>
+ *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-34">CLDR 34</a></td>
+ *     <td><a href="http://www.unicode.org/versions/Unicode11.0.0/">Unicode 11.0</a></td></tr>
  * </table>
  *
  * <a name="default_locale"></a><h4>Be wary of the default locale</h3>
@@ -945,21 +949,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 +986,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 +1111,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 +1128,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 +1157,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 +1725,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 +1757,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 +1771,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 +1825,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 +1913,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 +1943,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 +1955,7 @@
         }
 
         return result;
-        // END Android-changed
+        // END Android-changed: Use ICU.
     }
 
     /**
@@ -1882,7 +1980,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 +2102,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 +2125,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 +2205,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 +2230,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 +2400,7 @@
         }
         return buffer.toString();
     }
-    // END Android-changed: Use ICU.
+    // END Android-changed: Documentation and behavior of getDisplay*().
 
     /**
      * Overrides Cloneable.
@@ -2203,6 +2470,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 +2479,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 +2713,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 +2765,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 +3103,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/PriorityQueue.java b/ojluni/src/main/java/java/util/PriorityQueue.java
index 98d4939..90e59d1 100644
--- a/ojluni/src/main/java/java/util/PriorityQueue.java
+++ b/ojluni/src/main/java/java/util/PriorityQueue.java
@@ -72,7 +72,7 @@
  * ({@code peek}, {@code element}, and {@code size}).
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @since 1.5
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/RandomAccess.java b/ojluni/src/main/java/java/util/RandomAccess.java
index ca89cf8..6b7e453 100644
--- a/ojluni/src/main/java/java/util/RandomAccess.java
+++ b/ojluni/src/main/java/java/util/RandomAccess.java
@@ -59,7 +59,7 @@
  * </pre>
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @since 1.4
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/Set.java b/ojluni/src/main/java/java/util/Set.java
index 56db1ef..ee22fca 100644
--- a/ojluni/src/main/java/java/util/Set.java
+++ b/ojluni/src/main/java/java/util/Set.java
@@ -64,7 +64,7 @@
  * interface.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/SortedMap.java b/ojluni/src/main/java/java/util/SortedMap.java
index 7204237..15ddba5 100644
--- a/ojluni/src/main/java/java/util/SortedMap.java
+++ b/ojluni/src/main/java/java/util/SortedMap.java
@@ -93,7 +93,7 @@
  *   SortedMap&lt;String, V&gt; sub = m.subMap(low+"\0", high);</pre>
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <K> the type of keys maintained by this map
diff --git a/ojluni/src/main/java/java/util/SortedSet.java b/ojluni/src/main/java/java/util/SortedSet.java
index 07001cb..1ba72dd 100644
--- a/ojluni/src/main/java/java/util/SortedSet.java
+++ b/ojluni/src/main/java/java/util/SortedSet.java
@@ -89,7 +89,7 @@
  *   SortedSet&lt;String&gt; sub = s.subSet(low+"\0", high);</pre>
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/TimeZone.java b/ojluni/src/main/java/java/util/TimeZone.java
index de4d4d1..61826ba 100644
--- a/ojluni/src/main/java/java/util/TimeZone.java
+++ b/ojluni/src/main/java/java/util/TimeZone.java
@@ -39,15 +39,17 @@
 
 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 libcore.timezone.ZoneInfoDB;
+
+import dalvik.system.RuntimeHooks;
 
 /**
  * <code>TimeZone</code> represents a time zone offset, and also figures out daylight
@@ -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/TreeMap.java b/ojluni/src/main/java/java/util/TreeMap.java
index f46fbb7..7603cfc 100644
--- a/ojluni/src/main/java/java/util/TreeMap.java
+++ b/ojluni/src/main/java/java/util/TreeMap.java
@@ -93,7 +93,7 @@
  * associated map using {@code put}.)
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <K> the type of keys maintained by this map
@@ -1986,7 +1986,7 @@
             // if (!inRange(fromKey, inclusive))
             if (!inRange(fromKey) && !(!toEnd && m.compare(fromKey, hi) == 0 &&
                 !hiInclusive && !inclusive))
-            // END Android-changed
+            // END Android-changed: Fix for edge cases
                 throw new IllegalArgumentException("fromKey out of range");
             return new DescendingSubMap<>(m,
                                           fromStart, lo, loInclusive,
diff --git a/ojluni/src/main/java/java/util/TreeSet.java b/ojluni/src/main/java/java/util/TreeSet.java
index c1825ca..be215ba 100644
--- a/ojluni/src/main/java/java/util/TreeSet.java
+++ b/ojluni/src/main/java/java/util/TreeSet.java
@@ -74,7 +74,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <E> the type of elements maintained by this set
diff --git a/ojluni/src/main/java/java/util/Vector.java b/ojluni/src/main/java/java/util/Vector.java
index 895430b..6c5247c 100644
--- a/ojluni/src/main/java/java/util/Vector.java
+++ b/ojluni/src/main/java/java/util/Vector.java
@@ -68,7 +68,7 @@
  *
  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
  * implement the {@link List} interface, making it a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.  Unlike the new collection
  * implementations, {@code Vector} is synchronized.  If a thread-safe
  * implementation is not needed, it is recommended to use {@link
@@ -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/WeakHashMap.java b/ojluni/src/main/java/java/util/WeakHashMap.java
index a7dfa06..d977b61 100644
--- a/ojluni/src/main/java/java/util/WeakHashMap.java
+++ b/ojluni/src/main/java/java/util/WeakHashMap.java
@@ -120,7 +120,7 @@
  * should be used only to detect bugs.</i>
  *
  * <p>This class is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @param <K> the type of keys maintained by this map
diff --git a/ojluni/src/main/java/java/util/concurrent/BlockingDeque.java b/ojluni/src/main/java/java/util/concurrent/BlockingDeque.java
index 7100f38..da1a4fd 100644
--- a/ojluni/src/main/java/java/util/concurrent/BlockingDeque.java
+++ b/ojluni/src/main/java/java/util/concurrent/BlockingDeque.java
@@ -197,7 +197,7 @@
  * the {@code BlockingDeque} in another thread.
  *
  * <p>This interface is a member of the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
  *
  * @since 1.6
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/CopyOnWriteArrayList.java b/ojluni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
index d3d681f..ebcbbef 100644
--- a/ojluni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
+++ b/ojluni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
@@ -51,11 +51,7 @@
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 
-// BEGIN android-note
-// removed link to collections framework docs
-// fixed framework docs link to "Collection#optional"
-// END android-note
-
+// Android-changed: Removed javadoc link to collections framework docs
 /**
  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
  * operations ({@code add}, {@code set}, and so on) are implemented by
@@ -100,22 +96,21 @@
     final transient Object lock = new Object();
 
     /** The array, accessed only via getArray/setArray. */
-    // Android-changed: renamed array -> elements for backwards compatibility b/33916927
-    private transient volatile Object[] elements;
+    private transient volatile Object[] array;
 
     /**
      * Gets the array.  Non-private so as to also be accessible
      * from CopyOnWriteArraySet class.
      */
     final Object[] getArray() {
-        return elements;
+        return array;
     }
 
     /**
      * Sets the array.
      */
     final void setArray(Object[] a) {
-        elements = a;
+        array = a;
     }
 
     /**
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..589d5da 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,36 @@
             final Field field;
             final int modifiers;
             try {
+                // BEGIN 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);
+                // END Android-changed: Skip privilege escalation which is a noop on Android.
                 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);
+                }
+                */
+                // END Android-removed: Skip checkPackageAccess which is a noop on Android.
+            // BEGIN Android-removed: Skip privilege escalation which is a noop on Android.
+            /*
+            } catch (PrivilegedActionException pae) {
+                throw new RuntimeException(pae.getException());
+            */
+            // END Android-removed: Skip privilege escalation which is a noop on Android.
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -420,23 +428,25 @@
             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
+        // BEGIN 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;
+        }
+        */
+        // END Android-removed: isAncestor()'s only usage was removed above.
 
         /**
          * 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..6878aa8 100644
--- a/ojluni/src/main/java/java/util/jar/Attributes.java
+++ b/ojluni/src/main/java/java/util/jar/Attributes.java
@@ -45,7 +45,7 @@
  * the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed 70
  * characters in length. Attribute values can contain any characters and
  * will be UTF8-encoded when written to the output stream.  See the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html">JAR File Specification</a>
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html">JAR File Specification</a>
  * for more information about valid attribute names and values.
  *
  * @author  David Connelly
@@ -442,7 +442,7 @@
      * to the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed
      * 70 characters in length. Attribute values can contain any characters
      * and will be UTF8-encoded when written to the output stream.  See the
-     * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html">JAR File Specification</a>
+     * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html">JAR File Specification</a>
      * for more information about valid attribute names and values.
      */
     public static class Name {
@@ -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="https://docs.oracle.com/javase/8/docs/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="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest">
          *      Manifest and Signature Specification</a>
          */
         public static final Name SIGNATURE_VERSION = new Name("Signature-Version");
@@ -551,7 +551,7 @@
          * <code>Name</code> object for <code>Class-Path</code>
          * manifest attribute. Bundled extensions can use this attribute
          * to find other JAR files containing needed classes.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#classpath">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#classpath">
          *      JAR file specification</a>
          */
         public static final Name CLASS_PATH = new Name("Class-Path");
@@ -568,7 +568,7 @@
         /**
          * <code>Name</code> object for <code>Sealed</code> manifest attribute
          * used for sealing.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#sealing">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#sealing">
          *      Package Sealing</a>
          */
         public static final Name SEALED = new Name("Sealed");
@@ -576,7 +576,7 @@
        /**
          * <code>Name</code> object for <code>Extension-List</code> manifest attribute
          * used for declaring dependencies on installed extensions.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#dependency">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/extensions/spec.html#dependency">
          *      Installed extension dependency</a>
          */
         public static final Name EXTENSION_LIST = new Name("Extension-List");
@@ -584,7 +584,7 @@
         /**
          * <code>Name</code> object for <code>Extension-Name</code> manifest attribute
          * used for declaring dependencies on installed extensions.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#dependency">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/extensions/spec.html#dependency">
          *      Installed extension dependency</a>
          */
         public static final Name EXTENSION_NAME = new Name("Extension-Name");
@@ -594,7 +594,7 @@
          * used for declaring dependencies on installed extensions.
          * @deprecated Extension mechanism will be removed in a future release.
          *             Use class path instead.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#dependency">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/extensions/spec.html#dependency">
          *      Installed extension dependency</a>
          */
         @Deprecated
@@ -603,7 +603,7 @@
         /**
          * <code>Name</code> object for <code>Implementation-Title</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      Java Product Versioning Specification</a>
          */
         public static final Name IMPLEMENTATION_TITLE = new Name("Implementation-Title");
@@ -611,7 +611,7 @@
         /**
          * <code>Name</code> object for <code>Implementation-Version</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      Java Product Versioning Specification</a>
          */
         public static final Name IMPLEMENTATION_VERSION = new Name("Implementation-Version");
@@ -619,7 +619,7 @@
         /**
          * <code>Name</code> object for <code>Implementation-Vendor</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      Java Product Versioning Specification</a>
          */
         public static final Name IMPLEMENTATION_VENDOR = new Name("Implementation-Vendor");
@@ -629,7 +629,7 @@
          * manifest attribute used for package versioning.
          * @deprecated Extension mechanism will be removed in a future release.
          *             Use class path instead.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/versioning.html#applet">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/extensions/versioning.html#applet">
          *      Optional Package Versioning</a>
          */
         @Deprecated
@@ -640,7 +640,7 @@
          * manifest attribute used for package versioning.
          * @deprecated Extension mechanism will be removed in a future release.
          *             Use class path instead.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/versioning.html#applet">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/extensions/versioning.html#applet">
          *      Optional Package Versioning</a>
          */
         @Deprecated
@@ -649,7 +649,7 @@
         /**
          * <code>Name</code> object for <code>Specification-Title</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      Java Product Versioning Specification</a>
          */
         public static final Name SPECIFICATION_TITLE = new Name("Specification-Title");
@@ -657,7 +657,7 @@
         /**
          * <code>Name</code> object for <code>Specification-Version</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      Java Product Versioning Specification</a>
          */
         public static final Name SPECIFICATION_VERSION = new Name("Specification-Version");
@@ -665,14 +665,9 @@
         /**
          * <code>Name</code> object for <code>Specification-Vendor</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
+         * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
          *      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/jar/Manifest.java b/ojluni/src/main/java/java/util/jar/Manifest.java
index de842fc..4dfda78 100644
--- a/ojluni/src/main/java/java/util/jar/Manifest.java
+++ b/ojluni/src/main/java/java/util/jar/Manifest.java
@@ -39,7 +39,7 @@
  * associated Attributes. There are main Manifest Attributes as well as
  * per-entry Attributes. For information on the Manifest format, please
  * see the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html">
  * Manifest format specification</a>.
  *
  * @author  David Connelly
diff --git a/ojluni/src/main/java/java/util/jar/Pack200.java b/ojluni/src/main/java/java/util/jar/Pack200.java
index 984c784..26b2ce3 100644
--- a/ojluni/src/main/java/java/util/jar/Pack200.java
+++ b/ojluni/src/main/java/java/util/jar/Pack200.java
@@ -96,7 +96,7 @@
  * The deployment applications can use "Accept-Encoding=pack200-gzip". This
  * indicates to the server that the client application desires a version of
  * the file encoded with Pack200 and further compressed with gzip. Please
- * refer to  <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/deployment/deployment-guide/pack200.html">Java Deployment Guide</a> for more details and
+ * refer to  <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/deployment/deployment-guide/pack200.html">Java Deployment Guide</a> for more details and
  * techniques.
  * <p>
  * Unless otherwise noted, passing a <tt>null</tt> argument to a constructor or
diff --git a/ojluni/src/main/java/java/util/jar/package.html b/ojluni/src/main/java/java/util/jar/package.html
index 2d2e493..921a821 100644
--- a/ojluni/src/main/java/java/util/jar/package.html
+++ b/ojluni/src/main/java/java/util/jar/package.html
@@ -45,7 +45,7 @@
       package description.</a> <p>
       In JAR files, all file names must be encoded in the UTF-8 encoding. 
 <p>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html">
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html">
       Manifest and Signature Specification</a> - The manifest format specification.
 </ul>
 
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/logging/package.html b/ojluni/src/main/java/java/util/logging/package.html
index 7384835..a4c71f4 100644
--- a/ojluni/src/main/java/java/util/logging/package.html
+++ b/ojluni/src/main/java/java/util/logging/package.html
@@ -116,7 +116,7 @@
 <P>
 For an overview of control flow, 
 please refer to the 
-<a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/logging/overview.html">
+<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html">
 Java Logging Overview</a>.
 </P>
 
diff --git a/ojluni/src/main/java/java/util/package.html b/ojluni/src/main/java/java/util/package.html
index 9cad732..8bb5efe 100644
--- a/ojluni/src/main/java/java/util/package.html
+++ b/ojluni/src/main/java/java/util/package.html
@@ -35,8 +35,8 @@
 
 <h2>Package Specification</h2>
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/overview.html"><b>Collections Framework Overview</b></a>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/reference.html"><b>
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/overview.html"><b>Collections Framework Overview</b></a>
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/reference.html"><b>
        Collections Framework Annotated Outline</b></a>
 </ul>
 
@@ -46,7 +46,7 @@
     <li><a href="http://www.java.sun.com/docs/books/tutorial/collections/">
        <b>Collections Framework Tutorial</b></a>
     <li><a
-    href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/designfaq.html"><b>Collections
+    href="https://docs.oracle.com/javase/8/docs/technotes/guides/collections/designfaq.html"><b>Collections
     Framework Design FAQ</b></a>
 </ul>
 
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..c643fc2 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: 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..38f8046 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.
@@ -126,58 +149,34 @@
      */
     private Runnable nativeFinalizer;
 
-    private static final NativeAllocationRegistry registry = new NativeAllocationRegistry(
-            Matcher.class.getClassLoader(), getNativeFinalizer(), nativeSize());
+    private static final NativeAllocationRegistry registry =
+            NativeAllocationRegistry.createMalloced(Matcher.class.getClassLoader(),
+            getNativeFinalizer());
 
     /**
-     * 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 +192,7 @@
      * @return  The pattern for which this matcher was created
      */
     public Pattern pattern() {
-        return pattern;
+        return parentPattern;
     }
 
     /**
@@ -206,7 +205,7 @@
      */
     public MatchResult toMatchResult() {
         ensureMatch();
-        return new OffsetBasedMatchResult(input, matchOffsets);
+        return new OffsetBasedMatchResult(text, groups);
     }
 
     /**
@@ -226,11 +225,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 +235,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 +388,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 +415,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 +478,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 +513,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 +548,7 @@
      */
     public boolean matches() {
         synchronized (this) {
-            matchFound = matchesImpl(address, matchOffsets);
+            matchFound = matchesImpl(address, groups);
         }
         return matchFound;
     }
@@ -479,7 +570,7 @@
      */
     public boolean find() {
         synchronized (this) {
-            matchFound = findNextImpl(address, matchOffsets);
+            matchFound = findNextImpl(address, groups);
         }
         return matchFound;
     }
@@ -494,6 +585,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 +595,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 +621,7 @@
      */
     public boolean lookingAt() {
         synchronized (this) {
-            matchFound = lookingAtImpl(address, matchOffsets);
+            matchFound = lookingAtImpl(address, groups);
         }
         return matchFound;
     }
@@ -588,8 +679,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 +736,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 +786,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 +814,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 +856,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 +903,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 +953,7 @@
      * @since 1.5
      */
     public int regionStart() {
-        return regionStart;
+        return from;
     }
 
     /**
@@ -860,7 +966,7 @@
      * @since 1.5
      */
     public int regionEnd() {
-        return regionEnd;
+        return to;
     }
 
     /**
@@ -904,16 +1010,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 +1060,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 +1112,6 @@
         }
     }
 
-
     /**
      * <p>Returns true if more input could change a positive match into a
      * negative one.
@@ -1028,35 +1133,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 +1178,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 +1191,7 @@
 
     private void resetForInput() {
         synchronized (this) {
-            setInputImpl(address, input, regionStart, regionEnd);
+            setInputImpl(address, text, from, to);
             useAnchoringBoundsImpl(address, anchoringBounds);
             useTransparentBoundsImpl(address, transparentBounds);
         }
@@ -1117,77 +1210,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);
@@ -1203,7 +1228,6 @@
     private static native boolean hitEndImpl(long addr);
     private static native boolean lookingAtImpl(long addr, int[] offsets);
     private static native boolean matchesImpl(long addr, int[] offsets);
-    private static native int nativeSize();
     private static native long openImpl(long patternAddr);
     private static native boolean requireEndImpl(long addr);
     private static native void setInputImpl(long addr, String s, int start, int end);
diff --git a/ojluni/src/main/java/java/util/regex/Pattern.java b/ojluni/src/main/java/java/util/regex/Pattern.java
index 5938431..55a48de 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,27 @@
      *
      * @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());
-
+    private static final NativeAllocationRegistry registry =
+            NativeAllocationRegistry.createMalloced(Pattern.class.getClassLoader(),
+            getNativeFinalizer());
+    // 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 +968,7 @@
 
     /**
      * Compiles the given regular expression into a pattern with the given
-     * flags.  </p>
+     * flags.
      *
      * @param  regex
      *         The expression to be compiled
@@ -964,6 +980,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 +988,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 +1015,6 @@
 
     /**
      * Creates a matcher that will match the given input against this pattern.
-     * </p>
      *
      * @param  input
      *         The character sequence to be matched
@@ -1007,12 +1022,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 +1066,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 +1076,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 +1085,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 +1111,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 +1134,6 @@
      *     <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
      * </table></blockquote>
      *
-     *
      * @param  input
      *         The character sequence to be split
      *
@@ -1113,11 +1144,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 +1158,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 +1197,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 +1276,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 +1291,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 +1352,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 +1400,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.
+
+        // 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");
@@ -1347,7 +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/Cipher.java b/ojluni/src/main/java/javax/crypto/Cipher.java
index 37a6378..a872317 100644
--- a/ojluni/src/main/java/javax/crypto/Cipher.java
+++ b/ojluni/src/main/java/javax/crypto/Cipher.java
@@ -242,7 +242,7 @@
  * </table>
  *
  * These transformations are described in the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Cipher">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
  * Cipher section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -597,7 +597,7 @@
      * @param transformation the name of the transformation, e.g.,
      * <i>DES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Cipher">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard transformation names.
      *
@@ -634,7 +634,7 @@
      * @param transformation the name of the transformation,
      * e.g., <i>DES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Cipher">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard transformation names.
      *
@@ -686,7 +686,7 @@
      * @param transformation the name of the transformation,
      * e.g., <i>DES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Cipher">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard transformation names.
      *
@@ -2477,7 +2477,7 @@
      * For more information on default key size in JCE jurisdiction
      * policy files, please see Appendix E in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppC">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppC">
      * Java Cryptography Architecture Reference Guide</a>.
      *
      * @param transformation the cipher transformation.
diff --git a/ojluni/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java b/ojluni/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java
index 131bd18..b8bf169 100644
--- a/ojluni/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java
+++ b/ojluni/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java
@@ -115,7 +115,7 @@
      *
      * @param algName encryption algorithm name. See Appendix A in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture Reference Guide</a>
      * for information about standard Cipher algorithm names.
      * @param encryptedData encrypted data. The contents of
@@ -198,7 +198,7 @@
      * in the constructor when such mapping is available.
      * See Appendix A in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture Reference Guide</a>
      * for information about standard Cipher algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/crypto/ExemptionMechanism.java b/ojluni/src/main/java/javax/crypto/ExemptionMechanism.java
index 6cc37e4..f991a66 100644
--- a/ojluni/src/main/java/javax/crypto/ExemptionMechanism.java
+++ b/ojluni/src/main/java/javax/crypto/ExemptionMechanism.java
@@ -116,7 +116,7 @@
      * mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Exemption">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
@@ -155,7 +155,7 @@
      * @param algorithm the standard name of the requested exemption mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Exemption">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
@@ -199,7 +199,7 @@
      * @param algorithm the standard name of the requested exemption mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Exemption">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
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/crypto/KeyAgreement.java b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
index ce42de8..f6decbc 100644
--- a/ojluni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
@@ -75,7 +75,7 @@
  * </table>
  *
  * This algorithm is described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyAgreement">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyAgreement">
  * KeyAgreement section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -177,7 +177,7 @@
      * @param algorithm the standard name of the requested key agreement
      * algorithm.
      * See the KeyAgreement section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyAgreement">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyAgreement">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -226,7 +226,7 @@
      * @param algorithm the standard name of the requested key agreement
      * algorithm.
      * See the KeyAgreement section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyAgreement">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyAgreement">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -272,7 +272,7 @@
      * @param algorithm the standard name of the requested key agreement
      * algorithm.
      * See the KeyAgreement section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyAgreement">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyAgreement">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/crypto/KeyGenerator.java b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
index 2d6f43d..0b30338 100644
--- a/ojluni/src/main/java/javax/crypto/KeyGenerator.java
+++ b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
@@ -156,7 +156,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyGenerator">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyGenerator">
  * KeyGenerator section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -272,7 +272,7 @@
      *
      * @param algorithm the standard name of the requested key algorithm.
      * See the KeyGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -305,7 +305,7 @@
      *
      * @param algorithm the standard name of the requested key algorithm.
      * See the KeyGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -349,7 +349,7 @@
      *
      * @param algorithm the standard name of the requested key algorithm.
      * See the KeyGenerator section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyGenerator">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyGenerator">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/crypto/Mac.java b/ojluni/src/main/java/javax/crypto/Mac.java
index dab6971..749b627 100644
--- a/ojluni/src/main/java/javax/crypto/Mac.java
+++ b/ojluni/src/main/java/javax/crypto/Mac.java
@@ -142,7 +142,7 @@
  * </table>
  *
  * These algorithms are described in the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Mac">
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Mac">
  * Mac section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -243,7 +243,7 @@
      *
      * @param algorithm the standard name of the requested MAC algorithm.
      * See the Mac section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Mac">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Mac">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -287,7 +287,7 @@
      *
      * @param algorithm the standard name of the requested MAC algorithm.
      * See the Mac section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Mac">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Mac">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -327,7 +327,7 @@
      *
      * @param algorithm the standard name of the requested MAC algorithm.
      * See the Mac section in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#Mac">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Mac">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
index be1cef4..659df8d 100644
--- a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
+++ b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
@@ -251,7 +251,7 @@
  * </table>
  *
  * These algorithms are described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecretKeyFactory">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory">
  * SecretKeyFactory section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -324,7 +324,7 @@
      * @param algorithm the standard name of the requested secret-key
      * algorithm.
      * See the SecretKeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecretKeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -359,7 +359,7 @@
      * @param algorithm the standard name of the requested secret-key
      * algorithm.
      * See the SecretKeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecretKeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
@@ -405,7 +405,7 @@
      * @param algorithm the standard name of the requested secret-key
      * algorithm.
      * See the SecretKeyFactory section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SecretKeyFactory">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/crypto/interfaces/package.html b/ojluni/src/main/java/javax/crypto/interfaces/package.html
index 8c5ba20..75ef6fe 100644
--- a/ojluni/src/main/java/javax/crypto/interfaces/package.html
+++ b/ojluni/src/main/java/javax/crypto/interfaces/package.html
@@ -46,7 +46,7 @@
 cryptographic provider developer guide:
 <ul>
   <li><a href=
-    "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+    "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
     <b>How to Implement a Provider for the
     Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
     </b></a></li>
@@ -65,7 +65,7 @@
 <ul>
   <li>
     <a href=
-      "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
       <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
       Cryptography Architecture API Specification and Reference
       </b></a></li>
diff --git a/ojluni/src/main/java/javax/crypto/package.html b/ojluni/src/main/java/javax/crypto/package.html
index ec2239a..bd4c05a 100644
--- a/ojluni/src/main/java/javax/crypto/package.html
+++ b/ojluni/src/main/java/javax/crypto/package.html
@@ -47,7 +47,7 @@
 <h2>Package Specification</h2>
 
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html"><b>
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html"><b>
     <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
     Cryptography Architecture Standard Algorithm Name
     Documentation</b></a></li>
@@ -59,13 +59,13 @@
 <ul>
   <li>
     <a href=
-      "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
       <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
        Cryptography Architecture (JCA) Reference Guide
       </b></a></li>
   <li>
     <a href=
-      "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
       <b>How to Implement a Provider in the
       Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
       </b></a></li>
diff --git a/ojluni/src/main/java/javax/crypto/spec/SecretKeySpec.java b/ojluni/src/main/java/javax/crypto/spec/SecretKeySpec.java
index 4c60b04..ff1258c 100644
--- a/ojluni/src/main/java/javax/crypto/spec/SecretKeySpec.java
+++ b/ojluni/src/main/java/javax/crypto/spec/SecretKeySpec.java
@@ -82,7 +82,7 @@
      * @param algorithm the name of the secret-key algorithm to be associated
      * with the given key material.
      * See Appendix A in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture Reference Guide</a>
      * for information about standard algorithm names.
      * @exception IllegalArgumentException if <code>algorithm</code>
@@ -127,7 +127,7 @@
      * @param algorithm the name of the secret-key algorithm to be associated
      * with the given key material.
      * See Appendix A in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture Reference Guide</a>
      * for information about standard algorithm names.
      * @exception IllegalArgumentException if <code>algorithm</code>
diff --git a/ojluni/src/main/java/javax/crypto/spec/package.html b/ojluni/src/main/java/javax/crypto/spec/package.html
index 3b87900..3e30aa1 100644
--- a/ojluni/src/main/java/javax/crypto/spec/package.html
+++ b/ojluni/src/main/java/javax/crypto/spec/package.html
@@ -61,13 +61,13 @@
 <ul>
   <li>
     <a href=
-      "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html">
+      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html">
       <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
       Cryptography Architecture API Specification and Reference
       </b></a></li>
   <li>
     <a href=
-      "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/HowToImplAProvider.html">
+      "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
       <b>How to Implement a Provider for the
       Java<FONT SIZE=-2><SUP>TM</SUP></FONT> Cryptography Architecture
       </b></a></li>
diff --git a/ojluni/src/main/java/javax/net/ssl/ExtendedSSLSession.java b/ojluni/src/main/java/javax/net/ssl/ExtendedSSLSession.java
index d1a24ac..2d832f3 100644
--- a/ojluni/src/main/java/javax/net/ssl/ExtendedSSLSession.java
+++ b/ojluni/src/main/java/javax/net/ssl/ExtendedSSLSession.java
@@ -45,7 +45,7 @@
      * The signature algorithm name must be a standard Java Security
      * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
      * See Appendix A in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
      * for information about standard algorithm names.
      * <p>
@@ -73,7 +73,7 @@
      * The signature algorithm name must be a standard Java Security
      * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
      * See Appendix A in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
      * for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
index 49b3163..d876877 100644
--- a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
+++ b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
@@ -25,19 +25,19 @@
 
 package javax.net.ssl;
 
+// Android-changed: Clarified use of HostnameVerifier on Android.
 /**
  * This class is the base interface for hostname verification.
  * <P>
- * During handshaking, if the URL's hostname and
- * the server's identification hostname mismatch, the
+ * During handshaking, the
  * verification mechanism can call back to implementers of this
  * interface to determine if this connection should be allowed.
+ * <p>
+ * For more information of the use of this interface on Android, see
+ * {@link HttpsURLConnection#setDefaultHostnameVerifier(HostnameVerifier)}.
  * <P>
  * The policies can be certificate-based
  * or may depend on other authentication schemes.
- * <P>
- * These callbacks are used when the default rules for URL hostname
- * verification fail.
  *
  * @author Brad R. Wetmore
  * @since 1.4
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index ec4254a..143fa5e 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,15 +211,52 @@
      * 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.
 
+    // Android-changed: Modified the documentation to explain side effects / discourage method use.
     /**
      * Sets the default <code>HostnameVerifier</code> inherited by a
      * new instance of this class.
-     * <P>
-     * If this method is not called, the default
-     * <code>HostnameVerifier</code> assumes the connection should not
-     * be permitted.
+     * <p>
+     * Developers are <em>strongly</em> discouraged from changing the default
+     * {@code HostnameVerifier} as {@link #getDefaultHostnameVerifier()} is used by several
+     * classes for hostname verification on Android.
+     * <table>
+     *     <tr>
+     *         <th>User</th>
+     *         <th>Effect</th>
+     *     </tr>
+     *     <tr>
+     *         <td>Android's default {@link TrustManager}, as used with Android's default
+     *         {@link SSLContext}, {@link SSLSocketFactory} and {@link SSLSocket} implementations.
+     *         </td>
+     *         <td>The {@code HostnameVerifier} is used to verify the peer's
+     *         certificate hostname after connecting if {@code
+     *         SSLParameters.setEndpointIdentificationAlgorithm("HTTPS")} has been called.
+     *         Instances use the <em>current</em> default {@code HostnameVerifier} at verification
+     *         time.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>{@link android.net.SSLCertificateSocketFactory}</td>
+     *         <td>The current default {@code HostnameVerifier} is used from various {@code
+     *         createSocket} methods. See {@link android.net.SSLCertificateSocketFactory} for
+     *         details; for example {@link
+     *         android.net.SSLCertificateSocketFactory#createSocket(String, int)}.
+     *         </td>
+     *     </tr>
+     *     <tr>
+     *         <td>Android's default {@link HttpsURLConnection} implementation.</td>
+     *         <td>The {@code HostnameVerifier} is used after a successful TLS handshake to verify
+     *         the URI host against the TLS session server. Instances use the default {@code
+     *         HostnameVerifier} set <em>when they were created</em> unless overridden with {@link
+     *         #setHostnameVerifier(HostnameVerifier)}.
+     *         Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
+     *         for the <em>entire</em> hostname verification step.</td>
+     *     </tr>
+     * </table>
+     * <p>
+     * If this method is not called, the default <code>HostnameVerifier</code> will check the
+     * hostname according to RFC 2818.
      *
      * @param v the default host name verifier
      * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
@@ -239,6 +276,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,9 +289,12 @@
      * @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;
     }
 
+    // Android-changed: Modified the documentation to explain Android behavior.
     /**
      * Sets the <code>HostnameVerifier</code> for this instance.
      * <P>
@@ -260,6 +302,9 @@
      * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
      * setDefaultHostnameVerifier}.  Calls to this method replace
      * this object's <code>HostnameVerifier</code>.
+     * <p>
+     * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
+     * for the <em>entire</em> hostname verification step.
      *
      * @param v the host name verifier
      * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
@@ -284,7 +329,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 +408,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/net/ssl/KeyManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
index 2199c9f..04af51a 100644
--- a/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
@@ -134,7 +134,7 @@
      *
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
@@ -170,7 +170,7 @@
 
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
@@ -211,7 +211,7 @@
      *
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLContext.java b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
index 4105282..b580a72 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLContext.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
@@ -74,11 +74,15 @@
  *       <td>TLSv1.2</td>
  *       <td>16+</td>
  *     </tr>
+ *     <tr>
+ *       <td>TLSv1.3</td>
+ *       <td>29+</td>
+ *     </tr>
  *   </tbody>
  * </table>
  *
  * This protocol is described in the <a href=
- * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SSLContext">
+ * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">
  * SSLContext section</a> of the
  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  *
@@ -132,10 +136,16 @@
         return defaultContext;
     }
 
+    // Android-changed: Additional text to strongly discouraged changing the default.
     /**
      * Sets the default SSL context. It will be returned by subsequent calls
      * to {@link #getDefault}. The default context must be immediately usable
      * and not require {@linkplain #init initialization}.
+     * <p>
+     * Developers are <em>strongly</em> discouraged from changing the default {@code SSLContext} as
+     * it is used as the Android default for secure communication by APIs like
+     * {@link SSLSocketFactory#getDefault()}, {@link SSLServerSocketFactory#getDefault()} and
+     * {@link HttpsURLConnection}.
      *
      * @param context the SSLContext
      * @throws  NullPointerException if context is null
@@ -170,7 +180,7 @@
      *
      * @param protocol the standard name of the requested protocol.
      *          See the SSLContext section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SSLContext">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">
      *          Java Cryptography Architecture Standard Algorithm Name
      *          Documentation</a>
      *          for information about standard protocol names.
@@ -206,7 +216,7 @@
      *
      * @param protocol the standard name of the requested protocol.
      *          See the SSLContext section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SSLContext">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">
      *          Java Cryptography Architecture Standard Algorithm Name
      *          Documentation</a>
      *          for information about standard protocol names.
@@ -246,7 +256,7 @@
      *
      * @param protocol the standard name of the requested protocol.
      *          See the SSLContext section in the <a href=
-     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#SSLContext">
+     * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">
      *          Java Cryptography Architecture Standard Algorithm Name
      *          Documentation</a>
      *          for information about standard protocol names.
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
index b6d1e51..76f8f66 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@
 
 import java.nio.ByteBuffer;
 import java.nio.ReadOnlyBufferException;
+import java.util.List;
+import java.util.function.BiFunction;
 
 
 /**
@@ -359,7 +361,7 @@
  * </OL>
  *
  * <h3>Default configuration for different Android versions</h3>
- * <p>{@code SSLEngine} instances obtained from default {@link SSLContext} are configured as
+ * <p>{@code SSLEngine} instances obtained from the default {@link SSLContext} are configured as
  * follows:
  *
  * <style type="text/css">
@@ -400,6 +402,11 @@
  *             <td>20+</td>
  *             <td>20+</td>
  *         </tr>
+ *         <tr>
+ *             <td>TLSv1.3</td>
+ *             <td>29+</td>
+ *             <td>29+</td>
+ *         </tr>
  *     </tbody>
  * </table>
  *
@@ -508,6 +515,21 @@
  *       <td>9-25</td>
  *       <td>9-23</td>
  *     </tr>
+ *     <tr>
+ *       <td>TLS_AES_128_GCM_SHA256</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_AES_256_GCM_SHA384</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_CHACHA20_POLY1305_SHA256</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
  *     <tr class="deprecated">
  *       <td>TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
  *       <td>1-8</td>
@@ -683,9 +705,9 @@
  *       <td>20+</td>
  *       <td>20+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -698,9 +720,9 @@
  *       <td>20+</td>
  *       <td>20+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -748,9 +770,9 @@
  *       <td>20+</td>
  *       <td>20+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -763,9 +785,9 @@
  *       <td>20+</td>
  *       <td>20+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -953,9 +975,9 @@
  *       <td>9+</td>
  *       <td>9+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -968,9 +990,9 @@
  *       <td>9+</td>
  *       <td>20+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -1501,6 +1523,7 @@
     public abstract boolean isOutboundDone();
 
 
+    // Android-changed: Added warnings about misuse
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on this engine.  Normally, only a subset of these will actually
@@ -1508,6 +1531,15 @@
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites might be useful in specialized applications.
      *
+     * <p class="caution">Applications should not blindly enable all supported
+     * cipher suites.  The supported cipher suites can include signaling cipher suite
+     * values that can cause connection problems if enabled inappropriately.
+     *
+     * <p>The proper way to use this method is to either check if a specific cipher
+     * suite is supported via {@code Arrays.asList(getSupportedCipherSuites()).contains(...)}
+     * or to filter a desired list of cipher suites to only the supported ones via
+     * {@code desiredSuiteSet.retainAll(Arrays.asList(getSupportedCipherSuites()))}.
+     *
      * @return  an array of cipher suite names
      * @see     #getEnabledCipherSuites()
      * @see     #setEnabledCipherSuites(String [])
@@ -1905,4 +1937,145 @@
         }
     }
 
+    // BEGIN Android-added: Integrate ALPN-related methods from OpenJDK 9+181
+    // Also removed references to DTLS in documentation; Android doesn't support DTLS.
+    /**
+     * Returns the most recent application protocol value negotiated for this
+     * connection.
+     * <p>
+     * If supported by the underlying SSL/TLS implementation,
+     * application name negotiation mechanisms such as <a
+     * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+     * Application-Layer Protocol Negotiation (ALPN), can negotiate
+     * application-level values between peers.
+     * <p>
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return null if it has not yet been determined if application
+     *         protocols might be used for this connection, an empty
+     *         {@code String} if application protocols values will not
+     *         be used, or a non-empty application protocol {@code String}
+     *         if a value was successfully negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public String getApplicationProtocol() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the application protocol value negotiated on a SSL/TLS
+     * handshake currently in progress.
+     * <p>
+     * Like {@link #getHandshakeSession()},
+     * a connection may be in the middle of a handshake. The
+     * application protocol may or may not yet be available.
+     * <p>
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return null if it has not yet been determined if application
+     *         protocols might be used for this handshake, an empty
+     *         {@code String} if application protocols values will not
+     *         be used, or a non-empty application protocol {@code String}
+     *         if a value was successfully negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public String getHandshakeApplicationProtocol() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Registers a callback function that selects an application protocol
+     * value for a SSL/TLS handshake.
+     * The function overrides any values supplied using
+     * {@link SSLParameters#setApplicationProtocols
+     * SSLParameters.setApplicationProtocols} and it supports the following
+     * type parameters:
+     * <blockquote>
+     * <dl>
+     * <dt> {@code SSLEngine}
+     * <dd> The function's first argument allows the current {@code SSLEngine}
+     *      to be inspected, including the handshake session and configuration
+     *      settings.
+     * <dt> {@code List<String>}
+     * <dd> The function's second argument lists the application protocol names
+     *      advertised by the TLS peer.
+     * <dt> {@code String}
+     * <dd> The function's result is an application protocol name, or null to
+     *      indicate that none of the advertised names are acceptable.
+     *      If the return value is an empty {@code String} then application
+     *      protocol indications will not be used.
+     *      If the return value is null (no value chosen) or is a value that
+     *      was not advertised by the peer, the underlying protocol will
+     *      determine what action to take. (For example, ALPN will send a
+     *      "no_application_protocol" alert and terminate the connection.)
+     * </dl>
+     * </blockquote>
+     *
+     * For example, the following call registers a callback function that
+     * examines the TLS handshake parameters and selects an application protocol
+     * name:
+     * <pre>{@code
+     *     serverEngine.setHandshakeApplicationProtocolSelector(
+     *         (serverEngine, clientProtocols) -> {
+     *             SSLSession session = serverEngine.getHandshakeSession();
+     *             return chooseApplicationProtocol(
+     *                 serverEngine,
+     *                 clientProtocols,
+     *                 session.getProtocol(),
+     *                 session.getCipherSuite());
+     *         });
+     * }</pre>
+     *
+     * @apiNote
+     * This method should be called by TLS server applications before the TLS
+     * handshake begins. Also, this {@code SSLEngine} should be configured with
+     * parameters that are compatible with the application protocol selected by
+     * the callback function. For example, enabling a poor choice of cipher
+     * suites could result in no suitable application protocol.
+     * See {@link SSLParameters}.
+     *
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @param selector the callback function, or null to disable the callback
+     *         functionality.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public void setHandshakeApplicationProtocolSelector(
+            BiFunction<SSLEngine, List<String>, String> selector) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retrieves the callback function that selects an application protocol
+     * value during a SSL/TLS handshake.
+     * See {@link #setHandshakeApplicationProtocolSelector
+     * setHandshakeApplicationProtocolSelector}
+     * for the function's type parameters.
+     *
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return the callback function, or null if none has been set.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public BiFunction<SSLEngine, List<String>, String>
+            getHandshakeApplicationProtocolSelector() {
+        throw new UnsupportedOperationException();
+    }
+    // END Android-added: Integrate ALPN-related methods from OpenJDK 9+181
 }
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLParameters.java b/ojluni/src/main/java/javax/net/ssl/SSLParameters.java
index c83f656..41dcf0f 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLParameters.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,8 @@
     private Map<Integer, SNIServerName> sniNames = null;
     private Map<Integer, SNIMatcher> sniMatchers = null;
     private boolean preferLocalCipherSuites;
+    // Android-added: Integrate ALPN-related methods from OpenJDK 9+181
+    private String[] applicationProtocols = new String[0];
 
     /**
      * Constructs SSLParameters.
@@ -255,7 +257,7 @@
      *
      * @param algorithm The standard string name of the endpoint
      *     identification algorithm (or null).  See Appendix A in the <a href=
-     *   "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *   "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
      *     Java Cryptography Architecture API Specification &amp; Reference </a>
      *     for information about standard algorithm names.
      *
@@ -464,4 +466,77 @@
     public final boolean getUseCipherSuitesOrder() {
         return preferLocalCipherSuites;
     }
+
+    // BEGIN Android-added: Integrate ALPN-related methods from OpenJDK 9+181
+    // Also removed references to DTLS in documentation; Android doesn't support DTLS.
+    /**
+     * Returns a prioritized array of application-layer protocol names that
+     * can be negotiated over the SSL/TLS protocols.
+     * <p>
+     * The array could be empty (zero-length), in which case protocol
+     * indications will not be used.
+     * <p>
+     * This method will return a new array each time it is invoked.
+     *
+     * @return a non-null, possibly zero-length array of application protocol
+     *         {@code String}s.  The array is ordered based on protocol
+     *         preference, with {@code protocols[0]} being the most preferred.
+     * @see #setApplicationProtocols
+     * @since 9
+     */
+    public String[] getApplicationProtocols() {
+        return applicationProtocols.clone();
+    }
+
+    /**
+     * Sets the prioritized array of application-layer protocol names that
+     * can be negotiated over the SSL/TLS protocols.
+     * <p>
+     * If application-layer protocols are supported by the underlying
+     * SSL/TLS implementation, this method configures which values can
+     * be negotiated by protocols such as <a
+     * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+     * Application Layer Protocol Negotiation (ALPN).
+     * <p>
+     * If this end of the connection is expected to offer application protocol
+     * values, all protocols configured by this method will be sent to the
+     * peer.
+     * <p>
+     * If this end of the connection is expected to select the application
+     * protocol value, the {@code protocols} configured by this method are
+     * compared with those sent by the peer.  The first matched value becomes
+     * the negotiated value.  If none of the {@code protocols} were actually
+     * requested by the peer, the underlying protocol will determine what
+     * action to take.  (For example, ALPN will send a
+     * {@code "no_application_protocol"} alert and terminate the connection.)
+     * <p>
+     * @implSpec
+     * This method will make a copy of the {@code protocols} array.
+     *
+     * @param protocols   an ordered array of application protocols,
+     *                    with {@code protocols[0]} being the most preferred.
+     *                    If the array is empty (zero-length), protocol
+     *                    indications will not be used.
+     * @throws IllegalArgumentException if protocols is null, or if
+     *                    any element in a non-empty array is null or an
+     *                    empty (zero-length) string
+     * @see #getApplicationProtocols
+     * @since 9
+     */
+    public void setApplicationProtocols(String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("protocols was null");
+        }
+
+        String[] tempProtocols = protocols.clone();
+
+        for (String p : tempProtocols) {
+            if (p == null || p.equals("")) {
+                throw new IllegalArgumentException(
+                    "An element of protocols was null/empty");
+            }
+        }
+        applicationProtocols = tempProtocols;
+    }
+    // END Android-added: Integrate ALPN-related methods from OpenJDK 9+181
 }
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
index 7b07cfa..35c14ea 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
@@ -229,6 +229,7 @@
     public abstract void setEnabledCipherSuites(String suites []);
 
 
+    // Android-changed: Added warnings about misuse
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on an SSL connection.
@@ -238,6 +239,15 @@
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
      *
+     * <p class="caution">Applications should not blindly enable all supported
+     * cipher suites.  The supported cipher suites can include signaling cipher suite
+     * values that can cause connection problems if enabled inappropriately.
+     *
+     * <p>The proper way to use this method is to either check if a specific cipher
+     * suite is supported via {@code Arrays.asList(getSupportedCipherSuites()).contains(...)}
+     * or to filter a desired list of cipher suites to only the supported ones via
+     * {@code desiredSuiteSet.retainAll(Arrays.asList(getSupportedCipherSuites()))}.
+     *
      * @return an array of cipher suite names
      * @see #getEnabledCipherSuites()
      * @see #setEnabledCipherSuites(String [])
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index 2db63bb..5067f8f 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -162,6 +162,7 @@
     public abstract String [] getDefaultCipherSuites();
 
 
+    // Android-changed: Added warnings about misuse
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on an SSL connection created by this factory.
@@ -170,6 +171,15 @@
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
      *
+     * <p class="caution">Applications should not blindly enable all supported
+     * cipher suites.  The supported cipher suites can include signaling cipher suite
+     * values that can cause connection problems if enabled inappropriately.
+     *
+     * <p>The proper way to use this method is to either check if a specific cipher
+     * suite is supported via {@code Arrays.asList(getSupportedCipherSuites()).contains(...)}
+     * or to filter a desired list of cipher suites to only the supported ones via
+     * {@code desiredSuiteSet.retainAll(Arrays.asList(getSupportedCipherSuites()))}.
+     *
      * @return an array of cipher suite names
      * @see #getDefaultCipherSuites()
      */
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
index dfa5b7e..a2ba960 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
 
 import java.io.IOException;
 import java.net.*;
+import java.util.List;
+import java.util.function.BiFunction;
 
 
 /**
@@ -173,6 +175,11 @@
  *             <td>16+</td>
  *             <td>20+</td>
  *         </tr>
+ *         <tr>
+ *             <td>TLSv1.3</td>
+ *             <td>29+</td>
+ *             <td>29+</td>
+ *         </tr>
  *     </tbody>
  * </table>
  *
@@ -206,6 +213,11 @@
  *             <td>16+</td>
  *             <td>16+</td>
  *         </tr>
+ *         <tr>
+ *             <td>TLSv1.3</td>
+ *             <td>29+</td>
+ *             <td>29+</td>
+ *         </tr>
  *     </tbody>
  * </table>
  *
@@ -321,6 +333,21 @@
  *       <td>9-25</td>
  *       <td>9-23</td>
  *     </tr>
+ *     <tr>
+ *       <td>TLS_AES_128_GCM_SHA256</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_AES_256_GCM_SHA384</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_CHACHA20_POLY1305_SHA256</td>
+ *       <td>29+</td>
+ *       <td>29+</td>
+ *     </tr>
  *     <tr class="deprecated">
  *       <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
  *       <td>9-22</td>
@@ -421,9 +448,9 @@
  *       <td>11+</td>
  *       <td>11+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -436,9 +463,9 @@
  *       <td>11+</td>
  *       <td>11+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -486,9 +513,9 @@
  *       <td>11+</td>
  *       <td>11+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -501,9 +528,9 @@
  *       <td>11+</td>
  *       <td>11+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -676,9 +703,9 @@
  *       <td>9+</td>
  *       <td>9+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -691,9 +718,9 @@
  *       <td>9+</td>
  *       <td>11+</td>
  *     </tr>
- *     <tr>
+ *     <tr class="deprecated">
  *       <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
- *       <td>20+</td>
+ *       <td>20-28</td>
  *       <td></td>
  *     </tr>
  *     <tr>
@@ -992,6 +1019,7 @@
         { super(address, port, clientAddress, clientPort); }
 
 
+    // Android-changed: Added warnings about misuse
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on this connection.  Normally, only a subset of these will actually
@@ -999,6 +1027,15 @@
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites might be useful in specialized applications.
      *
+     * <p class="caution">Applications should not blindly enable all supported
+     * cipher suites.  The supported cipher suites can include signaling cipher suite
+     * values that can cause connection problems if enabled inappropriately.
+     *
+     * <p>The proper way to use this method is to either check if a specific cipher
+     * suite is supported via {@code Arrays.asList(getSupportedCipherSuites()).contains(...)}
+     * or to filter a desired list of cipher suites to only the supported ones via
+     * {@code desiredSuiteSet.retainAll(Arrays.asList(getSupportedCipherSuites()))}.
+     *
      * @return an array of cipher suite names
      * @see #getEnabledCipherSuites()
      * @see #setEnabledCipherSuites(String [])
@@ -1401,6 +1438,148 @@
         }
     }
 
+    // BEGIN Android-added: Add ALPN-related methods from OpenJDK 9.
+    // Also removed references to DTLS in documentation; Android doesn't support DTLS.
+    /**
+     * Returns the most recent application protocol value negotiated for this
+     * connection.
+     * <p>
+     * If supported by the underlying SSL/TLS implementation,
+     * application name negotiation mechanisms such as <a
+     * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+     * Application-Layer Protocol Negotiation (ALPN), can negotiate
+     * application-level values between peers.
+     * <p>
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return null if it has not yet been determined if application
+     *         protocols might be used for this connection, an empty
+     *         {@code String} if application protocols values will not
+     *         be used, or a non-empty application protocol {@code String}
+     *         if a value was successfully negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public String getApplicationProtocol() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the application protocol value negotiated on a SSL/TLS
+     * handshake currently in progress.
+     * <p>
+     * Like {@link #getHandshakeSession()},
+     * a connection may be in the middle of a handshake. The
+     * application protocol may or may not yet be available.
+     * <p>
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return null if it has not yet been determined if application
+     *         protocols might be used for this handshake, an empty
+     *         {@code String} if application protocols values will not
+     *         be used, or a non-empty application protocol {@code String}
+     *         if a value was successfully negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public String getHandshakeApplicationProtocol() {
+        throw new UnsupportedOperationException();
+    }
+
+
+    /**
+     * Registers a callback function that selects an application protocol
+     * value for a SSL/TLS handshake.
+     * The function overrides any values supplied using
+     * {@link SSLParameters#setApplicationProtocols
+     * SSLParameters.setApplicationProtocols} and it supports the following
+     * type parameters:
+     * <blockquote>
+     * <dl>
+     * <dt> {@code SSLSocket}
+     * <dd> The function's first argument allows the current {@code SSLSocket}
+     *      to be inspected, including the handshake session and configuration
+     *      settings.
+     * <dt> {@code List<String>}
+     * <dd> The function's second argument lists the application protocol names
+     *      advertised by the TLS peer.
+     * <dt> {@code String}
+     * <dd> The function's result is an application protocol name, or null to
+     *      indicate that none of the advertised names are acceptable.
+     *      If the return value is an empty {@code String} then application
+     *      protocol indications will not be used.
+     *      If the return value is null (no value chosen) or is a value that
+     *      was not advertised by the peer, the underlying protocol will
+     *      determine what action to take. (For example, ALPN will send a
+     *      "no_application_protocol" alert and terminate the connection.)
+     * </dl>
+     * </blockquote>
+     *
+     * For example, the following call registers a callback function that
+     * examines the TLS handshake parameters and selects an application protocol
+     * name:
+     * <pre>{@code
+     *     serverSocket.setHandshakeApplicationProtocolSelector(
+     *         (serverSocket, clientProtocols) -> {
+     *             SSLSession session = serverSocket.getHandshakeSession();
+     *             return chooseApplicationProtocol(
+     *                 serverSocket,
+     *                 clientProtocols,
+     *                 session.getProtocol(),
+     *                 session.getCipherSuite());
+     *         });
+     * }</pre>
+     *
+     * @apiNote
+     * This method should be called by TLS server applications before the TLS
+     * handshake begins. Also, this {@code SSLSocket} should be configured with
+     * parameters that are compatible with the application protocol selected by
+     * the callback function. For example, enabling a poor choice of cipher
+     * suites could result in no suitable application protocol.
+     * See {@link SSLParameters}.
+     *
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @param selector the callback function, or null to de-register.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public void setHandshakeApplicationProtocolSelector(
+            BiFunction<SSLSocket, List<String>, String> selector) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retrieves the callback function that selects an application protocol
+     * value during a SSL/TLS handshake.
+     * See {@link #setHandshakeApplicationProtocolSelector
+     * setHandshakeApplicationProtocolSelector}
+     * for the function's type parameters.
+     *
+     * @implSpec
+     * The implementation in this class throws
+     * {@code UnsupportedOperationException} and performs no other action.
+     *
+     * @return the callback function, or null if none has been set.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     * @since 9
+     */
+    public BiFunction<SSLSocket, List<String>, String>
+            getHandshakeApplicationProtocolSelector() {
+        throw new UnsupportedOperationException();
+    }
+    // END Android-added: Add ALPN-related methods from OpenJDK 9.
+
     // Android-added: Make toString explicit that this is an SSLSocket (http://b/6602228)
     @Override
     public String toString() {
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index 93b5dc7..8b0966b 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -187,6 +187,7 @@
      */
     public abstract String [] getDefaultCipherSuites();
 
+    // Android-changed: Added warnings about misuse
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on an SSL connection.  Normally, only a subset of these will actually
@@ -194,6 +195,15 @@
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
      *
+     * <p class="caution">Applications should not blindly enable all supported
+     * cipher suites.  The supported cipher suites can include signaling cipher suite
+     * values that can cause connection problems if enabled inappropriately.
+     *
+     * <p>The proper way to use this method is to either check if a specific cipher
+     * suite is supported via {@code Arrays.asList(getSupportedCipherSuites()).contains(...)}
+     * or to filter a desired list of cipher suites to only the supported ones via
+     * {@code desiredSuiteSet.retainAll(Arrays.asList(getSupportedCipherSuites()))}.
+     *
      * @see #getDefaultCipherSuites()
      * @return an array of cipher suite names
      */
diff --git a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
index 2a223b0..7322169 100644
--- a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
@@ -136,7 +136,7 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
@@ -172,7 +172,7 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
@@ -213,7 +213,7 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
+     *  "https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">
      *          Java Secure Socket Extension Reference Guide </a>
      *          for information about standard algorithm names.
      *
diff --git a/ojluni/src/main/java/javax/net/ssl/package.html b/ojluni/src/main/java/javax/net/ssl/package.html
index fc4d95c..0f87f45 100644
--- a/ojluni/src/main/java/javax/net/ssl/package.html
+++ b/ojluni/src/main/java/javax/net/ssl/package.html
@@ -37,7 +37,7 @@
 <h2>Package Specification</h2>
 
 <ul>
-  <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+  <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
     <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
     Cryptography Architecture Standard Algorithm Name
     Documentation</b></a></li>
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/javax/security/auth/login/package-info.java b/ojluni/src/main/java/javax/security/auth/login/package-info.java
index 301ac21..6bb5a06 100644
--- a/ojluni/src/main/java/javax/security/auth/login/package-info.java
+++ b/ojluni/src/main/java/javax/security/auth/login/package-info.java
@@ -28,7 +28,7 @@
  * <h2>Package Specification</h2>
  *
  * <ul>
- *   <li><a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html">
+ *   <li><a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
  *     <b>Java&trade;
  *     Cryptography Architecture Standard Algorithm Name
  *     Documentation</b></a></li>
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..2473f65 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");
         }
@@ -351,14 +353,7 @@
      * nanoseconds-from-now (<code>false</code>)
      * @param time the (absolute millis or relative nanos) time value
      */
-    public void park(boolean absolute, long time) {
-        if (absolute) {
-            Thread.currentThread().parkUntil$(time);
-        } else {
-            Thread.currentThread().parkFor$(time);
-        }
-    }
-
+    public native void park(boolean absolute, long time);
     /**
      * Unparks the given object, which must be a {@link Thread}.
      *
@@ -367,14 +362,8 @@
      *
      * @param obj non-null; the object to unpark
      */
-    public void unpark(Object obj) {
-        if (obj instanceof Thread) {
-            ((Thread) obj).unpark$();
-        } else {
-            throw new IllegalArgumentException("valid for Threads only");
-        }
-    }
-
+    @FastNative
+    public native void unpark(Object obj);
     /**
      * Allocates an instance of the given class without running the constructor.
      * The class' <clinit> will be run, if necessary.
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/SocketChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/SocketChannelImpl.java
index e4dbb5d..c6f06e2 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketChannelImpl.java
@@ -936,7 +936,14 @@
         if (guard != null) {
             guard.warnIfOpen();
         }
-        close();
+        // BEGIN Android-changed: Integrate upstream code from DatagramChannelImpl.finalize().
+        // http://b/115296581
+        // close();
+        // fd is null if constructor threw exception
+        if (fd != null) {
+            close();
+        }
+        // END Android-changed: Integrate upstream code from DatagramChannelImpl.finalize().
     }
 
     /**
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..3c71a79 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 properly.
         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/DefaultFileSystemProvider.java b/ojluni/src/main/java/sun/nio/fs/DefaultFileSystemProvider.java
index 595f3c6..5d2bae6 100644
--- a/ojluni/src/main/java/sun/nio/fs/DefaultFileSystemProvider.java
+++ b/ojluni/src/main/java/sun/nio/fs/DefaultFileSystemProvider.java
@@ -59,7 +59,9 @@
             .doPrivileged(new GetPropertyAction("os.name"));
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.fs.SolarisFileSystemProvider");
-        if (osname.equals("Linux"))
+        // Android-changed: Fuchsia: Use LinuxFileSystemProvider.
+        // if (osname.equals("Linux"))
+        if (osname.equals("Linux") || osname.equals("Fuchsia"))
             return createProvider("sun.nio.fs.LinuxFileSystemProvider");
         if (osname.contains("OS X"))
             return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
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/NativeBuffer.java b/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
index 1009bda..0c6de1d 100644
--- a/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
+++ b/ojluni/src/main/java/sun/nio/fs/NativeBuffer.java
@@ -59,10 +59,16 @@
         this.cleaner = Cleaner.create(this, new Deallocator(address));
     }
 
+    // Android-note: releaseNativeBuffer() ensures that its argument is strongly reachable.
     void release() {
         NativeBuffers.releaseNativeBuffer(this);
     }
 
+    // BEGIN Android-note: Lifecycle contract of NativeBuffer.address() relative to release().
+    // We require that:
+    // 1) NativeBuffer is ALWAYS explicitly release()ed before being dropped, and
+    // 2) The result of address() is only used before release() is called.
+    // END Android-note: Lifecycle contract of NativeBuffer.address() relative to release().
     long address() {
         return address;
     }
diff --git a/ojluni/src/main/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/java/sun/security/pkcs/PKCS7.java b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
index bf3e8f8..d3cd7e0 100644
--- a/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
+++ b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
@@ -77,7 +77,7 @@
 
     private Principal[] certIssuerNames;
 
-    // BEGIN Android-removed: unused in Android
+    // BEGIN Android-removed: Unused in Android.
     /*
     /*
      * Random number generator for creating nonce values
@@ -106,7 +106,7 @@
      *
     private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37";
     */
-    // END Android-removed: unused on Android
+    // END Android-removed: Unused in Android.
 
     /**
      * Unmarshals a PKCS7 block from its encoded form, parsing the
@@ -1008,7 +1008,7 @@
     }
     // END Android-added: Add subclass that returns the original encoded bytes.
 
-    // BEGIN Android-removed: unused in Android
+    // BEGIN Android-removed: Unused in Android.
     /**
      * Assembles a PKCS #7 signed data message that optionally includes a
      * signature timestamp.
@@ -1191,5 +1191,5 @@
         return tsReply.getEncodedToken();
     }
     */
-    // END Android-removed: unused in Android
+    // END Android-removed: Unused in Android.
 }
diff --git a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
index 3053730..88fcf06 100644
--- a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
@@ -96,6 +96,9 @@
     PKCS9Attributes authenticatedAttributes;
     PKCS9Attributes unauthenticatedAttributes;
 
+    // Android-added: No-arg constructor to use in @libcore.api.CorePlatformApi
+    public SignerInfo() {}
+
     public SignerInfo(X500Name  issuerName,
                       BigInteger serial,
                       AlgorithmId digestAlgorithmId,
diff --git a/ojluni/src/main/java/sun/security/x509/RDN.java b/ojluni/src/main/java/sun/security/x509/RDN.java
index 3bfc524..161ca2b 100644
--- a/ojluni/src/main/java/sun/security/x509/RDN.java
+++ b/ojluni/src/main/java/sun/security/x509/RDN.java
@@ -482,7 +482,7 @@
         boolean a1Has2253 = a1.hasRFC2253Keyword();
         boolean a2Has2253 = a2.hasRFC2253Keyword();
 
-        // BEGIN Android-changed: Keep sort order of RDN from Android M
+        // BEGIN Android-changed: Keep sort order of RDN from Android M.
         if (a1Has2253) {
             if (a2Has2253) {
                 return a1.toRFC2253CanonicalString().compareTo
@@ -506,7 +506,7 @@
                         a1Oid[pos] - a2Oid[pos];
             }
         }
-        // BEGIN Android-changed: Keep sort order of RDN from prev impl
+        // END Android-changed: Keep sort order of RDN from Android M.
     }
 
 }
diff --git a/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java b/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
index ead18de..28b10c8 100644
--- a/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
+++ b/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
@@ -126,12 +126,14 @@
             // BEGIN Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
             // if (zi instanceof ZoneInfo) {
             //    zoneOffset = ((ZoneInfo)zi).getOffsets(millis, offsets);
-            // } else {
+            if (zi instanceof libcore.util.ZoneInfo) {
+                zoneOffset = ((libcore.util.ZoneInfo) zi).getOffsetsByUtcTime(millis, offsets);
+            // END Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            } else {
                 zoneOffset = zi.getOffset(millis);
                 offsets[0] = zi.getRawOffset();
                 offsets[1] = zoneOffset - offsets[0];
-            // }
-            // END Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            }
 
             // We need to calculate the given millis and time zone
             // offset separately for java.util.GregorianCalendar
diff --git a/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java b/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java
index c158391..b067413 100644
--- a/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java
+++ b/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java
@@ -43,13 +43,17 @@
  * @author Naoto Sato
  */
 public class CalendarDataUtility {
+    // Android-note: This class has been rewritten from scratch and is effectively forked.
+    // The API (names of public constants, method signatures etc.) generally derives
+    // from OpenJDK so that other OpenJDK code that refers to this class doesn't need to
+    // be changed, but the implementation has been rewritten; logic / identifiers
+    // that weren't used from anywhere else have been dropped altogether.
 
-    // Android-note: This class has been rewritten from scratch, keeping its API the same.
-    // Since Android gets its calendar related data from ICU, the implementation of this class is
-    // effectively independent of the upstream class, with the only similarity being is API in
-    // order to keep the necessary modifications outside of this class to a minimum.
+    // Android-removed: Dead code, unused on Android.
+    // public final static String FIRST_DAY_OF_WEEK = "firstDayOfWeek";
+    // public final static String MINIMAL_DAYS_IN_FIRST_WEEK = "minimalDaysInFirstWeek";
 
-    // Android-added: calendar name constants for use in retrievFieldValueName.
+    // Android-added: Calendar name constants for use in retrievFieldValueName.
     private static final String ISLAMIC_CALENDAR = "islamic";
     private static final String GREGORIAN_CALENDAR = "gregorian";
     private static final String BUDDHIST_CALENDAR = "buddhist";
@@ -62,18 +66,42 @@
             NARROW_FORMAT, NARROW_STANDALONE
     };
 
-    // Android-removed: unused FIRST_DAY_OF_WEEK and MINIMAL_DAYS_IN_FIRST_WEEK constants.
-
     // No instantiation
     private CalendarDataUtility() {
     }
 
-    // Android-removed: retrieveFirstDayOfWeek and retrieveMinimalDaysInFirstWeek.
-    // Android-note: use libcore.icu.LocaleData or android.icu.util.Calendar.WeekData instead.
+    // BEGIN Android-removed: Dead code, unused on Android.
+    // Clients should use libcore.icu.LocaleData or android.icu.util.Calendar.WeekData instead.
+    /*
+    public static int retrieveFirstDayOfWeek(Locale locale) {
+        LocaleServiceProviderPool pool =
+                LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+        Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
+                                                locale, FIRST_DAY_OF_WEEK);
+        return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY;
+    }
 
+    public static int retrieveMinimalDaysInFirstWeek(Locale locale) {
+        LocaleServiceProviderPool pool =
+                LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+        Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
+                                                locale, MINIMAL_DAYS_IN_FIRST_WEEK);
+        return (value != null && (value >= 1 && value <= 7)) ? value : 1;
+    }
+    */
+    // END Android-removed: Dead code, unused on Android.
+
+    // BEGIN Android-changed: Implement on top of ICU.
+    /*
+    public static String retrieveFieldValueName(String id, int field, int value, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+                LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        return pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
+                                       field, value, style, false);
+    }
+    */
     public static String retrieveFieldValueName(String id, int field, int value, int style,
             Locale locale) {
-        // Android-changed: delegate to ICU.
         if (field == Calendar.ERA) {
             // For era the field value does not always equal the index into the names array.
             switch (normalizeCalendarType(id)) {
@@ -102,16 +130,41 @@
         }
         return names[value];
     }
+    // END Android-changed: Implement on top of ICU.
 
+    // BEGIN Android-changed: Implement on top of ICU.
+    /*
+    public static String retrieveJavaTimeFieldValueName(String id, int field, int value, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+                LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        String name;
+        name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
+                                       field, value, style, true);
+        if (name == null) {
+            name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
+                                           field, value, style, false);
+        }
+        return name;
+    }
+    */
     public static String retrieveJavaTimeFieldValueName(String id, int field, int value, int style,
             Locale locale) {
-        // Android-changed: don't distinguish between retrieve* and retrieveJavaTime* methods.
+        // Don't distinguish between retrieve* and retrieveJavaTime* methods.
         return retrieveFieldValueName(id, field, value, style, locale);
     }
+    // END Android-changed: Implement on top of ICU.
 
+    // BEGIN Android-changed: Implement on top of ICU.
+    /*
+    public static Map<String, Integer> retrieveFieldValueNames(String id, int field, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        return pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
+                                       normalizeCalendarType(id), field, style, false);
+    }
+    */
     public static Map<String, Integer> retrieveFieldValueNames(String id, int field, int style,
             Locale locale) {
-        // Android-changed: delegate to ICU.
         Map<String, Integer> names;
         if (style == ALL_STYLES) {
             names = retrieveFieldValueNamesImpl(id, field, SHORT_FORMAT, locale);
@@ -124,17 +177,40 @@
         }
         return names.isEmpty() ? null : names;
     }
+    // END Android-changed: Implement on top of ICU.
 
+    // BEGIN Android-changed: Implement on top of ICU.
+    /*
+    public static Map<String, Integer> retrieveJavaTimeFieldValueNames(String id, int field, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        Map<String, Integer> map;
+        map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
+                                       normalizeCalendarType(id), field, style, true);
+        if (map == null) {
+            map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
+                                           normalizeCalendarType(id), field, style, false);
+        }
+        return map;
+    }
+    */
     public static Map<String, Integer> retrieveJavaTimeFieldValueNames(String id, int field,
             int style, Locale locale) {
-        // Android-changed: don't distinguish between retrieve* and retrieveJavaTime* methods.
+        // Don't distinguish between retrieve* and retrieveJavaTime* methods.
         return retrieveFieldValueNames(id, field, style, locale);
     }
+    // END Android-changed: Implement on top of ICU.
 
+    // Android-changed: Added private modifier for normalizeCalendarType().
+    // static String normalizeCalendarType(String requestID) {
     private static String normalizeCalendarType(String requestID) {
         String type;
         // Android-changed: normalize "gregory" to "gregorian", not the other way around.
         // See android.icu.text.DateFormatSymbols.CALENDAR_CLASSES for reference.
+        // if (requestID.equals("gregorian") || requestID.equals("iso8601")) {
+        //    type = "gregory";
+        // } else if (requestID.startsWith("islamic")) {
+        //    type = "islamic";
         if (requestID.equals("gregory") || requestID.equals("iso8601")) {
             type = GREGORIAN_CALENDAR;
         } else if (requestID.startsWith(ISLAMIC_CALENDAR)) {
@@ -145,7 +221,7 @@
         return type;
     }
 
-    // BEGIN Android-added: various private helper methods.
+    // BEGIN Android-added: Various private helper methods.
     private static Map<String, Integer> retrieveFieldValueNamesImpl(String id, int field, int style,
             Locale locale) {
         String[] names = getNames(id, field, style, locale);
@@ -250,8 +326,101 @@
                 throw new IllegalArgumentException("Invalid style: " + style);
         }
     }
-    // END Android-added: various private helper methods.
+    // END Android-added: Various private helper methods.
 
-    // Android-removed: CalendarFieldValueNameGetter, CalendarFieldValueNamesMapGetter
-    // Android-removed: CalendarWeekParameterGetter
+    // BEGIN Android-removed: Dead code, unused on Android.
+    /*
+    /**
+     * Obtains a localized field value string from a CalendarDataProvider
+     * implementation.
+     *
+    private static class CalendarFieldValueNameGetter
+        implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,
+                                                                   String> {
+        private static final CalendarFieldValueNameGetter INSTANCE =
+            new CalendarFieldValueNameGetter();
+
+        @Override
+        public String getObject(CalendarNameProvider calendarNameProvider,
+                                Locale locale,
+                                String requestID, // calendarType
+                                Object... params) {
+            assert params.length == 4;
+            int field = (int) params[0];
+            int value = (int) params[1];
+            int style = (int) params[2];
+            boolean javatime = (boolean) params[3];
+
+            // If javatime is true, resources from CLDR have precedence over JRE
+            // native resources.
+            if (javatime && calendarNameProvider instanceof CalendarNameProviderImpl) {
+                String name;
+                name = ((CalendarNameProviderImpl)calendarNameProvider)
+                        .getJavaTimeDisplayName(requestID, field, value, style, locale);
+                return name;
+            }
+            return calendarNameProvider.getDisplayName(requestID, field, value, style, locale);
+        }
+    }
+
+    /**
+     * Obtains a localized field-value pairs from a CalendarDataProvider
+     * implementation.
+     *
+    private static class CalendarFieldValueNamesMapGetter
+        implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,
+                                                                   Map<String, Integer>> {
+        private static final CalendarFieldValueNamesMapGetter INSTANCE =
+            new CalendarFieldValueNamesMapGetter();
+
+        @Override
+        public Map<String, Integer> getObject(CalendarNameProvider calendarNameProvider,
+                                              Locale locale,
+                                              String requestID, // calendarType
+                                              Object... params) {
+            assert params.length == 3;
+            int field = (int) params[0];
+            int style = (int) params[1];
+            boolean javatime = (boolean) params[2];
+
+            // If javatime is true, resources from CLDR have precedence over JRE
+            // native resources.
+            if (javatime && calendarNameProvider instanceof CalendarNameProviderImpl) {
+                Map<String, Integer> map;
+                map = ((CalendarNameProviderImpl)calendarNameProvider)
+                        .getJavaTimeDisplayNames(requestID, field, style, locale);
+                return map;
+            }
+            return calendarNameProvider.getDisplayNames(requestID, field, style, locale);
+        }
+    }
+
+     private static class CalendarWeekParameterGetter
+        implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,
+                                                                   Integer> {
+        private static final CalendarWeekParameterGetter INSTANCE =
+            new CalendarWeekParameterGetter();
+
+        @Override
+        public Integer getObject(CalendarDataProvider calendarDataProvider,
+                                 Locale locale,
+                                 String requestID,    // resource key
+                                 Object... params) {
+            assert params.length == 0;
+            int value;
+            switch (requestID) {
+            case FIRST_DAY_OF_WEEK:
+                value = calendarDataProvider.getFirstDayOfWeek(locale);
+                break;
+            case MINIMAL_DAYS_IN_FIRST_WEEK:
+                value = calendarDataProvider.getMinimalDaysInFirstWeek(locale);
+                break;
+            default:
+                throw new InternalError("invalid requestID: " + requestID);
+            }
+            return (value != 0) ? value : null;
+        }
+    }
+    */
+    // END Android-removed: Dead code, unused on Android.
 }
diff --git a/ojluni/src/main/native/Android.bp b/ojluni/src/main/native/Android.bp
index 71546ca..38a2a23 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,9 @@
         "System.c",
         "Runtime.c",
         "UNIXProcess_md.c",
-        "Bits.c",
         "Character.cpp",
-        "Register.cpp",
         "socket_tagger_util.cpp",
+        "OnLoad.cpp",
+        "JniConstants.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/DatagramChannelImpl.c b/ojluni/src/main/native/DatagramChannelImpl.c
index 925064f..11d149d 100644
--- a/ojluni/src/main/native/DatagramChannelImpl.c
+++ b/ojluni/src/main/native/DatagramChannelImpl.c
@@ -96,7 +96,9 @@
     rv = connect(fd, 0, 0);
 #endif
 
-#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
+// Android-changed: Fuchsia: Pass linux-style args to connect.
+// #if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
+#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX) || defined(__Fuchsia__)
     {
         int len;
         SOCKADDR sa;
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/EPoll.c b/ojluni/src/main/native/EPoll.c
index ea9cdf4..207ef72 100644
--- a/ojluni/src/main/native/EPoll.c
+++ b/ojluni/src/main/native/EPoll.c
@@ -60,7 +60,9 @@
      * epoll_create expects a size as a hint to the kernel about how to
      * dimension internal structures. We can't predict the size in advance.
      */
-    int epfd = epoll_create(256);
+    // Android-changed: Avoid FD leaks through epoll_create. http://b/120983106
+    // int epfd = epoll_create(256);
+    int epfd = epoll_create1(EPOLL_CLOEXEC);
     if (epfd < 0) {
        JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
     }
diff --git a/ojluni/src/main/native/FileChannelImpl.c b/ojluni/src/main/native/FileChannelImpl.c
index 5b428e9..51339df 100644
--- a/ojluni/src/main/native/FileChannelImpl.c
+++ b/ojluni/src/main/native/FileChannelImpl.c
@@ -51,6 +51,11 @@
 
 #define lseek64 lseek
 #define mmap64 mmap
+// BEGIN Android-added: Alias *64 on Fuchsia builds. http://b/119496969
+#elif defined(__Fuchsia__)
+#define lseek64 lseek
+#define mmap64 mmap
+// END Android-added: Alias *64 on Fuchsia builds. http://b/119496969
 #endif
 
 static jfieldID chan_fd;        /* jobject 'fd' in sun.io.FileChannelImpl */
diff --git a/ojluni/src/main/native/FileDispatcherImpl.c b/ojluni/src/main/native/FileDispatcherImpl.c
index 5a49a60..3e8e4f3 100644
--- a/ojluni/src/main/native/FileDispatcherImpl.c
+++ b/ojluni/src/main/native/FileDispatcherImpl.c
@@ -45,7 +45,9 @@
 #define NATIVE_METHOD(className, functionName, signature) \
 { #functionName, signature, (void*)(className ## _ ## functionName) }
 
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #define stat64 stat
 #define flock64 flock
 #define off64_t off_t
diff --git a/ojluni/src/main/native/FileInputStream.c b/ojluni/src/main/native/FileInputStream.c
index 2418c5d..58664a1 100644
--- a/ojluni/src/main/native/FileInputStream.c
+++ b/ojluni/src/main/native/FileInputStream.c
@@ -89,6 +89,12 @@
 }
 
 static int available(int fd, jlong *bytes) {
+// BEGIN Android-added: Fuchsia does not support FIONREAD. http://b/120566512
+#if defined(__Fuchsia__)
+  *bytes = 0;
+  return 1;
+#else
+// END Android-added: Fuchsia does not support FIONREAD. http://b/120566512
   int n;
   // Unlike the original OpenJdk implementation, we use FIONREAD for all file
   // types. For regular files, this is specified to return the difference
@@ -112,6 +118,8 @@
 
   // Raise an exception for all other error types.
   return 0;
+// Android-added: Fuchsia does not support the FIONREAD code. http://b/120566512
+#endif
 }
 
 JNIEXPORT jint JNICALL
diff --git a/ojluni/src/main/native/FileKey.c b/ojluni/src/main/native/FileKey.c
index b28fb56..c3b5d2a 100644
--- a/ojluni/src/main/native/FileKey.c
+++ b/ojluni/src/main/native/FileKey.c
@@ -33,7 +33,9 @@
 #define NATIVE_METHOD(className, functionName, signature) \
 { #functionName, signature, (void*)(className ## _ ## functionName) }
 
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Alias *64 on Fuchsia builds. http://b/119496969
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #define stat64 stat
 
 #define fstat64 fstat
diff --git a/ojluni/src/main/native/FileSystemPreferences.c b/ojluni/src/main/native/FileSystemPreferences.c
index 8ab516a..9a73150 100644
--- a/ojluni/src/main/native/FileSystemPreferences.c
+++ b/ojluni/src/main/native/FileSystemPreferences.c
@@ -52,7 +52,9 @@
     return (jint) result;
 }
 
-#if defined(_ALLBSD_SOURCE)
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 typedef struct flock FLOCK;
 #else
 typedef struct flock64 FLOCK;
@@ -94,7 +96,9 @@
     if (fd < 0) {
         result[0] = 0;
     } else {
-#if defined(_ALLBSD_SOURCE)
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
         rc = fcntl(fd, F_SETLK, &fl);
 #else
         rc = fcntl(fd, F_SETLK64, &fl);
@@ -127,8 +131,9 @@
     fl.l_len = 0;
     fl.l_start = 0;
     fl.l_type = F_UNLCK;
-
-#if defined(_ALLBSD_SOURCE)
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
     rc = fcntl(fd, F_SETLK, &fl);
 #else
     rc = fcntl(fd, F_SETLK64, &fl);
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/JniConstants.cpp b/ojluni/src/main/native/JniConstants.cpp
new file mode 100644
index 0000000..0eb499d
--- /dev/null
+++ b/ojluni/src/main/native/JniConstants.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "JniConstants"
+
+#include "JniConstants.h"
+
+#include <atomic>
+#include <mutex>
+
+#include <log/log.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace {
+
+jclass findClass(JNIEnv* env, const char* name) {
+    ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
+    jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
+    if (result == NULL) {
+        ALOGE("failed to find class '%s'", name);
+        abort();
+    }
+    return result;
+}
+
+// Mutex protecting static variables
+static std::mutex g_constants_mutex;
+
+// Flag indicating whether cached constants are valid
+static bool g_constants_valid = false;
+
+// Constants
+jclass g_socket_tagger_class;
+
+// EnsureJniConstantsInitialized initializes cache constants. It should be
+// called before returning a heap object from the cache to ensure cache is
+// initialized. This pattern is only necessary because if a process finishes one
+// runtime and starts another then JNI_OnLoad may not be called.
+void EnsureJniConstantsInitialized(JNIEnv* env) {
+    if (g_constants_valid) {
+        return;
+    }
+
+    std::lock_guard guard(g_constants_mutex);
+    if (g_constants_valid) {
+        return;
+    }
+
+    g_socket_tagger_class = findClass(env, "dalvik/system/SocketTagger");
+    g_constants_valid = true;
+}
+
+}  // namespace
+
+void JniConstants::Initialize(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+}
+
+void JniConstants::Invalidate() {
+    std::lock_guard guard(g_constants_mutex);
+    g_constants_valid = false;
+}
+
+jclass JniConstants::GetSocketTaggerClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return g_socket_tagger_class;
+}
diff --git a/ojluni/src/main/native/JniConstants.h b/ojluni/src/main/native/JniConstants.h
new file mode 100644
index 0000000..849f6b9
--- /dev/null
+++ b/ojluni/src/main/native/JniConstants.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef JNI_CONSTANTS_H_included
+#define JNI_CONSTANTS_H_included
+
+#include <jni.h>
+
+/**
+ * A cache to avoid calling FindClass at runtime.
+ */
+struct JniConstants {
+    // Initialized cached heap objects. This should be called in JNI_OnLoad.
+    static void Initialize(JNIEnv* env);
+
+    // Invalidate cached heap objects. This should be called in JNI_OnUnload.
+    static void Invalidate();
+
+    // Gets class representing SocketTagger from cache.
+    static jclass GetSocketTaggerClass(JNIEnv* env);
+};
+
+#endif  // JNI_CONSTANTS_H_included
diff --git a/ojluni/src/main/native/LinuxWatchService.c b/ojluni/src/main/native/LinuxWatchService.c
index 375aaa4..1f531d0 100644
--- a/ojluni/src/main/native/LinuxWatchService.c
+++ b/ojluni/src/main/native/LinuxWatchService.c
@@ -32,8 +32,14 @@
 #include <dlfcn.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+// Android-changed: Fuchsia: Point to correct location of header. http://b/119426171
+// #include <sys/poll.h>
+#if defined(__Fuchsia__)
+#include <poll.h>
+#else
 #include <sys/poll.h>
 #include <sys/inotify.h>
+#endif
 
 #include "sun_nio_fs_LinuxWatchService.h"
 
diff --git a/ojluni/src/main/native/MappedByteBuffer.c b/ojluni/src/main/native/MappedByteBuffer.c
index a5b0b04..72e840a 100644
--- a/ojluni/src/main/native/MappedByteBuffer.c
+++ b/ojluni/src/main/native/MappedByteBuffer.c
@@ -40,6 +40,11 @@
 Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address,
                                          jlong len, jint numPages)
 {
+// BEGIN Android-added: Fuchsia holds all pages in memory. http://b/119503290
+#if defined(__Fuchsia__)
+    return JNI_TRUE;
+#else
+// END Android-added: Fuchsia holds all pages in memory. http://b/119503290
     jboolean loaded = JNI_TRUE;
     int result = 0;
     int i = 0;
@@ -70,6 +75,8 @@
     }
     free(vec);
     return loaded;
+// Android-added: Fuchsia holds all pages in memory. http://b/119503290
+#endif
 }
 
 
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/NativeThread.c b/ojluni/src/main/native/NativeThread.c
index 3a1c5c1..dc21e5d 100644
--- a/ojluni/src/main/native/NativeThread.c
+++ b/ojluni/src/main/native/NativeThread.c
@@ -48,6 +48,13 @@
   #include <signal.h>
   /* Also defined in net/bsd_close.c */
   #define INTERRUPT_SIGNAL SIGIO
+// BEGIN Android-added: Fuchsia: Support for Fuchsia platform.
+#elif __Fuchsia__
+  #include <pthread.h>
+  #include <signal.h>
+  /* Also defined in net/bsd_close.c */
+  #define INTERRUPT_SIGNAL SIGIO
+// END Android-added: Fuchsia: Support for Fuchsia platform.
 #else
   #error "missing platform-specific definition here"
 #endif
diff --git a/ojluni/src/main/native/Net.c b/ojluni/src/main/native/Net.c
index 462830d..bcf984e 100644
--- a/ojluni/src/main/native/Net.c
+++ b/ojluni/src/main/native/Net.c
@@ -23,7 +23,13 @@
  * questions.
  */
 
+// Android-changed: Fuchsia: Point to correct location of header. http://b/119426171
+// #include <sys/poll.h>
+#if defined(__Fuchsia__)
+#include <poll.h>
+#else
 #include <sys/poll.h>
+#endif
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <string.h>
@@ -374,7 +380,13 @@
             struct sockaddr_in *sin;
             sin = (struct sockaddr_in *) &sa;
             bzero(sin, sizeof(*sin));
+            // BEGIN Android-changed: Fuchsia: sin_len is not a sockaddr_in member on Fuchsia.
+            // http://b/119497331
+            // sin->sin_len = sizeof(struct sockaddr_in);
+#if !defined(__Fuchsia__)
             sin->sin_len  = sizeof(struct sockaddr_in);
+#endif
+            // END Android-changed: Fuchsia: sin_len is not a sockaddr_in member on Fuchsia.
             sin->sin_family = AF_INET;
             sin->sin_port = htonl(0);
             sin->sin_addr.s_addr = INADDR_ANY;
@@ -409,7 +421,13 @@
             struct sockaddr_in *sin;
             sin = (struct sockaddr_in *) &sa;
             bzero(sin, sizeof(*sin));
+            // BEGIN Android-changed: Fuchsia: sin_len is not a sockaddr_in member on Fuchsia.
+            // http://b/119497331
+            // sin->sin_len = sizeof(struct sockaddr_in);
+#if !defined(__Fuchsia__)
             sin->sin_len  = sizeof(struct sockaddr_in);
+#endif
+            // END Android-changed: Fuchsia: sin_len is not a sockaddr_in member on Fuchsia.
             sin->sin_family = AF_INET;
             sin->sin_port = htonl(0);
             sin->sin_addr.s_addr = INADDR_ANY;
diff --git a/ojluni/src/main/native/ObjectStreamClass.c b/ojluni/src/main/native/ObjectStreamClass.c
index 95cd4f0..3d3fdef 100644
--- a/ojluni/src/main/native/ObjectStreamClass.c
+++ b/ojluni/src/main/native/ObjectStreamClass.c
@@ -51,12 +51,19 @@
  * otherwise.
  */
 JNIEXPORT jboolean JNICALL
+// Android-changed: Added inheritStaticInitializer parameter.
+// The inheritStaticInitializer parameter is set to JNI_TRUE when behavior compatible with
+// Android version 23 is required.
 ObjectStreamClass_hasStaticInitializer(JNIEnv *env, jclass this,
                                        jclass clazz,
-                                       jboolean checkSuperclass)
+                                       jboolean inheritStaticInitializer)
 {
     jclass superCl = NULL;
     jmethodID superClinitId = NULL;
+
+    // Android-changed: Added comment to explain behavior.
+    // Search for a static initializer method in this class and up through its
+    // ancestor super classes, returning the id of the first method found.
     jmethodID clinitId =
         (*env)->GetStaticMethodID(env, clazz, "<clinit>", "()V");
     if (clinitId == NULL) {     /* error thrown */
@@ -68,13 +75,15 @@
         return JNI_FALSE;
     }
 
-    // Android-changed, if checkSuperclass == true, remove check for
-    // superclass clinitId != child clinitId.
-    // We're returning true to enable deserializing classes without explicit serialVersionID
-    // that would fail in this check (b/29064453).
-    if (checkSuperclass == JNI_FALSE) {
+    // BEGIN Android-changed: Exit immediately if version 23 behavior is required.
+    // At this point the class or one of its ancestor super classes has a
+    // static initializer. If inheritStaticInitializer is true then this method
+    // can simply return true. Otherwise, it needs to check that the static
+    // initializer was not inherited (b/29064453).
+    if (inheritStaticInitializer == JNI_TRUE) {
         return JNI_TRUE;
     }
+    // END Android-changed: Exit immediately if version 23 behavior is required.
 
     /*
      * Check superclass for static initializer as well--if the same method ID
@@ -83,6 +92,7 @@
      * JNI spec makes no guarantee that GetStaticMethodID will not return the
      * ID for a superclass initializer.
      */
+
     if ((superCl = (*env)->GetSuperclass(env, clazz)) == NULL) {
         return JNI_TRUE;
     }
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..c550c76 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -29,9 +29,10 @@
 
 #include <log/log.h>
 
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalFrame.h>
 
+#include "JniConstants.h"
+
 extern "C" {
 
 extern void register_java_io_Console(JNIEnv* env);
@@ -58,7 +59,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 +126,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);
@@ -135,5 +134,11 @@
     register_sun_nio_ch_DatagramDispatcher(env);
     register_java_nio_MappedByteBuffer(env);
     net_JNI_OnLoad(vm, NULL);
+
+    JniConstants::Initialize(env);
     return JNI_VERSION_1_6;
 }
+
+void JNI_OnUnload(JavaVM* vm, void*) {
+    JniConstants::Invalidate();
+}
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
index 4c023b5..749511e 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();
 }
@@ -75,19 +75,19 @@
 
 JNIEXPORT jstring JNICALL
 Runtime_nativeLoad(JNIEnv* env, jclass ignored, jstring javaFilename,
-                   jobject javaLoader)
+                   jobject javaLoader, jclass caller)
 {
-    return JVM_NativeLoad(env, javaFilename, javaLoader);
+    return JVM_NativeLoad(env, javaFilename, javaLoader, caller);
 }
 
 static JNINativeMethod gMethods[] = {
   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;)"
+                "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Class;)"
                     "Ljava/lang/String;"),
 };
 
diff --git a/ojluni/src/main/native/String.c b/ojluni/src/main/native/String.c
deleted file mode 100644
index 011089d..0000000
--- a/ojluni/src/main/native/String.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 1998, 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 "jvm.h"
-#include <nativehelper/JNIHelp.h>
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-
-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));
-}
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..40fdc18 100644
--- a/ojluni/src/main/native/UNIXProcess_md.c
+++ b/ojluni/src/main/native/UNIXProcess_md.c
@@ -44,7 +44,9 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <ctype.h>
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Fuchsia: Point to correct location of header. http://b/119426171
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) && !defined(__Fuchsia__)
 #include <wait.h>
 #else
 #include <sys/wait.h>
@@ -117,7 +119,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
@@ -384,7 +387,17 @@
 restartableClose(int fd)
 {
     int err;
-    RESTARTABLE(close(fd), err);
+    // Android-changed: do not retry EINTR close() failures. b/20501816
+    // Note: This code was removed upstream in OpenJDK 7u50,
+    // commit http://hg.openjdk.java.net/jdk/jdk/rev/e2e5122cd62e
+    // relating to upstream bug JDK-5049299. The entire file was
+    // then dropped in favor of .java code in upstream OpenJDK 9,
+    // commit http://hg.openjdk.java.net/jdk/jdk/rev/fe8344cf6496
+    //
+    // If we integrate OpenJDK 7u50+, this Android patch can be dropped.
+    //
+    // RESTARTABLE(close(fd), err);
+    err = close(fd);
     return err;
 }
 
@@ -400,7 +413,9 @@
   return c >= '0' && c <= '9';
 }
 
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #define FD_DIR "/dev/fd"
 #define dirent64 dirent
 #define readdir64 readdir
@@ -491,7 +506,9 @@
 
     if (errnum != 0) {
         const char *s = strerror(errnum);
-        if (strcmp(s, "Unknown error") != 0)
+        // Android-changed: Fix logic for recognizing error strings. http://b/110019823
+        // if (strcmp(s, "Unknown error") != 0)
+        if (strstr(s, "Unknown error") == 0)
             detail = s;
     }
     /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
diff --git a/ojluni/src/main/native/UnixFileSystem_md.c b/ojluni/src/main/native/UnixFileSystem_md.c
index 0c53f09..9c1ca05 100644
--- a/ojluni/src/main/native/UnixFileSystem_md.c
+++ b/ojluni/src/main/native/UnixFileSystem_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,9 +44,13 @@
 
 #include <nativehelper/JNIHelp.h>
 
-#if defined(_ALLBSD_SOURCE)
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #define dirent64 dirent
-#define readdir64_r readdir_r
+// Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+// #define readdir64_r readdir_r
+#define readdir64 readdir
 #define stat64 stat
 #define statvfs64 statvfs
 #endif
@@ -72,6 +76,8 @@
 
 /* -- Path operations -- */
 
+// Android-changed: hidden to avoid conflict with libm (b/135018555)
+__attribute__((visibility("hidden")))
 extern int canonicalize(char *path, const char *out, int len);
 
 JNIEXPORT jstring JNICALL
@@ -133,18 +139,15 @@
     return rv;
 }
 
-// Android-changed: Name changed because of added thread policy check
+// BEGIN Android-removed: Access files through common interface.
+/*
 JNIEXPORT jboolean JNICALL
-Java_java_io_UnixFileSystem_checkAccess0(JNIEnv *env, jobject this,
-                                         jobject file, jint a)
+Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,
+                                        jobject file, jint a)
 {
     jboolean rv = JNI_FALSE;
     int mode = 0;
     switch (a) {
-    // Android-changed: Added ACCESS_OK case
-    case java_io_FileSystem_ACCESS_OK:
-        mode = F_OK;
-        break;
     case java_io_FileSystem_ACCESS_READ:
         mode = R_OK;
         break;
@@ -163,6 +166,8 @@
     } END_PLATFORM_STRING(env, path);
     return rv;
 }
+*/
+// END Android-removed: Access files through common interface.
 
 // Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
@@ -228,10 +233,11 @@
     return rv;
 }
 
-// Android-changed: Name changed because of added thread policy check
+// BEGIN Android-removed: Access files through common interface.
+/*
 JNIEXPORT jlong JNICALL
-Java_java_io_UnixFileSystem_getLength0(JNIEnv *env, jobject this,
-                                       jobject file)
+Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
+                                      jobject file)
 {
     jlong rv = 0;
 
@@ -243,6 +249,8 @@
     } END_PLATFORM_STRING(env, path);
     return rv;
 }
+*/
+// END Android-removed: Access files through common interface.
 
 
 /* -- File operations -- */
@@ -273,6 +281,8 @@
 }
 
 
+// BEGIN Android-removed: Access files through common interface.
+/*
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
                                     jobject file)
@@ -286,6 +296,8 @@
     } END_PLATFORM_STRING(env, path);
     return rv;
 }
+*/
+// END Android-removed: Access files through common interface.
 
 // Android-changed: Name changed because of added thread policy check
 JNIEXPORT jobjectArray JNICALL
@@ -294,7 +306,8 @@
 {
     DIR *dir = NULL;
     struct dirent64 *ptr;
-    struct dirent64 *result;
+    // Android-removed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+    // struct dirent64 *result;
     int len, maxlen;
     jobjectArray rv, old;
     jclass str_class;
@@ -308,12 +321,15 @@
     } END_PLATFORM_STRING(env, path);
     if (dir == NULL) return NULL;
 
+    // Android-removed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+    /*
     ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
     if (ptr == NULL) {
         JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
         closedir(dir);
         return NULL;
     }
+    */
 
     /* Allocate an initial String array */
     len = 0;
@@ -322,7 +338,9 @@
     if (rv == NULL) goto error;
 
     /* Scan the directory */
-    while ((readdir64_r(dir, ptr, &result) == 0)  && (result != NULL)) {
+    // Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+    // while ((readdir64_r(dir, ptr, &result) == 0)  && (result != NULL)) {
+    while ((ptr = readdir64(dir)) != NULL) {
         jstring name;
         if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
             continue;
@@ -343,7 +361,8 @@
         (*env)->DeleteLocalRef(env, name);
     }
     closedir(dir);
-    free(ptr);
+    // Android-removed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+    // free(ptr);
 
     /* Copy the final results into an appropriately-sized array */
     old = rv;
@@ -358,7 +377,8 @@
 
  error:
     closedir(dir);
-    free(ptr);
+    // Android-removed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+    // free(ptr);
     return NULL;
 }
 
@@ -378,6 +398,8 @@
 }
 
 
+// BEGIN Android-removed: Access files through common interface.
+/*
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
                                     jobject from, jobject to)
@@ -393,6 +415,8 @@
     } END_PLATFORM_STRING(env, fromPath);
     return rv;
 }
+*/
+// END Android-removed: Access files through common interface.
 
 // Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
@@ -477,15 +501,11 @@
     NATIVE_METHOD(UnixFileSystem, initIDs, "()V"),
     NATIVE_METHOD(UnixFileSystem, canonicalize0, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(UnixFileSystem, getBooleanAttributes0, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(UnixFileSystem, checkAccess0, "(Ljava/io/File;I)Z"),
     NATIVE_METHOD(UnixFileSystem, setPermission0, "(Ljava/io/File;IZZ)Z"),
     NATIVE_METHOD(UnixFileSystem, getLastModifiedTime0, "(Ljava/io/File;)J"),
-    NATIVE_METHOD(UnixFileSystem, getLength0, "(Ljava/io/File;)J"),
     NATIVE_METHOD(UnixFileSystem, createFileExclusively0, "(Ljava/lang/String;)Z"),
-    NATIVE_METHOD(UnixFileSystem, delete0, "(Ljava/io/File;)Z"),
     NATIVE_METHOD(UnixFileSystem, list0, "(Ljava/io/File;)[Ljava/lang/String;"),
     NATIVE_METHOD(UnixFileSystem, createDirectory0, "(Ljava/io/File;)Z"),
-    NATIVE_METHOD(UnixFileSystem, rename0, "(Ljava/io/File;Ljava/io/File;)Z"),
     NATIVE_METHOD(UnixFileSystem, setLastModifiedTime0, "(Ljava/io/File;J)Z"),
     NATIVE_METHOD(UnixFileSystem, setReadOnly0, "(Ljava/io/File;)Z"),
     NATIVE_METHOD(UnixFileSystem, getSpace0, "(Ljava/io/File;I)J"),
diff --git a/ojluni/src/main/native/UnixNativeDispatcher.c b/ojluni/src/main/native/UnixNativeDispatcher.c
index e8a1623..633a989 100644
--- a/ojluni/src/main/native/UnixNativeDispatcher.c
+++ b/ojluni/src/main/native/UnixNativeDispatcher.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,9 @@
 #include <string.h>
 #endif
 
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #include <string.h>
 
 #define stat64 stat
@@ -56,7 +58,10 @@
 #define fstat64 fstat
 #define lstat64 lstat
 #define dirent64 dirent
-#define readdir64_r readdir_r
+// Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+// Integrate UnixNativeDispatcher.c changes from http://hg.openjdk.java.net/jdk/jdk/rev/90144bc10fe6
+// #define readdir64_r readdir_r
+#define readdir64 readdir
 #endif
 
 #include "jni.h"
@@ -408,9 +413,22 @@
 
 JNIEXPORT void JNICALL
 Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
-    int err;
-    /* TDB - need to decide if EIO and other errors should cause exception */
-    RESTARTABLE(close((int)fd), err);
+// BEGIN Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+//    int err;
+//    /* TDB - need to decide if EIO and other errors should cause exception */
+//    RESTARTABLE(close((int)fd), err);
+    int res;
+
+#if defined(_AIX)
+    /* AIX allows close to be restarted after EINTR */
+    RESTARTABLE(close((int)fd), res);
+#else
+    res = close((int)fd);
+#endif
+    if (res == -1 && errno != EINTR) {
+        throwUnixException(env, errno);
+    }
+// END Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
 }
 
 JNIEXPORT jint JNICALL
@@ -685,6 +703,8 @@
 
 JNIEXPORT jbyteArray JNICALL
 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
+// BEGIN Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
+/*
     struct dirent64* result;
     struct {
         struct dirent64 buf;
@@ -694,13 +714,13 @@
     int res;
     DIR* dirp = jlong_to_ptr(value);
 
-    /* EINTR not listed as a possible error */
-    /* TDB: reentrant version probably not required here */
+    * EINTR not listed as a possible error *
+    * TDB: reentrant version probably not required here *
     res = readdir64_r(dirp, ptr, &result);
 
 #ifdef _AIX
-    /* On AIX, readdir_r() returns EBADF (i.e. '9') and sets 'result' to NULL for the */
-    /* directory stream end. Otherwise, 'errno' will contain the error code. */
+    * On AIX, readdir_r() returns EBADF (i.e. '9') and sets 'result' to NULL for the *
+    * directory stream end. Otherwise, 'errno' will contain the error code. *
     if (res != 0) {
         res = (result == NULL && res == EBADF) ? 0 : errno;
     }
@@ -721,6 +741,26 @@
             return bytes;
         }
     }
+*/
+    DIR* dirp = jlong_to_ptr(value);
+    struct dirent64* ptr;
+
+    errno = 0;
+    ptr = readdir64(dirp);
+    if (ptr == NULL) {
+        if (errno != 0) {
+            throwUnixException(env, errno);
+        }
+        return NULL;
+    } else {
+        jsize len = strlen(ptr->d_name);
+        jbyteArray bytes = (*env)->NewByteArray(env, len);
+        if (bytes != NULL) {
+            (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
+        }
+        return bytes;
+    }
+// END Android-changed: Integrate OpenJDK 12 commit to use readdir, not readdir_r. b/64362645
 }
 
 JNIEXPORT void JNICALL
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/canonicalize_md.c b/ojluni/src/main/native/canonicalize_md.c
index 832cae3..b62ba6d 100644
--- a/ojluni/src/main/native/canonicalize_md.c
+++ b/ojluni/src/main/native/canonicalize_md.c
@@ -186,6 +186,8 @@
    work, though once that's done we still must collapse any remaining "." and
    ".." names by hand. */
 
+// Android-changed: hidden to avoid conflict with libm (b/135018555)
+__attribute__((visibility("hidden")))
 int
 canonicalize(char *original, char *resolved, int len)
 {
diff --git a/ojluni/src/main/native/io_util_md.c b/ojluni/src/main/native/io_util_md.c
index 8b8a687..39ceb4a 100644
--- a/ojluni/src/main/native/io_util_md.c
+++ b/ojluni/src/main/native/io_util_md.c
@@ -30,6 +30,14 @@
 #include "io_util_md.h"
 #include <string.h>
 
+// BEGIN Android-added: Fuchsia: Alias *64 functions on Fuchsia. http://b/119496969
+#if defined(__Fuchsia__)
+#define stat64 stat
+#define fstat64 fstat
+#define open64 open
+#endif
+// END Android-added: Fuchsia: Alias *64 functions on Fuchsia. http://b/119496969
+
 #ifdef MACOSX
 
 #include <CoreFoundation/CoreFoundation.h>
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/jni_util.c b/ojluni/src/main/native/jni_util.c
index 599f27d..6c6e5ba 100644
--- a/ojluni/src/main/native/jni_util.c
+++ b/ojluni/src/main/native/jni_util.c
@@ -839,6 +839,8 @@
  * VM can find it when loading system classes.
  *
  */
+// Android-changed: hidden to avoid conflict with libm (b/135018555)
+__attribute__((visibility("hidden")))
 extern int canonicalize(char *path, const char *out, int len);
 
 JNIEXPORT int
diff --git a/ojluni/src/main/native/jvm.h b/ojluni/src/main/native/jvm.h
index 83067ce..fd15abf 100644
--- a/ojluni/src/main/native/jvm.h
+++ b/ojluni/src/main/native/jvm.h
@@ -166,7 +166,7 @@
 JVM_ActiveProcessorCount(void);
 
 JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename,
-                                 jobject javaLoader);
+                                 jobject javaLoader, jclass caller);
 
 JNIEXPORT void * JNICALL
 JVM_LoadLibrary(const char *name);
diff --git a/ojluni/src/main/native/jvm_md.h b/ojluni/src/main/native/jvm_md.h
index a366445..54743c6 100644
--- a/ojluni/src/main/native/jvm_md.h
+++ b/ojluni/src/main/native/jvm_md.h
@@ -65,7 +65,13 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+// Android-changed: Fuchsia: Point to correct header location. http://b/119426171
+// #include <sys/signal.h>
+#if !defined(__Fuchsia__)
 #include <sys/signal.h>
+#else
+#include <signal.h>
+#endif
 
 /* O Flags */
 
diff --git a/ojluni/src/main/native/linux_close.cpp b/ojluni/src/main/native/linux_close.cpp
index e100035..a4d1457 100644
--- a/ojluni/src/main/native/linux_close.cpp
+++ b/ojluni/src/main/native/linux_close.cpp
@@ -35,10 +35,15 @@
 #include <unistd.h>
 #include <errno.h>
 
+// Android-changed: Fuchsia: Fix poll.h include location
+// #include <sys/poll.h>
+#if !defined(__Fuchsia__)
 #include <sys/poll.h>
+#else
+#include <poll.h>
+#endif
 
-
-#include <nativehelper/AsynchronousCloseMonitor.h>
+#include <AsynchronousCloseMonitor.h>
 
 extern "C" {
 
diff --git a/ojluni/src/main/native/net_util_md.h b/ojluni/src/main/native/net_util_md.h
index 94a8877..0bef5b9 100644
--- a/ojluni/src/main/native/net_util_md.h
+++ b/ojluni/src/main/native/net_util_md.h
@@ -33,11 +33,18 @@
 #include <unistd.h>
 
 #ifndef USE_SELECT
+// Android-changed: Fuchsia: Point to correct location of header. http://b/119426171
+// #include <sys/poll.h>
+#if !defined(__Fuchsia__)
 #include <sys/poll.h>
+#else
+#include <poll.h>
+#endif
 #endif
 
-
-#if defined(__linux__) || defined(MACOSX)
+// Android-changed: Fuchsia: Use the non-JVM NET_* on Fuchsia also.
+// #if defined(__linux__) || defined(MACOSX)
+#if defined(__linux__) || defined(MACOSX) || defined(__Fuchsia__)
 extern int NET_Timeout(int s, long timeout);
 extern int NET_Read(int s, void* buf, size_t len);
 extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
diff --git a/ojluni/src/main/native/socket_tagger_util.cpp b/ojluni/src/main/native/socket_tagger_util.cpp
index b62898f..cdac52b 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
@@ -19,22 +20,22 @@
  */
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 
-extern "C" {
+#include "JniConstants.h"
 
-int tagSocket(JNIEnv* env, int fd) {
-    if (env->ExceptionOccurred()) { return fd; }
-    jmethodID get = env->GetStaticMethodID(JniConstants::socketTaggerClass,
-                                           "get", "()Ldalvik/system/SocketTagger;");
-    jobject socketTagger =
-        env->CallStaticObjectMethod(JniConstants::socketTaggerClass, get);
-    jmethodID tag = env->GetMethodID(JniConstants::socketTaggerClass,
-                                     "tag", "(Ljava/io/FileDescriptor;)V");
+extern "C" int tagSocket(JNIEnv* env, int fd) {
+    if (env->ExceptionOccurred()) {
+      return fd;
+    }
+
+    jclass socketTaggerClass = JniConstants::GetSocketTaggerClass(env);
+    jmethodID get = env->GetStaticMethodID(socketTaggerClass,
+                                           "get",
+                                           "()Ldalvik/system/SocketTagger;");
+    jobject socketTagger = env->CallStaticObjectMethod(socketTaggerClass, get);
+    jmethodID tag = env->GetMethodID(socketTaggerClass, "tag", "(Ljava/io/FileDescriptor;)V");
 
     jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
     env->CallVoidMethod(socketTagger, tag, fileDescriptor);
     return fd;
 }
-
-}
diff --git a/ojluni/src/main/native/zip_util.c b/ojluni/src/main/native/zip_util.c
index e2503e8..6c02d2b 100644
--- a/ojluni/src/main/native/zip_util.c
+++ b/ojluni/src/main/native/zip_util.c
@@ -47,7 +47,9 @@
 #include "zip_util.h"
 #include <zlib.h>
 
-#ifdef _ALLBSD_SOURCE
+// Android-changed: Fuchsia: Alias *64 on Fuchsia builds. http://b/119496969
+// #ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE) || defined(__Fuchsia__)
 #define off64_t off_t
 #define mmap64 mmap
 #endif
diff --git a/ojluni/src/main/resources/java/lang/uniName.dat b/ojluni/src/main/resources/java/lang/uniName.dat
deleted file mode 100644
index 4b793b5..0000000
--- a/ojluni/src/main/resources/java/lang/uniName.dat
+++ /dev/null
Binary files differ
diff --git a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
index 394d6d5..091b385 100644
--- a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
+++ b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java
@@ -112,21 +112,6 @@
 @Test
 public class TCKJapaneseChronology {
 
-    // Android-added: Add a static field to indicate if the device supports the new Japanese era.
-    /**
-     * Indicates if the device support newer Japenese Era than Heisei. Old Android releases can
-     * optionally support new Japanese Era, e.g. Reiwa, and Android test suites, e.g. CTS, can use
-     * this flag to alter the expected result. This flag can be placed in other classes, but
-     * TCKJapaneseChronology is picked arbitrarily.
-     */
-    public static final boolean IS_HEISEI_LATEST;
-    static {
-        List<Era> japaneseEras = JapaneseChronology.INSTANCE.eras();
-        IS_HEISEI_LATEST =
-            japaneseEras.get(japaneseEras.size()-1).getValue() <= JapaneseEra.HEISEI.getValue();
-    }
-
-
     // Year differences from Gregorian years.
     private static final int YDIFF_REIWA = 2018;
     private static final int YDIFF_HEISEI = 1988;
@@ -191,10 +176,7 @@
     @DataProvider(name="createByEra")
     Object[][] data_createByEra() {
         return new Object[][] {
-                // Android-changed: Old Android releases can optionally support the new Japanese era.
-                IS_HEISEI_LATEST
-                    ? new Object[] {JapaneseEra.HEISEI, 2020 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2020, 2, 29)}
-                    : new Object[] {JapaneseEra.of(3), 2020 - YDIFF_REIWA, 2, 29, 60, LocalDate.of(2020, 2, 29)}, // NEWERA
+                {JapaneseEra.of(3), 2020 - YDIFF_REIWA, 2, 29, 60, LocalDate.of(2020, 2, 29)}, // NEWERA
                 {JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(1996, 2, 29)},
                 {JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2000, 2, 29)},
                 {JapaneseEra.MEIJI, 1874 - YDIFF_MEIJI, 2, 28, 59, LocalDate.of(1874, 2, 28)},
@@ -387,13 +369,8 @@
     @DataProvider(name="prolepticYear")
     Object[][] data_prolepticYear() {
         return new Object[][] {
-                // Android-changed: Old Android releases can optionally support the new Japanese era.
-                IS_HEISEI_LATEST
-                    ? new Object[] {2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false}
-                    : new Object[] {3, JapaneseEra.of(3), 1, 1 + YDIFF_REIWA, false},
-                IS_HEISEI_LATEST
-                    ? new Object[] {2, JapaneseEra.HEISEI, 102, 102 + YDIFF_HEISEI, false}
-                    : new Object[] {3, JapaneseEra.of(3), 102, 102 + YDIFF_REIWA, true},
+                {3, JapaneseEra.of(3), 1, 1 + YDIFF_REIWA, false},
+                {3, JapaneseEra.of(3), 102, 102 + YDIFF_REIWA, true},
 
                 {2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false},
                 {2, JapaneseEra.HEISEI, 4, 4 + YDIFF_HEISEI, true},
@@ -573,21 +550,12 @@
     //-----------------------------------------------------------------------
     @DataProvider(name="japaneseEras")
     Object[][] data_japanseseEras() {
-        // Android-changed: Old Android releases can optionally support the new Japanese era.
-        if (!IS_HEISEI_LATEST) {
-            return new Object[][] {
-                { JapaneseEra.MEIJI, -1, "Meiji"},
-                { JapaneseEra.TAISHO, 0, "Taisho"},
-                { JapaneseEra.SHOWA, 1, "Showa"},
-                { JapaneseEra.HEISEI, 2, "Heisei"},
-                { JapaneseEra.of(3), 3, "Reiwa"},
-            };
-        }
         return new Object[][] {
             { JapaneseEra.MEIJI, -1, "Meiji"},
             { JapaneseEra.TAISHO, 0, "Taisho"},
             { JapaneseEra.SHOWA, 1, "Showa"},
             { JapaneseEra.HEISEI, 2, "Heisei"},
+            { JapaneseEra.of(3), 3, "Reiwa"},
         };
     }
 
@@ -723,10 +691,7 @@
             {JapaneseChronology.INSTANCE.date(1989,  1,  7), "Japanese Showa 64-01-07"},
             {JapaneseChronology.INSTANCE.date(1989,  1,  8), "Japanese Heisei 1-01-08"},
             {JapaneseChronology.INSTANCE.date(2012, 12,  6), "Japanese Heisei 24-12-06"},
-            // Android-changed: Old Android releases can optionally support the new Japanese era.
-            IS_HEISEI_LATEST
-                ? new Object[] {JapaneseChronology.INSTANCE.date(2020,  1,  6), "Japanese Heisei 32-01-06"}
-                : new Object[] {JapaneseChronology.INSTANCE.date(2020,  1,  6), "Japanese Reiwa 2-01-06"},
+            {JapaneseChronology.INSTANCE.date(2020,  1,  6), "Japanese Reiwa 2-01-06"},
         };
     }
 
diff --git a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
index 815517c..e37a6a5 100644
--- a/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
+++ b/ojluni/src/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java
@@ -59,7 +59,6 @@
 import static java.time.temporal.ChronoField.ERA;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
-import static tck.java.time.chrono.TCKJapaneseChronology.IS_HEISEI_LATEST;
 
 import java.time.chrono.Era;
 import java.time.chrono.JapaneseChronology;
@@ -77,17 +76,8 @@
 
     @DataProvider(name = "JapaneseEras")
     Object[][] data_of_eras() {
-        // Android-changed: Old Android releases can optionally support the new Japanese era.
-        if (!IS_HEISEI_LATEST) {
-            return new Object[][] {
-                        {JapaneseEra.of(3), "Reiwa", 3},
-                        {JapaneseEra.HEISEI, "Heisei", 2},
-                        {JapaneseEra.SHOWA, "Showa", 1},
-                        {JapaneseEra.TAISHO, "Taisho", 0},
-                        {JapaneseEra.MEIJI, "Meiji", -1},
-            };
-        }
         return new Object[][] {
+                    {JapaneseEra.of(3), "Reiwa", 3},
                     {JapaneseEra.HEISEI, "Heisei", 2},
                     {JapaneseEra.SHOWA, "Showa", 1},
                     {JapaneseEra.TAISHO, "Taisho", 0},
diff --git a/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java b/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
index 337a8db..03443d9 100644
--- a/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
+++ b/ojluni/src/test/java/time/test/java/time/chrono/TestJapaneseChronology.java
@@ -28,7 +28,6 @@
 import java.time.*;
 import java.time.chrono.*;
 import java.time.temporal.*;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
@@ -36,7 +35,6 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
-import static tck.java.time.chrono.TCKJapaneseChronology.IS_HEISEI_LATEST;
 
 /**
  * Tests for the Japanese chronology
@@ -48,8 +46,7 @@
 
     @DataProvider(name="transitions")
     Object[][] transitionData() {
-        // Android-changed: Old Android releases can optionally support the new Japanese era.
-        List<Object[]> data = Arrays.asList(new Object[][] {
+        return new Object[][] {
             // Japanese era, yearOfEra, month, dayOfMonth, gregorianYear
             { JapaneseEra.MEIJI,      6,  1,  1, 1873 },
             // Meiji-Taisho transition isn't accurate. 1912-07-30 is the last day of Meiji
@@ -62,20 +59,14 @@
             { JapaneseEra.SHOWA,      1, 12, 25, 1926 },
             { JapaneseEra.SHOWA,     64,  1,  7, 1989 },
             { JapaneseEra.HEISEI,     1,  1,  8, 1989 },
-        });
-        if (IS_HEISEI_LATEST) {
-            data.addAll(Arrays.asList(new Object[][] {
-                { JapaneseEra.HEISEI,    31,  4, 30, 2019 },
-                { JapaneseEra.of(3),      1,  5,  1, 2019 },
-            }));
-        }
-        return data.toArray(new Object[data.size()][]);
+            { JapaneseEra.HEISEI,    31,  4, 30, 2019 },
+            { JapaneseEra.of(3),      1,  5,  1, 2019 },
+        };
     }
 
     @DataProvider(name="day_year_data")
     Object[][] dayYearData() {
-        // Android-changed: Old Android releases can optionally support the new Japanese era.
-        List<Object[]> data = Arrays.asList(new Object[][] {
+        return new Object[][] {
             // Japanese era, yearOfEra, dayOfYear, month, dayOfMonth
             { JapaneseEra.MEIJI,  45,  211,  7, 29 },
             { JapaneseEra.TAISHO,  1,    1,  7, 30 },
@@ -86,25 +77,17 @@
             { JapaneseEra.SHOWA,  64,    7,  1,  7 },
             { JapaneseEra.HEISEI,  1,    1,  1,  8 },
             { JapaneseEra.HEISEI,  2,    8,  1,  8 },
-        });
-        if (IS_HEISEI_LATEST) {
-            data.addAll(Arrays.asList(new Object[][] {
-                { JapaneseEra.HEISEI, 31,  120,  4, 30 },
-                { JapaneseEra.of(3),   1,    1,  5,  1 },
-            }));
-        }
-        return data.toArray(new Object[data.size()][]);
+            { JapaneseEra.HEISEI, 31,  120,  4, 30 },
+            { JapaneseEra.of(3),   1,    1,  5,  1 },
+        };
     }
 
     @DataProvider(name="range_data")
     Object[][] rangeData() {
-        // Android-changed: Old Android releases can optionally support the new Japanese era.
-        int maxEra = IS_HEISEI_LATEST ? 2 : 3;
-        int yearOfLatestEra = IS_HEISEI_LATEST ? 1989 : 2019;
         return new Object[][] {
             // field, minSmallest, minLargest, maxSmallest, maxLargest
-            { ChronoField.ERA,         -1, -1, maxEra, maxEra},
-            { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-yearOfLatestEra}, // depends on the current era
+            { ChronoField.ERA,         -1, -1, 3, 3},
+            { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-2019}, // depends on the current era
             { ChronoField.DAY_OF_YEAR, 1, 1, 7, 366},
             { ChronoField.YEAR, 1873, 1873, 999999999, 999999999},
         };
diff --git a/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
index e2f2b77..f86f144 100644
--- a/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
+++ b/ojluni/src/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
@@ -33,7 +33,6 @@
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
-import static tck.java.time.chrono.TCKJapaneseChronology.IS_HEISEI_LATEST;
 
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
@@ -777,10 +776,9 @@
             {HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"},
             {HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"},
             {HijrahDate.of(1440,8,25), "Japanese Heisei 31-04-30"},
-            // Android-changed: Old Android releases can optionally support the new Japanese era.
-            {HijrahDate.of(1440,8,26), IS_HEISEI_LATEST ? "Japanese Heisei 31-05-01" : "Japanese Reiwa 1-05-01"},
-            {HijrahDate.of(1500,6,12), IS_HEISEI_LATEST ? "Japanese Heisei 89-05-05" : "Japanese Reiwa 59-05-05"},
-            {HijrahDate.of(1550,3,11), IS_HEISEI_LATEST ? "Japanese Heisei 137-08-11" : "Japanese Reiwa 107-08-11"},
+            {HijrahDate.of(1440,8,26), "Japanese Reiwa 1-05-01"},
+            {HijrahDate.of(1500,6,12), "Japanese Reiwa 59-05-05"},
+            {HijrahDate.of(1550,3,11), "Japanese Reiwa 107-08-11"},
         };
     }
 
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java b/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
index e53adad..310f008 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestNonIsoFormatter.java
@@ -30,7 +30,6 @@
 package test.java.time.format;
 
 import static org.testng.Assert.assertEquals;
-import static tck.java.time.chrono.TCKJapaneseChronology.IS_HEISEI_LATEST;
 
 import java.time.LocalDate;
 import java.time.chrono.ChronoLocalDate;
@@ -151,8 +150,7 @@
             // Android-changed: Eras names have been changed in CLDR data.
             // { JAPANESE, "Showa 65", "Heisei 2" }
             { JAPANESE, "Shōwa 65", "Heisei 2" },
-            // Android-changed: Old Android releases can optionally support the new Japanese era.
-            { JAPANESE, "Heisei 32", IS_HEISEI_LATEST ? "Heisei 32" : "Reiwa 2" },
+            { JAPANESE, "Heisei 32", "Reiwa 2" },
         };
     }
 
diff --git a/openjdk_java_files.bp b/openjdk_java_files.bp
index c574f2d..c1f29ea 100644
--- a/openjdk_java_files.bp
+++ b/openjdk_java_files.bp
@@ -1,7 +1,7 @@
+// Classes which are part of the public API, except where classes and
+// members are hidden using @hide javadoc tags.
 filegroup {
     name: "openjdk_javadoc_files",
-    export_to_make_var: "openjdk_javadoc_files",
-    path: "ojluni/src/lambda/java",
     srcs: [
         "ojluni/src/main/java/java/awt/font/NumericShaper.java",
         "ojluni/src/main/java/java/awt/font/TextAttribute.java",
@@ -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",
@@ -381,7 +382,6 @@
         "ojluni/src/main/java/java/nio/channels/package-info.java",
         "ojluni/src/main/java/java/nio/CharBuffer.java",
         "ojluni/src/main/java/java/nio/CharBufferSpliterator.java",
-        "ojluni/src/main/java/java/nio/DirectByteBuffer.java",
         "ojluni/src/main/java/java/nio/DoubleBuffer.java",
         "ojluni/src/main/java/java/nio/FloatBuffer.java",
         "ojluni/src/main/java/java/nio/HeapByteBuffer.java",
@@ -1345,8 +1345,8 @@
         "ojluni/src/main/java/javax/sql/StatementEventListener.java",
         "ojluni/src/main/java/sun/reflect/CallerSensitive.java",
     ],
-
 }
+
 // Stubs needed to satisfy javac's dependencies when compiling lambda code. These are
 // not used on Android devices or required by the Jack compiler.
 //
@@ -1358,18 +1358,13 @@
 // any of these classes.
 filegroup {
     name: "openjdk_lambda_stub_files",
-    export_to_make_var: "openjdk_lambda_stub_files",
-    path: "ojluni/src/lambda/java",
     srcs: [
         "ojluni/src/lambda/java/java/lang/invoke/LambdaMetafactory.java",
         "ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java",
     ],
 }
-
 filegroup {
     name: "openjdk_lambda_duplicate_stub_files",
-    export_to_make_var: "openjdk_lambda_duplicate_stub_files",
-    path: "ojluni/src/lambda/java",
     srcs: [
         "ojluni/src/lambda/java/java/lang/invoke/CallSite.java",
         "ojluni/src/lambda/java/java/lang/invoke/MethodHandles.java",
@@ -1379,12 +1374,36 @@
     ],
 }
 
-// NOTE: Files in java/lang/invoke are listed here because they're not being made public
-// until the entire package is available for use.
+// Classes which are exposed in the intra-core or core-platform APIs but not in
+// the public APIs. Unless they are annotated, these classes and all their
+// members will be exposed in all such APIs. To avoid patching the main ojluni
+// sources, these API annotations can be placed in .annotated.java stub files
+// under ojluni/annotations/mmodule. Classes must be hidden using the
+// libcore.api.Hide annotation, and then the class and the members to be exposed
+// must be annotated with libcore.api.CorePlatformApi and/or
+// libcore.api.IntraCoreApi.
 filegroup {
-    name: "openjdk_java_files",
-    export_to_make_var: "openjdk_java_files",
-    path: "ojluni/src/lambda/java",
+    name: "openjdk_mmodule_extra_files",
+    srcs: [
+        "ojluni/src/main/java/java/nio/DirectByteBuffer.java",
+        "ojluni/src/main/java/sun/misc/Cleaner.java",
+        "ojluni/src/main/java/sun/misc/Unsafe.java",
+        "ojluni/src/main/java/sun/nio/ch/DirectBuffer.java",
+        "ojluni/src/main/java/sun/security/jca/Providers.java",
+        "ojluni/src/main/java/sun/security/pkcs/ContentInfo.java",
+        "ojluni/src/main/java/sun/security/pkcs/ParsingException.java",
+        "ojluni/src/main/java/sun/security/pkcs/PKCS7.java",
+        "ojluni/src/main/java/sun/security/pkcs/SignerInfo.java",
+        "ojluni/src/main/java/sun/security/util/DerEncoder.java",
+        "ojluni/src/main/java/sun/security/util/ObjectIdentifier.java",
+        "ojluni/src/main/java/sun/security/x509/AlgorithmId.java",
+        "ojluni/src/main/java/sun/util/locale/LanguageTag.java",
+    ],
+}
+
+// Classes not exposed in any API (either public or mmodule).
+filegroup {
+    name: "openjdk_internal_files",
     srcs: [
         "ojluni/src/main/java/com/sun/net/ssl/internal/ssl/X509ExtendedTrustManager.java",
         "ojluni/src/main/java/com/sun/security/cert/internal/x509/X509V1CertImpl.java",
@@ -1433,7 +1452,6 @@
         "ojluni/src/main/java/sun/misc/Resource.java",
         "ojluni/src/main/java/sun/misc/SharedSecrets.java",
         "ojluni/src/main/java/sun/misc/URLClassPath.java",
-        "ojluni/src/main/java/sun/misc/Unsafe.java",
         "ojluni/src/main/java/sun/misc/Version.java",
         "ojluni/src/main/java/sun/misc/VM.java",
         "ojluni/src/main/java/sun/net/ApplicationProxy.java",
@@ -1605,8 +1623,6 @@
         "ojluni/src/main/java/sun/security/jca/ProviderList.java",
         "ojluni/src/main/java/sun/security/jca/Providers.java",
         "ojluni/src/main/java/sun/security/jca/ServiceId.java",
-        "ojluni/src/main/java/sun/security/pkcs/ContentInfo.java",
-        "ojluni/src/main/java/sun/security/pkcs/ParsingException.java",
         "ojluni/src/main/java/sun/security/pkcs/PKCS7.java",
         "ojluni/src/main/java/sun/security/pkcs/PKCS8Key.java",
         "ojluni/src/main/java/sun/security/pkcs/PKCS9Attribute.java",
@@ -1656,7 +1672,6 @@
         "ojluni/src/main/java/sun/security/util/ByteArrayTagOrder.java",
         "ojluni/src/main/java/sun/security/util/Cache.java",
         "ojluni/src/main/java/sun/security/util/Debug.java",
-        "ojluni/src/main/java/sun/security/util/DerEncoder.java",
         "ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java",
         "ojluni/src/main/java/sun/security/util/DerInputBuffer.java",
         "ojluni/src/main/java/sun/security/util/DerInputStream.java",
@@ -1667,14 +1682,12 @@
         "ojluni/src/main/java/sun/security/util/Length.java",
         "ojluni/src/main/java/sun/security/util/ManifestDigester.java",
         "ojluni/src/main/java/sun/security/util/ManifestEntryVerifier.java",
-        "ojluni/src/main/java/sun/security/util/ObjectIdentifier.java",
         "ojluni/src/main/java/sun/security/util/PropertyExpander.java",
         "ojluni/src/main/java/sun/security/util/Resources.java",
         "ojluni/src/main/java/sun/security/util/ResourcesMgr.java",
         "ojluni/src/main/java/sun/security/util/SecurityConstants.java",
         "ojluni/src/main/java/sun/security/util/SignatureFileVerifier.java",
         "ojluni/src/main/java/sun/security/x509/AccessDescription.java",
-        "ojluni/src/main/java/sun/security/x509/AlgorithmId.java",
         "ojluni/src/main/java/sun/security/x509/AttributeNameEnumeration.java",
         "ojluni/src/main/java/sun/security/x509/AuthorityInfoAccessExtension.java",
         "ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java",
@@ -1759,7 +1772,6 @@
         "ojluni/src/main/java/sun/util/locale/BaseLocale.java",
         "ojluni/src/main/java/sun/util/locale/Extension.java",
         "ojluni/src/main/java/sun/util/locale/InternalLocaleBuilder.java",
-        "ojluni/src/main/java/sun/util/locale/LanguageTag.java",
         "ojluni/src/main/java/sun/util/locale/LocaleEquivalentMaps.java",
         "ojluni/src/main/java/sun/util/locale/LocaleExtensions.java",
         "ojluni/src/main/java/sun/util/locale/LocaleMatcher.java",
@@ -1775,7 +1787,50 @@
         "ojluni/src/main/java/sun/util/logging/PlatformLogger.java",
         "ojluni/src/main/java/sun/util/ResourceBundleEnumeration.java",
         "ojluni/src/main/java/sun/util/resources/OpenListResourceBundle.java",
+    ],
+}
+
+// All classes, whether exposed in any API or not.
+filegroup {
+    name: "openjdk_java_files",
+    srcs: [
         ":openjdk_javadoc_files",
+        ":openjdk_mmodule_extra_files",
+        ":openjdk_internal_files",
         ":openjdk_lambda_stub_files",
     ],
 }
+
+// Classes that provide information about hidden APIs.
+filegroup {
+    name: "openjdk_hiddenapi_javadoc_files",
+    srcs: ["ojluni/annotations/hiddenapi/**/*.java"],
+}
+
+// Generates stub files for the classes exposed in the public API, without
+// javadoc. This can be used as a starting point for adding a new file to
+// libcore/ojluni/annotations/sdk. See libcore/ojluni/annotations/README.
+droidstubs {
+    name: "openjdk-sdk-stubs-no-javadoc",
+    srcs: [":openjdk_javadoc_files"],
+    installable: false,
+    no_framework_libs: true,
+    args: "--exclude-documentation-from-stubs"
+}
+
+// Generates stub files for the classes exposed in the intra-core or
+// core-platform APIs, without javadoc. This can be used as a starting point
+// for adding a new file to libcore/ojluni/annotations/mmodule.
+// See libcore/ojluni/annotations/README.
+droidstubs {
+    name: "openjdk-mmodule-stubs-no-javadoc",
+    srcs: [
+        ":openjdk_javadoc_files",
+        ":openjdk_mmodule_extra_files",
+    ],
+    installable: false,
+    no_framework_libs: true,
+    args: "--exclude-documentation-from-stubs "
+        + "--hide-annotation libcore.api.Hide ",
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
+}
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/CpuFeatures.java b/support/src/test/java/libcore/java/security/CpuFeatures.java
index df65ed2..8ab610f 100644
--- a/support/src/test/java/libcore/java/security/CpuFeatures.java
+++ b/support/src/test/java/libcore/java/security/CpuFeatures.java
@@ -16,87 +16,47 @@
 
 package libcore.java.security;
 
-import android.system.Os;
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import dalvik.system.VMRuntime;
 
-public class CpuFeatures {
-    /** Machine architecture, determined from the "machine" value returned by uname() */
-    private enum Arch {
-        // 64bit ARM can return armv8 or aarch64.
-        // 32bit ARM should return armv7 or armv7a
-        ARM("^aarch.*|^arm.*"),
-        // 64bit Android and Linux generally return x86_64.
-        // 32bit Android and Linux generally return i686
-        // Other host architectures can potentially return x86 or i386.
-        X86("^x86.*|i386|i686");
-
-        private final String machineRegex;
-
-        Arch(String machineRegex) {
-            this.machineRegex = machineRegex;
-        }
-
-        /**
-         * Returns the architecture of this machine by matching against output from uname()
-         * against the regex for each known family.
-         */
-        public static Arch currentArch() {
-            String machine = Os.uname().machine;
-            for (Arch type : values()) {
-                if (machine.matches(type.machineRegex)) {
-                    return type;
-                }
-            }
-            throw new IllegalStateException("Unknown machine value: " + machine);
-        }
-    }
-
-    private enum InstructionSet {
-        ARM_32(Arch.ARM, "arm"),
-        ARM_64(Arch.ARM, "arm64"),
-        X86_32(Arch.X86, "x86"),
-        X86_64(Arch.X86, "x86_64");
-
-        private final Arch arch;
-        private final String name;
-
-        InstructionSet(Arch arch, String name) {
-            this.arch = arch;
-            this.name = name;
-        }
-
-        public Arch architecture() {
-            return arch;
-        }
-
-        /**
-         * Returns the current InstructionSet set by matching against the name fields above.
-         */
-        public static InstructionSet currentInstructionSet() {
-            // Always returns one of the values from VMRuntime.ABI_TO_INSTRUCTION_SET_MAP.
-            String instructionSet = VMRuntime.getCurrentInstructionSet();
-            for (InstructionSet set : values()) {
-                if (instructionSet.equals(set.name)) {
-                    return set;
-                }
-            }
-            throw new IllegalStateException("Unknown instruction set: " + instructionSet);
-        }
-    }
-
+class CpuFeatures {
     private CpuFeatures() {
     }
 
-    /**
-     * Returns true if this device has hardware AES support as determined by BoringSSL.
-     */
-    public static boolean isAesHardwareAccelerated() {
+    static boolean isAESHardwareAccelerated() {
+        // Expectations based on CPU type: If these aren't met then Conscrypt
+        // integration tests will fail and the cause should be investigated.
+        String instructionSet = VMRuntime.getCurrentInstructionSet();
+        if (instructionSet.startsWith("arm")) {
+            // All ARM CPUs with the "aes" feature should have hardware AES.
+            List<String> features = getListFromCpuinfo("Features");
+            if (features != null && features.contains("aes")) {
+                return true;
+            }
+        } else if (instructionSet.startsWith("x86")) {
+            // x86 CPUs with the "aes" flag and running in 64bit mode should have hardware AES.
+            if ("x86_64".equals(instructionSet)) {
+                List<String> flags = getListFromCpuinfo("flags");
+                if (flags != null && flags.contains("aes")) {
+                    return true;
+                }
+            } else {
+                // Hardware AES not supported in 32bit mode.
+                return false;
+            }
+        }
+
+        // Otherwise trust Conscrypt NativeCrypto's own checks, for example if we're in an
+        // emulated ABI, it might bridge to a library that has accelerated AES instructions.
         try {
             Class<?> nativeCrypto = Class.forName("com.android.org.conscrypt.NativeCrypto");
             Method EVP_has_aes_hardware = nativeCrypto.getDeclaredMethod("EVP_has_aes_hardware");
@@ -111,51 +71,33 @@
         return false;
     }
 
-    /**
-     * Returns true if this device should have hardware AES support based on CPU information.
-     *
-     * A return value of false means that acceleration isn't expected, but it may still be available
-     * e.g. via bridging to a native library in an emulated environment.
-     */
-    public static boolean isKnownToSupportHardwareAes() {
-        Arch architecture = Arch.currentArch();
-        InstructionSet instructionSet = InstructionSet.currentInstructionSet();
+    private static String getFieldFromCpuinfo(String field) {
+        try {
+            BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
+            Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)");
 
-        if (!instructionSet.architecture().equals(architecture)) {
-            // Different architectures imply an emulated environment, so unable to determine if
-            // hardware acceleration is expected.  Assume not.
-            return false;
-        }
-
-        if (architecture.equals(Arch.ARM)) {
-            // All ARM CPUs (32 and 64 bit) with the "aes" feature should have hardware AES.
-            return cpuFieldContainsAes("Features");
-        } else if (instructionSet.equals(InstructionSet.X86_64)) {
-            // x86 CPUs with the "aes" flag and running in 64bit mode should have hardware AES.
-            // Hardware AES is not *expected* in 32bit mode, but may be available.
-            return cpuFieldContainsAes("flags");
-        }
-        return false;
-    }
-
-
-    /**
-     * Returns true if any line in the output from /proc/cpuinfo matches the provided
-     * field name and contains the word "aes" in its list of values.
-     *
-     * Example line from /proc/cpuinfo: Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
-     */
-    private static boolean cpuFieldContainsAes(String fieldName) {
-        try (BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"))) {
-            String regex = "^" + fieldName + "\\s*:.*\\baes\\b.*";
-            String line;
-            while ((line = br.readLine()) != null) {
-                if (line.matches(regex)) {
-                    return true;
+            try {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    Matcher m = p.matcher(line);
+                    if (m.matches()) {
+                        return m.group(1);
+                    }
                 }
+            } finally {
+                br.close();
             }
         } catch (IOException ignored) {
         }
-        return false;
+
+        return null;
+    }
+
+    private static List<String> getListFromCpuinfo(String fieldName) {
+        String features = getFieldFromCpuinfo(fieldName);
+        if (features == null)
+            return null;
+
+        return Arrays.asList(features.split("\\s"));
     }
 }
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 7f826b34..eb9cf45 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -16,7 +16,6 @@
 
 package libcore.java.security;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
@@ -28,12 +27,9 @@
 import java.security.spec.KeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -70,47 +66,33 @@
 
     public static final boolean IS_RI
             = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
-    public static final String JSSE_PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "AndroidOpenSSL";
-    public static final String SECURITY_PROVIDER_NAME = (IS_RI) ? "SUN" : "BC";
 
-    public static final String KEY_MANAGER_FACTORY_DEFAULT = (IS_RI) ? "SunX509" : "PKIX";
-    public static final String TRUST_MANAGER_FACTORY_DEFAULT = "PKIX";
+    public static final String SECURITY_PROVIDER_NAME = (IS_RI) ? "SUN" : "BC";
 
     public static final String KEY_STORE_ALGORITHM = (IS_RI) ? "JKS" : "BKS";
 
     /**
      * RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
      */
-    public static final String CIPHER_SUITE_SECURE_RENEGOTIATION
+    private static final String CIPHER_SUITE_SECURE_RENEGOTIATION
             = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
 
     /**
-     * From https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 it is a
-     * signaling cipher suite value (SCSV) to indicate that this request is a
-     * protocol fallback (e.g., TLS 1.0 -> SSL 3.0) because the server didn't respond
-     * to the first request.
-     */
-    public static final String CIPHER_SUITE_FALLBACK = "TLS_FALLBACK_SCSV";
-
-    /**
      * A map from algorithm type (e.g. Cipher) to a set of algorithms (e.g. AES, DES, ...)
      */
-    public static final Map<String,Set<String>> PROVIDER_ALGORITHMS
-            = new HashMap<String,Set<String>>();
+    static final Map<String,Set<String>> PROVIDER_ALGORITHMS
+            = new HashMap<>();
 
-    public static final Map<String,Set<String>> CIPHER_MODES
-            = new HashMap<String,Set<String>>();
+    private static final Map<String,Set<String>> CIPHER_MODES
+            = new HashMap<>();
 
-    public static final Map<String,Set<String>> CIPHER_PADDINGS
-            = new HashMap<String,Set<String>>();
-
-    private static final Map<String, String[]> SSL_CONTEXT_PROTOCOLS_ENABLED
-            = new HashMap<String,String[]>();
+    private static final Map<String,Set<String>> CIPHER_PADDINGS
+            = new HashMap<>();
 
     private static void provide(String type, String algorithm) {
         Set<String> algorithms = PROVIDER_ALGORITHMS.get(type);
         if (algorithms == null) {
-            algorithms = new HashSet<String>();
+            algorithms = new HashSet<>();
             PROVIDER_ALGORITHMS.put(type, algorithms);
         }
         assertTrue("Duplicate " + type + " " + algorithm,
@@ -127,7 +109,7 @@
     private static void provideCipherModes(String algorithm, String newModes[]) {
         Set<String> modes = CIPHER_MODES.get(algorithm);
         if (modes == null) {
-            modes = new HashSet<String>();
+            modes = new HashSet<>();
             CIPHER_MODES.put(algorithm, modes);
         }
         modes.addAll(Arrays.asList(newModes));
@@ -135,23 +117,11 @@
     private static void provideCipherPaddings(String algorithm, String newPaddings[]) {
         Set<String> paddings = CIPHER_PADDINGS.get(algorithm);
         if (paddings == null) {
-            paddings = new HashSet<String>();
+            paddings = new HashSet<>();
             CIPHER_PADDINGS.put(algorithm, paddings);
         }
         paddings.addAll(Arrays.asList(newPaddings));
     }
-    private static void provideSslContextEnabledProtocols(String algorithm, TLSVersion minimum,
-            TLSVersion maximum) {
-        if (minimum.ordinal() > maximum.ordinal()) {
-            throw new RuntimeException("TLS version: minimum > maximum");
-        }
-        int versionsLength = maximum.ordinal() - minimum.ordinal() + 1;
-        String[] versionNames = new String[versionsLength];
-        for (int i = 0; i < versionsLength; i++) {
-            versionNames[i] = TLSVersion.values()[i + minimum.ordinal()].name;
-        }
-        SSL_CONTEXT_PROTOCOLS_ENABLED.put(algorithm, versionNames);
-    }
     static {
         provide("AlgorithmParameterGenerator", "DSA");
         provide("AlgorithmParameterGenerator", "DiffieHellman");
@@ -264,6 +234,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");
@@ -635,43 +606,16 @@
                 provide("KeyStore", "KnoxAndroidKeyStore");
             }
         }
-
-        if (IS_RI) {
-            provideSslContextEnabledProtocols("SSL", TLSVersion.SSLv3, TLSVersion.TLSv1);
-            provideSslContextEnabledProtocols("SSLv3", TLSVersion.SSLv3, TLSVersion.TLSv1);
-            provideSslContextEnabledProtocols("TLS", TLSVersion.SSLv3, TLSVersion.TLSv1);
-            provideSslContextEnabledProtocols("TLSv1", TLSVersion.SSLv3, TLSVersion.TLSv1);
-            provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.SSLv3, TLSVersion.TLSv11);
-            provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.SSLv3, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("Default", TLSVersion.SSLv3, TLSVersion.TLSv1);
-        } else {
-            provideSslContextEnabledProtocols("SSL", TLSVersion.TLSv1, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
-            provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv12);
-        }
     }
 
-    public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
-    public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(Arrays.asList(
-        SSL_CONTEXT_PROTOCOLS_DEFAULT,
-        "SSL",
-        "TLS",
-        "TLSv1",
-        "TLSv1.1",
-        "TLSv1.2"));
-    public static final String SSL_CONTEXT_PROTOCOL_DEFAULT = "TLS";
-
-    public static final Set<String> KEY_TYPES = new HashSet<String>(Arrays.asList(
-        "RSA",
-        "DSA",
-        "DH_RSA",
-        "DH_DSA",
-        "EC",
-        "EC_EC",
-        "EC_RSA"));
+    public static final Set<String> KEY_TYPES = new HashSet<>(Arrays.asList(
+            "RSA",
+            "DSA",
+            "DH_RSA",
+            "DH_DSA",
+            "EC",
+            "EC_EC",
+            "EC_RSA"));
     static {
         if (IS_RI) {
             // DH_* are specified by standard names, but do not seem to be supported by RI
@@ -680,268 +624,50 @@
         }
     }
 
-    public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
-        "TLSv1",
-        "TLSv1.1",
-        "TLSv1.2"));
-    public static final Set<String> SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT =
-            new HashSet<String>(Arrays.asList(
-                "TLSv1",
-                "TLSv1.1",
-                "TLSv1.2"));
-    public static final Set<String> SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT =
-            new HashSet<String>(Arrays.asList(
-                "TLSv1",
-                "TLSv1.1",
-                "TLSv1.2"));
-    static {
-        if (IS_RI) {
-            /* Even though we use OpenSSL's SSLv23_method which
-             * supports sending SSLv2 client hello messages, the
-             * OpenSSL implementation in s23_client_hello disables
-             * this if SSL_OP_NO_SSLv2 is specified, which we always
-             * do to disable general use of SSLv2.
-             */
-            SSL_SOCKET_PROTOCOLS.add("SSLv2Hello");
-
-            /* The RI still has SSLv3 as a default protocol. */
-            SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT.add("SSLv3");
-            SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT.add("SSLv3");
-        }
-    }
-
-    private static enum TLSVersion {
-        SSLv3("SSLv3"),
-        TLSv1("TLSv1"),
-        TLSv11("TLSv1.1"),
-        TLSv12("TLSv1.2");
-
-        private final String name;
-
-        TLSVersion(String name) {
-            this.name = name;
-        }
-    };
-
     /**
      * Valid values for X509TrustManager.checkClientTrusted authType,
      * either the algorithm of the public key or UNKNOWN.
      */
-    public static final Set<String> CLIENT_AUTH_TYPES = new HashSet<String>(Arrays.asList(
-        "RSA",
-        "DSA",
-        "EC",
-        "UNKNOWN"));
+    public static final Set<String> CLIENT_AUTH_TYPES = new HashSet<>(Arrays.asList(
+            "RSA",
+            "DSA",
+            "EC",
+            "UNKNOWN"));
 
     /**
      * 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",
-        "DHE_DSS_EXPORT",
-        "DHE_RSA",
-        "DHE_RSA_EXPORT",
-        "DH_DSS_EXPORT",
-        "DH_RSA_EXPORT",
-        "DH_anon",
-        "DH_anon_EXPORT",
-        "KRB5",
-        "KRB5_EXPORT",
-        "RSA",
-        "RSA_EXPORT",
-        "RSA_EXPORT1024",
-        "ECDH_ECDSA",
-        "ECDH_RSA",
-        "ECDHE_ECDSA",
-        "ECDHE_RSA",
-        "UNKNOWN"));
-
-    public static final String CIPHER_SUITE_INVALID = "SSL_NULL_WITH_NULL_NULL";
-
-    public static final Set<String> CIPHER_SUITES_NEITHER = new HashSet<String>();
-
-    public static final Set<String> CIPHER_SUITES_RI = new LinkedHashSet<String>();
-    public static final Set<String> CIPHER_SUITES_OPENSSL = new LinkedHashSet<String>();
-
-    public static final Set<String> CIPHER_SUITES;
-
-    private static final void addRi(String cipherSuite) {
-        CIPHER_SUITES_RI.add(cipherSuite);
-    }
-
-    private static final void addOpenSsl(String cipherSuite) {
-        CIPHER_SUITES_OPENSSL.add(cipherSuite);
-    }
-
-    private static final void addBoth(String cipherSuite) {
-        addRi(cipherSuite);
-        addOpenSsl(cipherSuite);
-    }
-
-    private static final void addNeither(String cipherSuite) {
-        CIPHER_SUITES_NEITHER.add(cipherSuite);
-    }
-
-    static {
-        // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
-        // javax.net.ssl.SSLEngine.
-        addBoth(   "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
-        addBoth(   "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
-        addBoth(   "TLS_RSA_WITH_AES_256_CBC_SHA");
-        addBoth(   "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
-        addBoth(   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
-        addBoth(   "TLS_RSA_WITH_AES_128_CBC_SHA");
-        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");
-        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");
-        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");
-        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");
-
-        // Pre-Shared Key (PSK) cipher suites
-        addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
-        addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
-        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
-        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
-        addOpenSsl("TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256");
-
-        // RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
-        addBoth(CIPHER_SUITE_SECURE_RENEGOTIATION);
-
-        // From https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 to indicate
-        // TLS fallback request
-        addOpenSsl(CIPHER_SUITE_FALLBACK);
-
-        // non-defaultCipherSuites
-
-        // Android does not have Kerberos support
-        addRi(     "TLS_KRB5_WITH_RC4_128_SHA");
-        addRi(     "TLS_KRB5_WITH_RC4_128_MD5");
-        addRi(     "TLS_KRB5_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_KRB5_WITH_3DES_EDE_CBC_MD5");
-        addRi(     "TLS_KRB5_WITH_DES_CBC_SHA");
-        addRi(     "TLS_KRB5_WITH_DES_CBC_MD5");
-        addRi(     "TLS_KRB5_EXPORT_WITH_RC4_40_SHA");
-        addRi(     "TLS_KRB5_EXPORT_WITH_RC4_40_MD5");
-        addRi(     "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA");
-        addRi(     "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5");
-
-        // Android does not have DSS support
-        addRi(     "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
-        addRi(     "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "SSL_DHE_DSS_WITH_DES_CBC_SHA");
-        addRi(     "TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
-        addNeither("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256");
-        addRi(     "TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
-        addNeither("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384");
-
-        // Android does not have RC4 support
-        addRi(     "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA");
-        addRi(     "TLS_ECDHE_RSA_WITH_RC4_128_SHA");
-        addRi(     "SSL_RSA_WITH_RC4_128_SHA");
-        addRi(     "SSL_RSA_WITH_RC4_128_MD5");
-
-        // Dropped
-        addRi(     "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
-        addRi(     "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "SSL_DHE_RSA_WITH_DES_CBC_SHA");
-        addNeither("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
-        addNeither("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
-        addRi(     "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
-        addRi(     "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5");
-        addRi(     "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "SSL_DH_anon_WITH_DES_CBC_SHA");
-        addRi(     "SSL_DH_anon_WITH_RC4_128_MD5");
-        addRi(     "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA");
-        addRi(     "SSL_RSA_EXPORT_WITH_RC4_40_MD5");
-        addRi(     "SSL_RSA_WITH_DES_CBC_SHA");
-        addRi(     "SSL_RSA_WITH_NULL_MD5");
-        addRi(     "SSL_RSA_WITH_NULL_SHA");
-        addRi(     "TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
-        addNeither("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256");
-        addNeither("TLS_DHE_RSA_WITH_AES_128_GCM_SHA384");
-        addRi(     "TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
-        addRi(     "TLS_DH_anon_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_DH_anon_WITH_AES_128_CBC_SHA256");
-        addNeither("TLS_DH_anon_WITH_AES_128_GCM_SHA256");
-        addRi(     "TLS_DH_anon_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_DH_anon_WITH_AES_256_CBC_SHA256");
-        addNeither("TLS_DH_anon_WITH_AES_256_GCM_SHA384");
-        addRi(     "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_ECDHE_ECDSA_WITH_NULL_SHA");
-        addRi(     "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_ECDHE_RSA_WITH_NULL_SHA");
-        addRi(     "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
-        addNeither("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256");
-        addRi(     "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
-        addNeither("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384");
-        addRi(     "TLS_ECDH_ECDSA_WITH_NULL_SHA");
-        addRi(     "TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
-        addRi(     "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
-        addNeither("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256");
-        addRi(     "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
-        addNeither("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384");
-        addRi(     "TLS_ECDH_RSA_WITH_NULL_SHA");
-        addRi(     "TLS_ECDH_RSA_WITH_RC4_128_SHA");
-        addRi(     "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
-        addRi(     "TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
-        addRi(     "TLS_ECDH_anon_WITH_NULL_SHA");
-        addRi(     "TLS_ECDH_anon_WITH_RC4_128_SHA");
-        addNeither("TLS_PSK_WITH_3DES_EDE_CBC_SHA");
-        addRi(     "TLS_RSA_WITH_NULL_SHA256");
-
-        // Old non standard exportable encryption
-        addNeither("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA");
-        addNeither("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA");
-
-        // No RC2
-        addNeither("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5");
-        addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA");
-        addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5");
-
-        CIPHER_SUITES = (IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL;
-    }
+    public static final Set<String> SERVER_AUTH_TYPES = new HashSet<>(Arrays.asList(
+            "DHE_DSS",
+            "DHE_DSS_EXPORT",
+            "DHE_RSA",
+            "DHE_RSA_EXPORT",
+            "DH_DSS_EXPORT",
+            "DH_RSA_EXPORT",
+            "DH_anon",
+            "DH_anon_EXPORT",
+            "KRB5",
+            "KRB5_EXPORT",
+            "RSA",
+            "RSA_EXPORT",
+            "RSA_EXPORT1024",
+            "ECDH_ECDSA",
+            "ECDH_RSA",
+            "ECDHE_ECDSA",
+            "ECDHE_RSA",
+            "UNKNOWN",
+            "GENERIC"));
 
     /**
-     * Cipher suites that are not negotiated when TLSv1.2 is selected on the RI.
+     * Cipher suites that are only supported with TLS 1.3.
      */
-    public static final List<String> CIPHER_SUITES_OBSOLETE_TLS12 =
-            Arrays.asList(
-                    "SSL_RSA_WITH_DES_CBC_SHA",
-                    "SSL_DHE_RSA_WITH_DES_CBC_SHA",
-                    "SSL_DHE_DSS_WITH_DES_CBC_SHA",
-                    "SSL_DH_anon_WITH_DES_CBC_SHA",
-                    "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
-                    "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-                    "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
-                    "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
-                    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
-                    "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
-            );
+    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.
@@ -1028,53 +754,16 @@
                             "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
                             "SSL_RSA_WITH_RC4_128_MD5",
                             "TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
-            : CpuFeatures.isAesHardwareAccelerated() ? CIPHER_SUITES_ANDROID_AES_HARDWARE
+            : CpuFeatures.isAESHardwareAccelerated() ? CIPHER_SUITES_ANDROID_AES_HARDWARE
                     : CIPHER_SUITES_ANDROID_SOFTWARE;
 
-    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
-    // javax.net.ssl.SSLEngine.
-    public static final List<String> CIPHER_SUITES_DEFAULT_PSK = Arrays.asList(
-            "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
-            "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
-            "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
-            "TLS_PSK_WITH_AES_128_CBC_SHA",
-            "TLS_PSK_WITH_AES_256_CBC_SHA"
-            );
-
-    // Should be updated to match BoringSSL's defaults when they change.
-    // https://android.googlesource.com/platform/external/boringssl/+/master/src/ssl/t1_lib.c#305
-    public static final List<String> ELLIPTIC_CURVES_DEFAULT = Arrays.asList(
-            "x25519 (29)",
-            "secp256r1 (23)",
-            "secp384r1 (24)"
-            );
-
-    private static final Set<String> PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS =
-            new HashSet<String>(Arrays.asList("RSA",
-                                              "DHE_RSA",
-                                              "DHE_DSS",
-                                              "ECDHE_RSA",
-                                              "ECDHE_ECDSA"));
-
-    private static final Set<String> PERMITTED_DEFAULT_BULK_ENCRYPTION_CIPHERS =
-            new HashSet<String>(Arrays.asList("AES_128_CBC",
-                                              "AES_256_CBC",
-                                              "AES_128_GCM",
-                                              "AES_256_GCM",
-                                              "CHACHA20_POLY1305"));
-
-    private static final Set<String> PERMITTED_DEFAULT_MACS =
-            new HashSet<String>(Arrays.asList("SHA",
-                                              "SHA256",
-                                              "SHA384"));
-
-    public static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;
-    public static final Map<String, Class<? extends KeySpec>> PUBLIC_KEY_SPEC_CLASSES;
-    public static final Map<String, Integer> MINIMUM_KEY_SIZE;
+    private static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;
+    private static final Map<String, Class<? extends KeySpec>> PUBLIC_KEY_SPEC_CLASSES;
+    private static final Map<String, Integer> MINIMUM_KEY_SIZE;
     static {
-        PRIVATE_KEY_SPEC_CLASSES = new HashMap<String, Class<? extends KeySpec>>();
-        PUBLIC_KEY_SPEC_CLASSES = new HashMap<String, Class<? extends KeySpec>>();
-        MINIMUM_KEY_SIZE = new HashMap<String, Integer>();
+        PRIVATE_KEY_SPEC_CLASSES = new HashMap<>();
+        PUBLIC_KEY_SPEC_CLASSES = new HashMap<>();
+        MINIMUM_KEY_SIZE = new HashMap<>();
         PRIVATE_KEY_SPEC_CLASSES.put("RSA", RSAPrivateCrtKeySpec.class);
         PUBLIC_KEY_SPEC_CLASSES.put("RSA", RSAPublicKeySpec.class);
         MINIMUM_KEY_SIZE.put("RSA", 512);
@@ -1101,178 +790,4 @@
         return MINIMUM_KEY_SIZE.get(algName);
     }
 
-    /**
-     * Asserts that the cipher suites array is non-null and that it
-     * all of its contents are cipher suites known to this
-     * implementation. As a convenience, returns any unenabled cipher
-     * suites in a test for those that want to verify separately that
-     * all cipher suites were included.
-     */
-    private static Set<String> assertValidCipherSuites(
-            Set<String> expected, String[] cipherSuites) {
-        assertNotNull(cipherSuites);
-        assertTrue(cipherSuites.length != 0);
-
-        // Make sure all cipherSuites names are expected
-        Set remainingCipherSuites = new HashSet<String>(expected);
-        Set unknownCipherSuites = new HashSet<String>();
-        for (String cipherSuite : cipherSuites) {
-            boolean removed = remainingCipherSuites.remove(cipherSuite);
-            if (!removed) {
-                unknownCipherSuites.add(cipherSuite);
-            }
-        }
-        assertEquals("Unknown cipher suites", Collections.EMPTY_SET, unknownCipherSuites);
-        return remainingCipherSuites;
-    }
-
-    /**
-     * After using assertValidCipherSuites on cipherSuites,
-     * assertSupportedCipherSuites additionally verifies that all
-     * supported cipher suites where in the input array.
-     */
-    private static void assertSupportedCipherSuites(Set<String> expected, String[] cipherSuites) {
-        Set<String> remainingCipherSuites = assertValidCipherSuites(expected, cipherSuites);
-        assertEquals("Missing cipher suites", Collections.EMPTY_SET, remainingCipherSuites);
-        assertEquals(expected.size(), cipherSuites.length);
-    }
-
-    /**
-     * Asserts that the protocols array is non-null and that it all of
-     * its contents are protocols known to this implementation. As a
-     * convenience, returns any unenabled protocols in a test for
-     * those that want to verify separately that all protocols were
-     * included.
-     */
-    private static Set<String> assertValidProtocols(Set<String> expected, String[] protocols) {
-        assertNotNull(protocols);
-        assertTrue(protocols.length != 0);
-
-        // Make sure all protocols names are expected
-        Set remainingProtocols = new HashSet<String>(expected);
-        Set unknownProtocols = new HashSet<String>();
-        for (String protocol : protocols) {
-            if (!remainingProtocols.remove(protocol)) {
-                unknownProtocols.add(protocol);
-            }
-        }
-        assertEquals("Unknown protocols", Collections.EMPTY_SET, unknownProtocols);
-        return remainingProtocols;
-    }
-
-    /**
-     * After using assertValidProtocols on protocols,
-     * assertSupportedProtocols additionally verifies that all
-     * supported protocols where in the input array.
-     */
-    private static void assertSupportedProtocols(Set<String> expected, String[] protocols) {
-        Set<String> remainingProtocols = assertValidProtocols(expected, protocols);
-        assertEquals("Missing protocols", Collections.EMPTY_SET, remainingProtocols);
-        assertEquals(expected.size(), protocols.length);
-    }
-
-    /**
-     * Asserts that the provided list of protocols matches the supported list of protocols.
-     */
-    public static void assertSupportedProtocols(String[] protocols) {
-        assertSupportedProtocols(SSL_SOCKET_PROTOCOLS, protocols);
-    }
-
-    /**
-     * Assert that the provided list of cipher suites contains only the supported cipher suites.
-     */
-    public static void assertValidCipherSuites(String[] cipherSuites) {
-        assertValidCipherSuites(CIPHER_SUITES, cipherSuites);
-    }
-
-    /**
-     * Assert that the provided list of cipher suites matches the supported list.
-     */
-    public static void assertSupportedCipherSuites(String[] cipherSuites) {
-        assertSupportedCipherSuites(CIPHER_SUITES, cipherSuites);
-    }
-
-    /**
-     * Assert cipher suites match the default list in content and priority order and contain
-     * only cipher suites permitted by default.
-     */
-    public static void assertDefaultCipherSuites(String[] cipherSuites) {
-        assertValidCipherSuites(cipherSuites);
-        assertEquals(CIPHER_SUITES_DEFAULT, Arrays.asList(cipherSuites));
-
-        // Assert that all the cipher suites are permitted to be in the default list.
-        // This assertion is a backup for the stricter assertion above.
-        //
-        // There is no point in asserting this for the RI as it's outside of our control.
-        if (!IS_RI) {
-            List<String> disallowedDefaultCipherSuites = new ArrayList<String>();
-            for (String cipherSuite : cipherSuites) {
-                if (!isPermittedDefaultCipherSuite(cipherSuite)) {
-                    disallowedDefaultCipherSuites.add(cipherSuite);
-                }
-            }
-            assertEquals(Collections.EMPTY_LIST, disallowedDefaultCipherSuites);
-        }
-    }
-
-    public static void assertDefaultEllipticCurves(String[] curves) {
-        assertEquals(ELLIPTIC_CURVES_DEFAULT, Arrays.asList(curves));
-    }
-
-    public static void assertSSLContextEnabledProtocols(String version, String[] protocols) {
-        assertEquals("For protocol \"" + version + "\"",
-                Arrays.toString(SSL_CONTEXT_PROTOCOLS_ENABLED.get(version)),
-                Arrays.toString(protocols));
-    }
-
-    private static boolean isPermittedDefaultCipherSuite(String cipherSuite) {
-        assertNotNull(cipherSuite);
-        if (CIPHER_SUITE_SECURE_RENEGOTIATION.equals(cipherSuite)) {
-            return true;
-        }
-        assertTrue(cipherSuite, cipherSuite.startsWith("TLS_") || cipherSuite.startsWith("SSL_"));
-
-        // Example: RSA_WITH_AES_128_CBC_SHA
-        String remainder = cipherSuite.substring("TLS_".length());
-        int macDelimiterIndex = remainder.lastIndexOf('_');
-        assertTrue(cipherSuite, macDelimiterIndex != -1);
-        // Example: SHA
-        String mac = remainder.substring(macDelimiterIndex + 1);
-
-        // Example: RSA_WITH_AES_128_CBC
-        remainder = remainder.substring(0, macDelimiterIndex);
-        int withDelimiterIndex = remainder.indexOf("_WITH_");
-        assertTrue(cipherSuite, withDelimiterIndex != -1);
-
-        // Example: RSA
-        String keyExchange = remainder.substring(0, withDelimiterIndex);
-        // Example: AES_128_CBC
-        String bulkEncryptionCipher = remainder.substring(withDelimiterIndex + "_WITH_".length());
-
-        if (!PERMITTED_DEFAULT_MACS.contains(mac)) {
-            return false;
-        }
-        if (!PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS.contains(keyExchange)) {
-            return false;
-        }
-        if (!PERMITTED_DEFAULT_BULK_ENCRYPTION_CIPHERS.contains(bulkEncryptionCipher)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Get all supported mode names for the given cipher.
-     */
-    public static Set<String> getModesForCipher(String cipher) {
-        return CIPHER_MODES.get(cipher);
-    }
-
-    /**
-     * Get all supported padding names for the given cipher.
-     */
-    public static Set<String> getPaddingsForCipher(String cipher) {
-        return CIPHER_PADDINGS.get(cipher);
-    }
 }
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index be9874f..b3544b7 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -18,33 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 
-import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.x500.X500Name;
-import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
-import com.android.org.bouncycastle.asn1.x509.CRLReason;
-import com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import com.android.org.bouncycastle.asn1.x509.Extension;
-import com.android.org.bouncycastle.asn1.x509.GeneralName;
-import com.android.org.bouncycastle.asn1.x509.GeneralNames;
-import com.android.org.bouncycastle.asn1.x509.GeneralSubtree;
-import com.android.org.bouncycastle.asn1.x509.KeyPurposeId;
-import com.android.org.bouncycastle.asn1.x509.KeyUsage;
-import com.android.org.bouncycastle.asn1.x509.NameConstraints;
-import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import com.android.org.bouncycastle.cert.X509CertificateHolder;
-import com.android.org.bouncycastle.cert.X509v3CertificateBuilder;
-import com.android.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import com.android.org.bouncycastle.cert.ocsp.BasicOCSPResp;
-import com.android.org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
-import com.android.org.bouncycastle.cert.ocsp.CertificateID;
-import com.android.org.bouncycastle.cert.ocsp.CertificateStatus;
-import com.android.org.bouncycastle.cert.ocsp.OCSPResp;
-import com.android.org.bouncycastle.cert.ocsp.OCSPRespBuilder;
-import com.android.org.bouncycastle.cert.ocsp.RevokedStatus;
-import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
-import com.android.org.bouncycastle.operator.DigestCalculatorProvider;
-import com.android.org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
-import com.android.org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.PrintStream;
@@ -81,6 +54,33 @@
 import javax.security.auth.x500.X500Principal;
 import libcore.javax.net.ssl.TestKeyManager;
 import libcore.javax.net.ssl.TestTrustManager;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.CRLReason;
+import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.GeneralSubtree;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.NameConstraints;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.DigestCalculatorProvider;
+import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 
 /**
  * TestKeyStore is a convenience class for other tests that
@@ -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/support/src/test/java/libcore/javax/net/ssl/SSLConfigurationAsserts.java b/support/src/test/java/libcore/javax/net/ssl/SSLConfigurationAsserts.java
index bdaad65..d76ee49 100644
--- a/support/src/test/java/libcore/javax/net/ssl/SSLConfigurationAsserts.java
+++ b/support/src/test/java/libcore/javax/net/ssl/SSLConfigurationAsserts.java
@@ -16,20 +16,14 @@
 
 package libcore.javax.net.ssl;
 
-import junit.framework.Assert;
-import libcore.java.security.StandardNames;
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.Set;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
+import junit.framework.Assert;
 
 /**
  * Assertions about the configuration of TLS/SSL primitives.
@@ -40,41 +34,6 @@
   private SSLConfigurationAsserts() {}
 
   /**
-   * Asserts that the provided {@link SSLContext} has the expected default configuration, and that
-   * {@link SSLSocketFactory}, {@link SSLServerSocketFactory}, {@link SSLSocket},
-   * {@link SSLServerSocket} and {@link SSLEngine} instances created from the context match the
-   * configuration.
-   */
-  public static void assertSSLContextDefaultConfiguration(SSLContext sslContext)
-      throws IOException {
-    SSLParameters defaultParameters = sslContext.getDefaultSSLParameters();
-    StandardNames.assertSSLContextEnabledProtocols(sslContext.getProtocol(),
-        defaultParameters.getProtocols());
-    StandardNames.assertDefaultCipherSuites(defaultParameters.getCipherSuites());
-    assertFalse(defaultParameters.getWantClientAuth());
-    assertFalse(defaultParameters.getNeedClientAuth());
-
-    SSLParameters supportedParameters = sslContext.getSupportedSSLParameters();
-    StandardNames.assertSupportedCipherSuites(supportedParameters.getCipherSuites());
-    StandardNames.assertSupportedProtocols(supportedParameters.getProtocols());
-    assertFalse(supportedParameters.getWantClientAuth());
-    assertFalse(supportedParameters.getNeedClientAuth());
-
-    assertContainsAll("Unsupported enabled cipher suites", supportedParameters.getCipherSuites(),
-        defaultParameters.getCipherSuites());
-    assertContainsAll("Unsupported enabled protocols", supportedParameters.getProtocols(),
-        defaultParameters.getProtocols());
-
-    assertSSLSocketFactoryConfigSameAsSSLContext(sslContext.getSocketFactory(), sslContext);
-    assertSSLServerSocketFactoryConfigSameAsSSLContext(sslContext.getServerSocketFactory(),
-        sslContext);
-
-    SSLEngine sslEngine = sslContext.createSSLEngine();
-    assertFalse(sslEngine.getUseClientMode());
-    assertSSLEngineConfigSameAsSSLContext(sslEngine, sslContext);
-  }
-
-  /**
    * Asserts that the provided {@link SSLSocketFactory} has the expected default configuration and
    * that {@link SSLSocket} instances created by the factory match the configuration.
    */
@@ -104,15 +63,6 @@
   }
 
   /**
-   * Asserts that the provided {@link SSLSocket} has the expected default configuration.
-   */
-  public static void assertSSLSocketDefaultConfiguration(SSLSocket sslSocket) throws Exception {
-    assertTrue(sslSocket.getUseClientMode());
-    assertTrue(sslSocket.getEnableSessionCreation());
-    assertSSLSocketConfigSameAsSSLContext(sslSocket, SSLContext.getDefault());
-  }
-
-  /**
    * Asserts that {@link SSLSocket}'s configuration matches {@code SSLContext's} configuration.
    */
   private static void assertSSLSocketConfigSameAsSSLContext(SSLSocket sslSocket,
@@ -129,95 +79,6 @@
         sslContext.getSupportedSSLParameters().getProtocols());
   }
 
-  /**
-   * Asserts that the provided {@link SSLServerSocketFactory} has the expected default
-   * configuration, and that {@link SSLServerSocket} instances created by the factory match the
-   * configuration.
-   */
-  public static void assertSSLServerSocketFactoryDefaultConfiguration(
-      SSLServerSocketFactory sslServerSocketFactory) throws Exception {
-    assertSSLServerSocketFactoryConfigSameAsSSLContext(sslServerSocketFactory,
-        SSLContext.getDefault());
-  }
-
-  /**
-   * Asserts that {@link SSLServerSocketFactory}'s configuration matches {@code SSLContext}'s
-   * configuration, and that {@link SSLServerSocket} instances obtained from the factory match this
-   * configuration as well.
-   */
-  private static void assertSSLServerSocketFactoryConfigSameAsSSLContext(
-      SSLServerSocketFactory sslServerSocketFactory, SSLContext sslContext)  throws IOException {
-    assertCipherSuitesEqual(sslContext.getDefaultSSLParameters().getCipherSuites(),
-        sslServerSocketFactory.getDefaultCipherSuites());
-    assertCipherSuitesEqual(sslContext.getSupportedSSLParameters().getCipherSuites(),
-        sslServerSocketFactory.getSupportedCipherSuites());
-    try (SSLServerSocket sslServerSocket =
-        (SSLServerSocket) sslServerSocketFactory.createServerSocket()) {
-      assertFalse(sslServerSocket.getUseClientMode());
-      assertTrue(sslServerSocket.getEnableSessionCreation());
-      assertSSLServerSocketConfigSameAsSSLContext(sslServerSocket, sslContext);
-    }
-  }
-
-  /**
-   * Asserts that the provided {@link SSLServerSocket} has the expected default configuration.
-   */
-  public static void assertSSLServerSocketDefaultConfiguration(SSLServerSocket sslServerSocket)
-      throws Exception {
-    assertFalse(sslServerSocket.getUseClientMode());
-    assertTrue(sslServerSocket.getEnableSessionCreation());
-    assertSSLServerSocketConfigSameAsSSLContext(sslServerSocket, SSLContext.getDefault());
-    // TODO: Check SSLParameters when supported by SSLServerSocket API
-  }
-
-  /**
-   * Asserts that {@link SSLServerSocket}'s configuration matches {@code SSLContext's}
-   * configuration.
-   */
-  private static void assertSSLServerSocketConfigSameAsSSLContext(SSLServerSocket sslServerSocket,
-      SSLContext sslContext) {
-    assertCipherSuitesEqual(sslServerSocket.getEnabledCipherSuites(),
-        sslContext.getDefaultSSLParameters().getCipherSuites());
-    assertProtocolsEqual(sslServerSocket.getEnabledProtocols(),
-        sslContext.getDefaultSSLParameters().getProtocols());
-
-    assertCipherSuitesEqual(sslServerSocket.getSupportedCipherSuites(),
-        sslContext.getSupportedSSLParameters().getCipherSuites());
-    assertProtocolsEqual(sslServerSocket.getSupportedProtocols(),
-        sslContext.getSupportedSSLParameters().getProtocols());
-
-    assertEquals(sslServerSocket.getNeedClientAuth(),
-        sslContext.getDefaultSSLParameters().getNeedClientAuth());
-    assertEquals(sslServerSocket.getWantClientAuth(),
-        sslContext.getDefaultSSLParameters().getWantClientAuth());
-  }
-
-  /**
-   * Asserts that the provided {@link SSLEngine} has the expected default configuration.
-   */
-  public static void assertSSLEngineDefaultConfiguration(SSLEngine sslEngine) throws Exception {
-    assertFalse(sslEngine.getUseClientMode());
-    assertTrue(sslEngine.getEnableSessionCreation());
-    assertSSLEngineConfigSameAsSSLContext(sslEngine, SSLContext.getDefault());
-  }
-
-  /**
-   * Asserts that {@link SSLEngine}'s configuration matches {@code SSLContext's} configuration.
-   */
-  private static void assertSSLEngineConfigSameAsSSLContext(SSLEngine sslEngine,
-      SSLContext sslContext) {
-    assertSSLParametersEqual(sslEngine.getSSLParameters(), sslContext.getDefaultSSLParameters());
-    assertCipherSuitesEqual(sslEngine.getEnabledCipherSuites(),
-        sslContext.getDefaultSSLParameters().getCipherSuites());
-    assertProtocolsEqual(sslEngine.getEnabledProtocols(),
-        sslContext.getDefaultSSLParameters().getProtocols());
-
-    assertCipherSuitesEqual(sslEngine.getSupportedCipherSuites(),
-        sslContext.getSupportedSSLParameters().getCipherSuites());
-    assertProtocolsEqual(sslEngine.getSupportedProtocols(),
-        sslContext.getSupportedSSLParameters().getProtocols());
-  }
-
   private static void assertSSLParametersEqual(SSLParameters expected, SSLParameters actual) {
     assertCipherSuitesEqual(expected.getCipherSuites(), actual.getCipherSuites());
     assertProtocolsEqual(expected.getProtocols(), actual.getProtocols());
@@ -236,13 +97,4 @@
     assertEquals(new HashSet<String>(Arrays.asList(expected)),
         new HashSet<String>(Arrays.asList(actual)));
   }
-
-  /**
-   * Asserts that the {@code container} contains all the {@code elements}.
-   */
-  private static void assertContainsAll(String message, String[] container, String[] elements) {
-    Set<String> elementsNotInContainer = new HashSet<String>(Arrays.asList(elements));
-    elementsNotInContainer.removeAll(Arrays.asList(container));
-    assertEquals(message, Collections.EMPTY_SET, elementsNotInContainer);
-  }
 }
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestKeyManager.java b/support/src/test/java/libcore/javax/net/ssl/TestKeyManager.java
index 03420fe6..5b49318 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestKeyManager.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestKeyManager.java
@@ -20,7 +20,6 @@
 import java.net.Socket;
 import java.security.Principal;
 import java.security.PrivateKey;
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLEngine;
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLSocketPair.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLSocketPair.java
index 55ce3bb..f96fc59 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLSocketPair.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLSocketPair.java
@@ -17,7 +17,6 @@
 package libcore.javax.net.ssl;
 
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
diff --git a/support/src/test/java/libcore/sun/security/x509/Utils.java b/support/src/test/java/libcore/sun/security/x509/Utils.java
deleted file mode 100644
index 412a06d..0000000
--- a/support/src/test/java/libcore/sun/security/x509/Utils.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 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.security.x509;
-
-import junit.framework.Assert;
-
-import java.util.function.Function;
-
-public class Utils extends Assert {
-    /**
-     * Many classes in this package can be created using a bit array, and the toString method
-     * depends only on the bit array. The logic for toString was changed in rev/04cda5b7a3c1.
-     * The expected result is the same before and after the change.
-     * @param parts The different parts of the result
-     * @param objectCreator Function to create a new instance of the class tested.
-     * @param prefix prefix in all toString results
-     * @param suffix suffix in all toString results
-     */
-    static void test_toString_bitArrayBasedClass(
-            String[] parts,
-            Function<byte[], Object> objectCreator,
-            String prefix,
-            String suffix) {
-        testWithEachSinglePart(parts, objectCreator, prefix, suffix);
-        testWithAllParts(parts, objectCreator, prefix, suffix);
-        testWithNoParts(parts, objectCreator, prefix, suffix);
-        testWithEveryOtherPart(parts, objectCreator, prefix, suffix);
-    }
-
-    private static void testWithEachSinglePart(
-            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
-        int bitCounter = 0, byteCounter = 1;
-        for (int i = 0; i < parts.length; i++) {
-            byte[] ba = new byte[byteCounter];
-            ba[byteCounter - 1] = (byte) (1 << (7 - bitCounter));
-            bitCounter++;
-            if (bitCounter == 8) {
-                bitCounter = 0;
-                byteCounter++;
-            }
-            Object o =  objectCreator.apply(ba);
-            assertEquals(prefix + parts[i] + suffix, o.toString());
-        }
-    }
-
-    private static void testWithAllParts(
-            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
-        int bitsInAByte = 8;
-        int allOnesLength = (parts.length + bitsInAByte - 1) / bitsInAByte;
-        byte[] allOnes = new byte[allOnesLength];
-
-        for (int i = 0; i < allOnes.length; i++) {
-            allOnes[i] = -1;
-        }
-        assertEquals(prefix + String.join("", parts)
-                + suffix, objectCreator.apply(allOnes).toString());
-    }
-
-    private static void testWithNoParts(
-            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
-        // Test with empty array
-        assertEquals(prefix + suffix, objectCreator.apply(new byte[0]).toString());
-
-        // Test with array will all zeros
-        assertEquals(prefix + suffix, objectCreator.apply(new byte[parts.length]).toString());
-    }
-
-    private static void testWithEveryOtherPart(
-            String[] parts, Function<byte[], Object> objectCreator, String prefix, String suffix) {
-        int bitsInAByte = 8;
-        byte[] ba = new byte[(parts.length + bitsInAByte - 1) / bitsInAByte];
-        String expectedResult = new String();
-        for (int i = 0; i < parts.length; i += 2) {
-            ba[i / bitsInAByte] = (byte) 170; // Binary 10101010
-            expectedResult += parts[i];
-        }
-        assertEquals(prefix + expectedResult + suffix, objectCreator.apply(ba).toString());
-    }
-}
diff --git a/support/src/test/java/libcore/testing/io/TestIoUtils.java b/support/src/test/java/libcore/testing/io/TestIoUtils.java
new file mode 100644
index 0000000..8e241df
--- /dev/null
+++ b/support/src/test/java/libcore/testing/io/TestIoUtils.java
@@ -0,0 +1,57 @@
+/*
+ * 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.testing.io;
+
+import java.io.File;
+import java.util.Random;
+
+public class TestIoUtils {
+    private final static Random random = new Random();
+
+    private TestIoUtils() {}
+
+    /**
+     * Creates a unique new temporary directory under "java.io.tmpdir".
+     */
+    public static File createTemporaryDirectory(String prefix) {
+        while (true) {
+            String candidateName = prefix + nextRandomInt();
+            File result = new File(System.getProperty("java.io.tmpdir"), candidateName);
+            if (result.mkdir()) {
+                return result;
+            }
+        }
+    }
+
+    /**
+     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
+     */
+    public static void closeQuietly(AutoCloseable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    private synchronized static int nextRandomInt() {
+        return random.nextInt();
+    }
+}
diff --git a/support/src/test/java/libcore/tlswire/handshake/CipherSuite.java b/support/src/test/java/libcore/tlswire/handshake/CipherSuite.java
deleted file mode 100644
index af9e103..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/CipherSuite.java
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@code CipherSuite} enum from TLS 1.2 RFC 5246.
- */
-public class CipherSuite {
-    // The list of cipher suites below is based on IANA registry
-    // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
-    private static final CipherSuite[] CIPHER_SUITES = new CipherSuite[] {
-        new CipherSuite(0x0000, "TLS_NULL_WITH_NULL_NULL"),
-        new CipherSuite(0x0001, "TLS_RSA_WITH_NULL_MD5", "SSL_RSA_WITH_NULL_MD5"),
-        new CipherSuite(0x0002, "TLS_RSA_WITH_NULL_SHA", "SSL_RSA_WITH_NULL_SHA"),
-        new CipherSuite(0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_EXPORT_WITH_RC4_40_MD5"),
-        new CipherSuite(0x0004, "TLS_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_MD5"),
-        new CipherSuite(0x0005, "TLS_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_SHA"),
-        new CipherSuite(0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
-        new CipherSuite(0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA"),
-        new CipherSuite(0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
-                "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x0009, "TLS_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x000a, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x000b, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x000c, "TLS_DH_DSS_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x000d, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x000e, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x000f, "TLS_DH_RSA_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
-                "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
-                "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
-                "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
-                "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
-                "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"),
-        new CipherSuite(0x0018, "TLS_DH_anon_WITH_RC4_128_MD5", "SSL_DH_anon_WITH_RC4_128_MD5"),
-        new CipherSuite(0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-                "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"),
-        new CipherSuite(0x001a, "TLS_DH_anon_WITH_DES_CBC_SHA", "SSL_DH_anon_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x001b, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA",
-                "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x001e, "TLS_KRB5_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x001f, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0020, "TLS_KRB5_WITH_RC4_128_SHA"),
-        new CipherSuite(0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"),
-        new CipherSuite(0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"),
-        new CipherSuite(0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"),
-        new CipherSuite(0x0024, "TLS_KRB5_WITH_RC4_128_MD5"),
-        new CipherSuite(0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"),
-        new CipherSuite(0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"),
-        new CipherSuite(0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"),
-        new CipherSuite(0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"),
-        new CipherSuite(0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"),
-        new CipherSuite(0x002a, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"),
-        new CipherSuite(0x002b, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"),
-        new CipherSuite(0x002c, "TLS_PSK_WITH_NULL_SHA"),
-        new CipherSuite(0x002d, "TLS_DHE_PSK_WITH_NULL_SHA"),
-        new CipherSuite(0x002e, "TLS_RSA_PSK_WITH_NULL_SHA"),
-        new CipherSuite(0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x003a, "TLS_DH_anon_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x003b, "TLS_RSA_WITH_NULL_SHA256"),
-        new CipherSuite(0x003c, "TLS_RSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x003d, "TLS_RSA_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x003e, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x003f, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"),
-        new CipherSuite(0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5"),
-        new CipherSuite(0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5"),
-        new CipherSuite(0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA"),
-        new CipherSuite(0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"),
-        new CipherSuite(0x0065, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA"),
-        new CipherSuite(0x0066, "TLS_DHE_DSS_WITH_RC4_128_SHA"),
-        new CipherSuite(0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x006a, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x006b, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x006c, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x006d, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"),
-        new CipherSuite(0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"),
-        new CipherSuite(0x008a, "TLS_PSK_WITH_RC4_128_SHA"),
-        new CipherSuite(0x008b, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x008c, "TLS_PSK_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x008d, "TLS_PSK_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x008e, "TLS_DHE_PSK_WITH_RC4_128_SHA"),
-        new CipherSuite(0x008f, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"),
-        new CipherSuite(0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x009a, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x009b, "TLS_DH_anon_WITH_SEED_CBC_SHA"),
-        new CipherSuite(0x009c, "TLS_RSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x009d, "TLS_RSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x009e, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x009f, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00a0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00a1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00a2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00a3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00a4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00a5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00a6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00a7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00a8, "TLS_PSK_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00a9, "TLS_PSK_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00aa, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00ab, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00ac, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0x00ad, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0x00ae, "TLS_PSK_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x00af, "TLS_PSK_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0x00b0, "TLS_PSK_WITH_NULL_SHA256"),
-        new CipherSuite(0x00b1, "TLS_PSK_WITH_NULL_SHA384"),
-        new CipherSuite(0x00b2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x00b3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0x00b4, "TLS_DHE_PSK_WITH_NULL_SHA256"),
-        new CipherSuite(0x00b5, "TLS_DHE_PSK_WITH_NULL_SHA384"),
-        new CipherSuite(0x00b6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0x00b7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0x00b8, "TLS_RSA_PSK_WITH_NULL_SHA256"),
-        new CipherSuite(0x00b9, "TLS_RSA_PSK_WITH_NULL_SHA384"),
-        new CipherSuite(0x00ba, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00bb, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00bc, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00bd, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00be, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00bf, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0x00c0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00c1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00c2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00c3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00c4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00c5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"),
-        new CipherSuite(0x00ff, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"),
-        new CipherSuite(0x5600, "TLS_FALLBACK_SCSV"),
-        new CipherSuite(0xc001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"),
-        new CipherSuite(0xc002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"),
-        new CipherSuite(0xc007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc00a, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc00b, "TLS_ECDH_RSA_WITH_NULL_SHA"),
-        new CipherSuite(0xc00c, "TLS_ECDH_RSA_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc00d, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc00e, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc00f, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc010, "TLS_ECDHE_RSA_WITH_NULL_SHA"),
-        new CipherSuite(0xc011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc015, "TLS_ECDH_anon_WITH_NULL_SHA"),
-        new CipherSuite(0xc016, "TLS_ECDH_anon_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc01a, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc01b, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc01c, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc01d, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc01e, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc01f, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0xc024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0xc025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0xc026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0xc027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0xc028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0xc029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0xc02a, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0xc02d, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0xc02e, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0xc02f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0xc030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0xc031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"),
-        new CipherSuite(0xc032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"),
-        new CipherSuite(0xc033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA"),
-        new CipherSuite(0xc034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA"),
-        new CipherSuite(0xc035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"),
-        new CipherSuite(0xc036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA"),
-        new CipherSuite(0xc037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"),
-        new CipherSuite(0xc038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384"),
-        new CipherSuite(0xc039, "TLS_ECDHE_PSK_WITH_NULL_SHA"),
-        new CipherSuite(0xc03a, "TLS_ECDHE_PSK_WITH_NULL_SHA256"),
-        new CipherSuite(0xc03b, "TLS_ECDHE_PSK_WITH_NULL_SHA384"),
-        new CipherSuite(0xc03c, "TLS_RSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc03d, "TLS_RSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc03e, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc03f, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc04a, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc04b, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc04c, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc04d, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc04e, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc04f, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc05a, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc05b, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc05c, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc05d, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc05e, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc05f, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc06a, "TLS_PSK_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc06b, "TLS_PSK_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc06c, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc06d, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc06e, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256"),
-        new CipherSuite(0xc06f, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384"),
-        new CipherSuite(0xc070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256"),
-        new CipherSuite(0xc071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384"),
-        new CipherSuite(0xc072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc07a, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc07b, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc07c, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc07d, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc07e, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc07f, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc08a, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc08b, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc08c, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc08d, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc08e, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc08f, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
-        new CipherSuite(0xc093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
-        new CipherSuite(0xc094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc09a, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
-        new CipherSuite(0xc09b, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
-        new CipherSuite(0xc09c, "TLS_RSA_WITH_AES_128_CCM"),
-        new CipherSuite(0xc09d, "TLS_RSA_WITH_AES_256_CCM"),
-        new CipherSuite(0xc09e, "TLS_DHE_RSA_WITH_AES_128_CCM"),
-        new CipherSuite(0xc09f, "TLS_DHE_RSA_WITH_AES_256_CCM"),
-        new CipherSuite(0xc0a0, "TLS_RSA_WITH_AES_128_CCM_8"),
-        new CipherSuite(0xc0a1, "TLS_RSA_WITH_AES_256_CCM_8"),
-        new CipherSuite(0xc0a2, "TLS_DHE_RSA_WITH_AES_128_CCM_8"),
-        new CipherSuite(0xc0a3, "TLS_DHE_RSA_WITH_AES_256_CCM_8"),
-        new CipherSuite(0xc0a4, "TLS_PSK_WITH_AES_128_CCM"),
-        new CipherSuite(0xc0a5, "TLS_PSK_WITH_AES_256_CCM"),
-        new CipherSuite(0xc0a6, "TLS_DHE_PSK_WITH_AES_128_CCM"),
-        new CipherSuite(0xc0a7, "TLS_DHE_PSK_WITH_AES_256_CCM"),
-        new CipherSuite(0xc0a8, "TLS_PSK_WITH_AES_128_CCM_8"),
-        new CipherSuite(0xc0a9, "TLS_PSK_WITH_AES_256_CCM_8"),
-        new CipherSuite(0xc0aa, "TLS_PSK_DHE_WITH_AES_128_CCM_8"),
-        new CipherSuite(0xc0ab, "TLS_PSK_DHE_WITH_AES_256_CCM_8"),
-        new CipherSuite(0xc0ac, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"),
-        new CipherSuite(0xc0ad, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"),
-        new CipherSuite(0xc0ae, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"),
-        new CipherSuite(0xc0af, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"),
-        new CipherSuite(0xcc13, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD"),
-        new CipherSuite(0xcc14, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD"),
-        new CipherSuite(0xcc15, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_OLD"),
-        new CipherSuite(0xcca8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xccaa, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xccab, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xccac, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xccad, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256"),
-        new CipherSuite(0xccae, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256"),
-    };
-
-    private static final Map<Integer, CipherSuite> CODE_TO_CIPHER_SUITE;
-    private static final Map<String, CipherSuite> NAME_TO_CIPHER_SUITE;
-
-
-    static {
-        Map<Integer, CipherSuite> byCode = new HashMap<Integer, CipherSuite>();
-        Map<String, CipherSuite> byName = new HashMap<String, CipherSuite>();
-        for (CipherSuite cipherSuite : CIPHER_SUITES) {
-            if (byCode.put(cipherSuite.code, cipherSuite) != null) {
-                throw new RuntimeException(
-                        "Cipher suite multiply defined: " + Integer.toHexString(cipherSuite.code));
-            }
-            String name = cipherSuite.name;
-            if (byName.put(name, cipherSuite) != null) {
-                throw new RuntimeException(
-                        "Cipher suite multiply defined: " + cipherSuite.name);
-            }
-            String androidName = cipherSuite.getAndroidName();
-            if (!name.equals(androidName)) {
-                if (byName.put(androidName, cipherSuite) != null) {
-                    throw new RuntimeException(
-                            "Cipher suite multiply defined: " + cipherSuite.androidName);
-                }
-            }
-        }
-
-        CODE_TO_CIPHER_SUITE = byCode;
-        NAME_TO_CIPHER_SUITE = byName;
-    }
-
-    public final int code;
-    public final String name;
-    private final String androidName;
-
-    private CipherSuite(int code, String name) {
-        this.code = code;
-        this.name = name;
-        this.androidName = null;
-    }
-
-    private CipherSuite(int code, String name, String androidName) {
-        this.code = code;
-        this.name = name;
-        this.androidName = androidName;
-    }
-
-    public static CipherSuite valueOf(String name) {
-        CipherSuite result = NAME_TO_CIPHER_SUITE.get(name);
-        if (result != null) {
-            return result;
-        }
-        throw new IllegalArgumentException("Unknown cipher suite: " + name);
-    }
-
-    public static CipherSuite valueOf(int code) {
-        CipherSuite result = CODE_TO_CIPHER_SUITE.get(code);
-        if (result != null) {
-            return result;
-        }
-        return new CipherSuite(code, Integer.toHexString(code));
-    }
-
-    public String getAndroidName() {
-        return (androidName != null) ? androidName : name;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + code;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        CipherSuite other = (CipherSuite) obj;
-        if (code != other.code) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/ClientHello.java b/support/src/test/java/libcore/tlswire/handshake/ClientHello.java
deleted file mode 100644
index dd42cb1..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/ClientHello.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-import libcore.tlswire.util.TlsProtocolVersion;
-import libcore.tlswire.util.IoUtils;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link ClientHello} {@link HandshakeMessage} from TLS 1.2 RFC 5246.
- */
-public class ClientHello extends HandshakeMessage {
-    public TlsProtocolVersion clientVersion;
-    public byte[] random;
-    public byte[] sessionId;
-    public List<CipherSuite> cipherSuites;
-    public List<CompressionMethod> compressionMethods;
-
-    /** Extensions or {@code null} for no extensions. */
-    public List<HelloExtension> extensions;
-
-    @Override
-    protected void parseBody(DataInput in) throws IOException {
-        clientVersion = TlsProtocolVersion.read(in);
-        random = new byte[32];
-        in.readFully(random);
-        sessionId = IoUtils.readTlsVariableLengthByteVector(in, 32);
-        int[] cipherSuiteCodes = IoUtils.readTlsVariableLengthUnsignedShortVector(in, 0xfffe);
-        cipherSuites = new ArrayList<CipherSuite>(cipherSuiteCodes.length);
-        for (int i = 0; i < cipherSuiteCodes.length; i++) {
-            cipherSuites.add(CipherSuite.valueOf(cipherSuiteCodes[i]));
-        }
-        byte[] compressionMethodCodes = IoUtils.readTlsVariableLengthByteVector(in, 0xff);
-        compressionMethods = new ArrayList<CompressionMethod>(compressionMethodCodes.length);
-        for (int i = 0; i < compressionMethodCodes.length; i++) {
-            int code = compressionMethodCodes[i] & 0xff;
-            compressionMethods.add(CompressionMethod.valueOf(code));
-        }
-
-        int extensionsSectionSize;
-        try {
-            extensionsSectionSize = in.readUnsignedShort();
-        } catch (EOFException e) {
-            // No extensions present
-            extensionsSectionSize = 0;
-        }
-
-        if (extensionsSectionSize > 0) {
-            extensions = new ArrayList<HelloExtension>();
-            byte[] extensionsBytes = new byte[extensionsSectionSize];
-            in.readFully(extensionsBytes);
-            ByteArrayInputStream extensionsIn = new ByteArrayInputStream(extensionsBytes);
-            DataInput extensionsDataIn = new DataInputStream(extensionsIn);
-            while (extensionsIn.available() > 0) {
-                try {
-                    extensions.add(HelloExtension.read(extensionsDataIn));
-                } catch (IOException e) {
-                    throw new IOException(
-                            "Failed to read HelloExtension #" + (extensions.size() + 1));
-                }
-            }
-        }
-    }
-
-    public HelloExtension findExtensionByType(int extensionType) {
-        if (extensions == null) {
-            return null;
-        }
-        for (HelloExtension extension : extensions) {
-            if (extension.type == extensionType) {
-                return extension;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return "ClientHello{client version: " + clientVersion
-                + ", random: " + new BigInteger(1, random).toString(16)
-                + ", sessionId: " + new BigInteger(1, sessionId).toString(16)
-                + ", cipher suites: " + cipherSuites
-                + ", compression methods: " + compressionMethods
-                + ((extensions != null) ? (", extensions: " + String.valueOf(extensions)) : "")
-                + "}";
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/CompressionMethod.java b/support/src/test/java/libcore/tlswire/handshake/CompressionMethod.java
deleted file mode 100644
index 0f4f619..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/CompressionMethod.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-/**
- * {@code CompressionMethod} enum from TLS 1.2 RFC 5246.
- */
-public class CompressionMethod {
-
-    public static final CompressionMethod NULL = new CompressionMethod(0, "null");
-    public static final CompressionMethod DEFLATE = new CompressionMethod(1, "deflate");
-
-    public final int type;
-    public final String name;
-
-    private CompressionMethod(int type, String name) {
-        this.type = type;
-        this.name = name;
-    }
-
-    public static CompressionMethod valueOf(int type) {
-        switch (type) {
-            case 0:
-                return NULL;
-            case 1:
-                return DEFLATE;
-            default:
-                return new CompressionMethod(type, String.valueOf(type));
-        }
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + type;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        CompressionMethod other = (CompressionMethod) obj;
-        if (type != other.type) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java b/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java
deleted file mode 100644
index 51bcf8e..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/EllipticCurve.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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.tlswire.handshake;
-
-/**
- * {@code EllipticCurve} enum from RFC 4492 section 5.1.1. Curves are assigned
- * via the
- * <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8">IANA registry</a>.
- */
-public enum EllipticCurve {
-    SECT163K1(1, "sect163k1"),
-    SECT163R1(2, "sect163r1"),
-    SECT163R2(3, "sect163r2"),
-    SECT193R1(4, "sect193r1"),
-    SECT193R2(5, "sect193r2"),
-    SECT233K1(6, "sect233k1"),
-    SECT233R1(7, "sect233r1"),
-    SECT239K1(8, "sect239k1"),
-    SECT283K1(9, "sect283k1"),
-    SECT283R1(10, "sect283r1"),
-    SECT409K1(11, "sect409k1"),
-    SECT409R1(12, "sect409r1"),
-    SECT571K1(13, "sect571k1"),
-    SECT571R1(14, "sect571r1"),
-    SECP160K1(15, "secp160k1"),
-    SECP160R1(16, "secp160r1"),
-    SECP160R2(17, "secp160r2"),
-    SECP192K1(18, "secp192k1"),
-    SECP192R1(19, "secp192r1"),
-    SECP224K1(20, "secp224k1"),
-    SECP224R1(21, "secp224r1"),
-    SECP256K1(22, "secp256k1"),
-    SECP256R1(23, "secp256r1"),
-    SECP384R1(24, "secp384r1"),
-    SECP521R1(25, "secp521r1"),
-    BRAINPOOLP256R1(26, "brainpoolP256r1"),
-    BRAINPOOLP384R1(27, "brainpoolP384r1"),
-    BRAINPOOLP521R1(28, "brainpoolP521r1"),
-    X25519(29, "x25519"),
-    X448(30, "x448"),
-    ARBITRARY_PRIME(0xFF01, "arbitrary_explicit_prime_curves"),
-    ARBITRARY_CHAR2(0xFF02, "arbitrary_explicit_char2_curves");
-
-    public final int identifier;
-    public final String name;
-
-    private EllipticCurve(int identifier, String name) {
-        this.identifier = identifier;
-        this.name = name;
-    }
-
-    public static EllipticCurve fromIdentifier(int identifier) {
-        for (EllipticCurve curve : values()) {
-            if (curve.identifier == identifier) {
-                return curve;
-            }
-        }
-        throw new AssertionError("Unknown curve identifier " + identifier);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(name);
-        sb.append(" (");
-        sb.append(identifier);
-        sb.append(')');
-        return sb.toString();
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java
deleted file mode 100644
index 19749a3..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/EllipticCurvesHelloExtension.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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.tlswire.handshake;
-
-import libcore.tlswire.util.IoUtils;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@code elliptic_curves} {@link HelloExtension} from RFC 4492 section 5.1.1.
- */
-public class EllipticCurvesHelloExtension extends HelloExtension {
-    public List<EllipticCurve> supported;
-    public boolean wellFormed;
-
-    @Override
-    protected void parseData() throws IOException {
-        byte[] ellipticCurvesListBytes = IoUtils.readTlsVariableLengthByteVector(
-                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
-        ByteArrayInputStream ellipticCurvesListIn = new ByteArrayInputStream(ellipticCurvesListBytes);
-        DataInputStream in = new DataInputStream(ellipticCurvesListIn);
-        wellFormed = (ellipticCurvesListIn.available() % 2) == 0;
-        supported = new ArrayList<EllipticCurve>(ellipticCurvesListIn.available() / 2);
-        while (ellipticCurvesListIn.available() >= 2) {
-            int curve_id = in.readUnsignedShort();
-            supported.add(EllipticCurve.fromIdentifier(curve_id));
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("HelloExtension{type: elliptic_curves, wellFormed: ");
-        sb.append(wellFormed);
-        sb.append(", supported: ");
-        sb.append(supported);
-        sb.append('}');
-        return sb.toString();
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/HandshakeMessage.java b/support/src/test/java/libcore/tlswire/handshake/HandshakeMessage.java
deleted file mode 100644
index a855b46..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/HandshakeMessage.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-import libcore.tlswire.util.IoUtils;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.IOException;
-
-/**
- * Handshake Protocol message from TLS 1.2 RFC 5246.
- */
-public class HandshakeMessage {
-    public static final int TYPE_CLIENT_HELLO = 1;
-
-    public int type;
-    public byte[] body;
-
-    /**
-     * Parses the provided TLS record as a handshake message.
-     */
-    public static HandshakeMessage read(DataInput in) throws IOException {
-        int type = in.readUnsignedByte();
-        HandshakeMessage result;
-        switch (type) {
-            case TYPE_CLIENT_HELLO:
-                result = new ClientHello();
-                break;
-            default:
-                result = new HandshakeMessage();
-                break;
-        }
-        result.type = type;
-        int bodyLength = IoUtils.readUnsignedInt24(in);
-        result.body = new byte[bodyLength];
-        in.readFully(result.body);
-        result.parseBody(new DataInputStream(new ByteArrayInputStream(result.body)));
-        return result;
-    }
-
-    /**
-     * Parses the provided body. The default implementation does nothing.
-     *
-     * @throws IOException if an I/O error occurs.
-     */
-    protected void parseBody(@SuppressWarnings("unused") DataInput in) throws IOException {}
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
deleted file mode 100644
index 567c082..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-import libcore.tlswire.util.IoUtils;
-import java.io.DataInput;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@code HelloExtension} struct from TLS 1.2 RFC 5246.
- */
-public class HelloExtension {
-
-    public static final int TYPE_SERVER_NAME = 0;
-    public static final int TYPE_ELLIPTIC_CURVES = 10;
-    public static final int TYPE_PADDING = 21;
-    public static final int TYPE_SESSION_TICKET = 35;
-    public static final int TYPE_RENEGOTIATION_INFO = 65281;
-
-    private static final Map<Integer, String> TYPE_TO_NAME = new HashMap<Integer, String>();
-    static {
-        TYPE_TO_NAME.put(TYPE_SERVER_NAME, "server_name");
-        TYPE_TO_NAME.put(1, "max_fragment_length");
-        TYPE_TO_NAME.put(2, "client_certificate_url");
-        TYPE_TO_NAME.put(3, "trusted_ca_keys");
-        TYPE_TO_NAME.put(4, "truncated_hmac");
-        TYPE_TO_NAME.put(5, "status_request");
-        TYPE_TO_NAME.put(6, "user_mapping");
-        TYPE_TO_NAME.put(7, "client_authz");
-        TYPE_TO_NAME.put(8, "server_authz");
-        TYPE_TO_NAME.put(9, "cert_type");
-        TYPE_TO_NAME.put(TYPE_ELLIPTIC_CURVES, "elliptic_curves");
-        TYPE_TO_NAME.put(11, "ec_point_formats");
-        TYPE_TO_NAME.put(12, "srp");
-        TYPE_TO_NAME.put(13, "signature_algorithms");
-        TYPE_TO_NAME.put(14, "use_srtp");
-        TYPE_TO_NAME.put(15, "heartbeat");
-        TYPE_TO_NAME.put(16, "application_layer_protocol_negotiation");
-        TYPE_TO_NAME.put(17, "status_request_v2");
-        TYPE_TO_NAME.put(18, "signed_certificate_timestamp");
-        TYPE_TO_NAME.put(19, "client_certificate_type");
-        TYPE_TO_NAME.put(20, "server_certificate_type");
-        TYPE_TO_NAME.put(TYPE_PADDING, "padding");
-        TYPE_TO_NAME.put(TYPE_SESSION_TICKET, "SessionTicket");
-        TYPE_TO_NAME.put(13172, "next_protocol_negotiation");
-        TYPE_TO_NAME.put(30031, "Channel ID (old)");
-        TYPE_TO_NAME.put(30032, "Channel ID (new)");
-        TYPE_TO_NAME.put(TYPE_RENEGOTIATION_INFO, "renegotiation_info");
-    }
-
-    public int type;
-    public String name;
-    public byte[] data;
-
-    public static HelloExtension read(DataInput in) throws IOException {
-        int type = in.readUnsignedShort();
-        HelloExtension result;
-        switch (type) {
-            case TYPE_SERVER_NAME:
-                result = new ServerNameHelloExtension();
-                break;
-            case TYPE_ELLIPTIC_CURVES:
-                result = new EllipticCurvesHelloExtension();
-                break;
-            default:
-                result = new HelloExtension();
-                break;
-        }
-        result.type = type;
-        result.name = TYPE_TO_NAME.get(result.type);
-        if (result.name == null) {
-            result.name = String.valueOf(result.type);
-        }
-        result.data = IoUtils.readTlsVariableLengthByteVector(in, 0xffff);
-        result.parseData();
-        return result;
-    }
-
-    /**
-     * @throws IOException
-     */
-    protected void parseData() throws IOException {}
-
-    @Override
-    public String toString() {
-        return "HelloExtension{type: " + name + ", data: " + new BigInteger(1, data).toString(16)
-            + "}";
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/handshake/ServerNameHelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/ServerNameHelloExtension.java
deleted file mode 100644
index 5b06246..0000000
--- a/support/src/test/java/libcore/tlswire/handshake/ServerNameHelloExtension.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.handshake;
-
-import libcore.tlswire.util.IoUtils;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@code server_name} (SNI) {@link HelloExtension} from TLS 1.2 RFC 5246.
- */
-public class ServerNameHelloExtension extends HelloExtension {
-    private static final int TYPE_HOST_NAME = 0;
-
-    public List<String> hostnames;
-
-    @Override
-    protected void parseData() throws IOException {
-        byte[] serverNameListBytes = IoUtils.readTlsVariableLengthByteVector(
-                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
-        ByteArrayInputStream serverNameListIn = new ByteArrayInputStream(serverNameListBytes);
-        DataInputStream in = new DataInputStream(serverNameListIn);
-        hostnames = new ArrayList<String>();
-        while (serverNameListIn.available() > 0) {
-            int type = in.readUnsignedByte();
-            if (type != TYPE_HOST_NAME) {
-                throw new IOException("Unsupported ServerName type: " + type);
-            }
-            byte[] hostnameBytes = IoUtils.readTlsVariableLengthByteVector(in, 0xffff);
-            String hostname = new String(hostnameBytes, "US-ASCII");
-            hostnames.add(hostname);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "HelloExtension{type: server_name, hostnames: " + hostnames + "}";
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/record/TlsProtocols.java b/support/src/test/java/libcore/tlswire/record/TlsProtocols.java
deleted file mode 100644
index 0ce0d35..0000000
--- a/support/src/test/java/libcore/tlswire/record/TlsProtocols.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.record;
-
-/**
- * Protocols that can run over the TLS Record Protocol from TLS 1.2 RFC 5246.
- */
-public class TlsProtocols {
-    public static final int CHANGE_CIPHER_SPEC = 20;
-    public static final int ALERT = 21;
-    public static final int HANDSHAKE = 22;
-    public static final int APPLICATION_DATA = 23;
-    public static final int HEARTBEAT = 24;
-
-    private TlsProtocols() {}
-}
diff --git a/support/src/test/java/libcore/tlswire/record/TlsRecord.java b/support/src/test/java/libcore/tlswire/record/TlsRecord.java
deleted file mode 100644
index 1b60407..0000000
--- a/support/src/test/java/libcore/tlswire/record/TlsRecord.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.record;
-
-import libcore.tlswire.util.TlsProtocolVersion;
-import java.io.DataInput;
-import java.io.IOException;
-
-/**
- * TLS Record Protocol record from TLS 1.2 RFC 5246.
- */
-public class TlsRecord {
-    public int type;
-    public TlsProtocolVersion version;
-    public byte[] fragment;
-
-    public static TlsRecord read(DataInput in) throws IOException {
-        TlsRecord result = new TlsRecord();
-        result.type = in.readUnsignedByte();
-        result.version = TlsProtocolVersion.read(in);
-        int fragmentLength = in.readUnsignedShort();
-        result.fragment = new byte[fragmentLength];
-        in.readFully(result.fragment);
-        return result;
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/util/IoUtils.java b/support/src/test/java/libcore/tlswire/util/IoUtils.java
deleted file mode 100644
index 1e2d8f2..0000000
--- a/support/src/test/java/libcore/tlswire/util/IoUtils.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.util;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-public class IoUtils {
-
-    public static int readUnsignedInt24(DataInput in) throws IOException {
-        return (in.readUnsignedByte() << 16) | in.readUnsignedShort();
-    }
-
-    public static byte[] readTlsVariableLengthByteVector(DataInput in, int maxSizeBytes)
-            throws IOException {
-        int sizeBytes = readTlsVariableLengthVectorSizeBytes(in, maxSizeBytes);
-        byte[] result = new byte[sizeBytes];
-        in.readFully(result);
-        return result;
-    }
-
-    public static int[] readTlsVariableLengthUnsignedShortVector(DataInput in, int maxSizeBytes)
-            throws IOException {
-        int sizeBytes = readTlsVariableLengthVectorSizeBytes(in, maxSizeBytes);
-        int elementCount = sizeBytes / 2;
-        int[] result = new int[elementCount];
-        for (int i = 0; i < elementCount; i++) {
-            result[i] = in.readUnsignedShort();
-        }
-        return result;
-    }
-
-    private static int readTlsVariableLengthVectorSizeBytes(DataInput in, int maxSizeBytes)
-            throws IOException {
-        if (maxSizeBytes < 0x100) {
-            return in.readUnsignedByte();
-        } else if (maxSizeBytes < 0x10000) {
-            return in.readUnsignedShort();
-        } else if (maxSizeBytes < 0x1000000) {
-            return readUnsignedInt24(in);
-        } else {
-            return in.readInt();
-        }
-    }
-}
diff --git a/support/src/test/java/libcore/tlswire/util/TlsProtocolVersion.java b/support/src/test/java/libcore/tlswire/util/TlsProtocolVersion.java
deleted file mode 100644
index f58faf2..0000000
--- a/support/src/test/java/libcore/tlswire/util/TlsProtocolVersion.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2014 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.tlswire.util;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-/**
- * {@code ProtovolVersion} struct from TLS 1.2 RFC 5246.
- */
-public class TlsProtocolVersion {
-    public static final TlsProtocolVersion SSLV3 = new TlsProtocolVersion(3, 0, "SSLv3");
-    public static final TlsProtocolVersion TLSv1_0 = new TlsProtocolVersion(3, 1, "TLSv1.0");
-    public static final TlsProtocolVersion TLSv1_1 = new TlsProtocolVersion(3, 2, "TLSv1.1");
-    public static final TlsProtocolVersion TLSv1_2 = new TlsProtocolVersion(3, 3, "TLSv1.2");
-
-    public final int major;
-    public final int minor;
-    public final String name;
-
-    private TlsProtocolVersion(int major, int minor, String name) {
-        this.major = major;
-        this.minor = minor;
-        this.name = name;
-    }
-
-    public static TlsProtocolVersion valueOf(int major, int minor) {
-        if (major == 3) {
-            switch (minor) {
-                case 0:
-                    return SSLV3;
-                case 1:
-                    return TLSv1_0;
-                case 2:
-                    return TLSv1_1;
-                case 3:
-                    return TLSv1_2;
-            }
-        }
-        return new TlsProtocolVersion(major, minor, major + "." + minor);
-    }
-
-    public static TlsProtocolVersion read(DataInput in) throws IOException {
-        int major = in.readUnsignedByte();
-        int minor = in.readUnsignedByte();
-        return TlsProtocolVersion.valueOf(major, minor);
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + major;
-        result = prime * result + minor;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        TlsProtocolVersion other = (TlsProtocolVersion) obj;
-        if (major != other.major) {
-            return false;
-        }
-        if (minor != other.minor) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MyBasicPermission.java b/support/src/test/java/org/apache/harmony/security/tests/support/MyBasicPermission.java
deleted file mode 100644
index a0dbcea..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MyBasicPermission.java
+++ /dev/null
@@ -1,29 +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.security.tests.support;
-
-import java.security.BasicPermission;
-import java.security.Permission;
-
-public class MyBasicPermission extends BasicPermission {
-    public MyBasicPermission(String name) { super(""); }
-
-    @Override public String getActions() { return null; }
-
-    @Override public boolean implies(Permission permission) { return true; }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MyGuard.java b/support/src/test/java/org/apache/harmony/security/tests/support/MyGuard.java
deleted file mode 100644
index 073c928..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MyGuard.java
+++ /dev/null
@@ -1,38 +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.security.tests.support;
-
-import java.io.Serializable;
-import java.security.Guard;
-
-public class MyGuard implements Guard, Serializable {
-
-    private static final long serialVersionUID = 5767944725614823373L;
-
-    final boolean enabled;
-
-    public MyGuard(boolean state) {
-        enabled = state;
-    }
-
-    public void checkGuard(Object object) {
-        if (!enabled) {
-            throw new SecurityException();
-        }
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MyMessageDigest2.java b/support/src/test/java/org/apache/harmony/security/tests/support/MyMessageDigest2.java
deleted file mode 100644
index b9fb959..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MyMessageDigest2.java
+++ /dev/null
@@ -1,73 +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.
- */
-
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.tests.support;
-
-import java.security.MessageDigestSpi;
-
-/**
- * Tests implementation of MessageDigest
- *
- */
-public class MyMessageDigest2 extends MessageDigestSpi {
-
-    public static boolean runEngineReset = false;
-    public static boolean runEngineDigest = false;
-    public static boolean runEngineUpdate1 = false;
-    public static boolean runEngineUpdate2 = false;
-
-    /**
-     *
-     */
-    public void engineReset() {
-        runEngineReset = true;
-    }
-
-    /**
-     *
-     */
-    public byte[] engineDigest() {
-        runEngineDigest = true;
-        return new byte[0];
-    }
-
-    /**
-     *
-     */
-    public void engineUpdate(byte arg0) {
-        runEngineUpdate1 = true;
-    }
-
-    /**
-     *
-     */
-    public void engineUpdate(byte[] arg0, int arg1, int arg2) {
-        runEngineUpdate2 = true;
-    }
-
-    /**
-     * The implementation is not cloneable
-     */
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java b/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java
deleted file mode 100644
index 9da7a6f..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java
+++ /dev/null
@@ -1,157 +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.security.tests.support;
-
-import java.nio.ByteBuffer;
-import java.security.KeyManagementException;
-import java.security.SecureRandom;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContextSpi;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-/**
- * Additional class for verification of SSLContextSpi and SSLContext
- * functionality
- *
- */
-
-public class MySSLContextSpi extends SSLContextSpi {
-
-    private boolean init = false;
-
-    protected void engineInit(KeyManager[] km, TrustManager[] tm,
-            SecureRandom sr) throws KeyManagementException {
-        if (sr == null) {
-            throw new KeyManagementException(
-                    "secureRandom is null");
-        }
-        init = true;
-    }
-
-    protected SSLSocketFactory engineGetSocketFactory() {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return null;
-    }
-
-    protected SSLServerSocketFactory engineGetServerSocketFactory() {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return null;
-    }
-
-    protected SSLSessionContext engineGetServerSessionContext() {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return null;
-    }
-
-    protected SSLSessionContext engineGetClientSessionContext() {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return null;
-    }
-
-    protected SSLParameters engineGetDefaultSSLParameters() {
-        engineGetSocketFactory();
-        return null;
-    }
-
-    protected SSLParameters engineGetSupportedSSLParameters() {
-        engineGetSocketFactory();
-        return null;
-    }
-
-    /*
-     * FIXME: add these methods
-     */
-    protected SSLEngine engineCreateSSLEngine(String host, int port) {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return new tmpSSLEngine(host, port);
-    }
-
-    protected SSLEngine engineCreateSSLEngine() {
-        if (!init) {
-            throw new RuntimeException("Not initialiazed");
-        }
-        return new tmpSSLEngine();
-    }
-
-    public class tmpSSLEngine extends SSLEngine {
-        String tmpHost;
-        int tmpPort;
-        public tmpSSLEngine() {
-            tmpHost = null;
-            tmpPort = 0;
-        }
-        public tmpSSLEngine(String host, int port) {
-            tmpHost = host;
-            tmpPort = port;
-        }
-        public String getPeerHost() {
-            return tmpHost;
-        }
-        public int getPeerPort() {
-            return tmpPort;
-        }
-        public void beginHandshake() throws SSLException { }
-        public void closeInbound() throws SSLException { }
-        public void closeOutbound() {}
-        public Runnable getDelegatedTask() { return null; }
-        public String[] getEnabledCipherSuites() { return null; }
-        public String[] getEnabledProtocols() {return null; }
-        public boolean getEnableSessionCreation() { return true; }
-        public SSLEngineResult.HandshakeStatus getHandshakeStatus() { return null; }
-        public boolean getNeedClientAuth() { return true; }
-        public SSLSession getSession() { return null; }
-        public String[] getSupportedCipherSuites()  { return null; }
-        public String[] getSupportedProtocols()  { return null; }
-        public boolean getUseClientMode()  { return true; }
-        public boolean getWantClientAuth()  { return true; }
-        public boolean isInboundDone()  { return true; }
-        public boolean isOutboundDone()  { return true; }
-        public void setEnabledCipherSuites(String[] suites) { }
-        public void setEnabledProtocols(String[] protocols) { }
-        public void setEnableSessionCreation(boolean flag) { }
-        public void setNeedClientAuth(boolean need) { }
-        public void setUseClientMode(boolean mode) { }
-        public void setWantClientAuth(boolean want) { }
-        public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts,
-                int offset, int length) throws SSLException {
-            return null;
-        }
-        public SSLEngineResult wrap(ByteBuffer[] srcs, int offset,
-                int length, ByteBuffer dst) throws SSLException {
-            return null;
-        }
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MySignature2.java b/support/src/test/java/org/apache/harmony/security/tests/support/MySignature2.java
deleted file mode 100644
index 1742800..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MySignature2.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.
- */
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.tests.support;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.SignatureSpi;
-
-/**
- * Tests implementation of Signature
- *
- */
-public class MySignature2 extends SignatureSpi {
-
-    public static boolean runEngineInitVerify = false;
-    public static boolean runEngineInitSign = false;
-    public static boolean runEngineUpdate1 = false;
-    public static boolean runEngineUpdate2 = false;
-    public static boolean runEngineSign = false;
-    public static boolean runEngineVerify = false;
-    public static boolean runEngineSetParameter = false;
-    public static boolean runEngineGetParameter = false;
-
-    protected void engineInitVerify(PublicKey publicKey)
-            throws InvalidKeyException {
-        runEngineInitVerify = true;
-    }
-
-    protected void engineInitSign(PrivateKey privateKey)
-            throws InvalidKeyException {
-        runEngineInitSign = true;
-    }
-
-    protected void engineUpdate(byte b) throws SignatureException {
-        runEngineUpdate1 = true;
-    }
-
-    protected void engineUpdate(byte[] b, int off, int len)
-            throws SignatureException {
-        runEngineUpdate2 = true;
-    }
-
-    protected byte[] engineSign() throws SignatureException {
-        runEngineSign = true;
-        return null;
-    }
-
-    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
-        runEngineVerify = true;
-        return false;
-    }
-
-    protected void engineSetParameter(String param, Object value)
-            throws InvalidParameterException {
-        runEngineSetParameter = true;
-    }
-
-    protected Object engineGetParameter(String param)
-            throws InvalidParameterException {
-        runEngineGetParameter = true;
-        return null;
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MyTrustManagerFactorySpi.java b/support/src/test/java/org/apache/harmony/security/tests/support/MyTrustManagerFactorySpi.java
deleted file mode 100644
index db9e0f8..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MyTrustManagerFactorySpi.java
+++ /dev/null
@@ -1,71 +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.security.tests.support;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactorySpi;
-
-/**
- * Class for vertifying TrustManagerFactorySpi and TrustManagerFactory
- * functionality
- *
- */
-
-public class MyTrustManagerFactorySpi extends TrustManagerFactorySpi {
-    protected void engineInit(KeyStore ks) throws KeyStoreException {
-        if (ks == null) {
-            throw new KeyStoreException("Not supported operation for null KeyStore");
-        }
-    }
-
-    protected void engineInit(ManagerFactoryParameters spec)
-            throws InvalidAlgorithmParameterException {
-        if (spec == null) {
-            throw new InvalidAlgorithmParameterException("Null parameter");
-        }
-        if (spec instanceof Parameters) {
-            try {
-                engineInit(((Parameters)spec).getKeyStore());
-            } catch (KeyStoreException e) {
-                throw new RuntimeException(e);
-            }
-        } else {
-            throw new InvalidAlgorithmParameterException("Invalid parameter");
-        }
-    }
-
-    protected TrustManager[] engineGetTrustManagers() {
-        return null;
-    }
-
-
-    public static class Parameters implements ManagerFactoryParameters {
-        private KeyStore keyStore;
-        public Parameters (KeyStore ks) {
-            this.keyStore = ks;
-        }
-        public KeyStore getKeyStore() {
-            return keyStore;
-        }
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/SecurityChecker.java b/support/src/test/java/org/apache/harmony/security/tests/support/SecurityChecker.java
deleted file mode 100644
index 2cf846a..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/SecurityChecker.java
+++ /dev/null
@@ -1,58 +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.
- */
-
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.tests.support;
-
-import java.security.Permission;
-
-/**
- * Custom security manager
- */
-
-public class SecurityChecker extends SecurityManager {
-
-    public boolean enableAccess;
-
-    public Permission checkTarget;
-
-    public boolean checkAsserted;
-
-    public SecurityChecker(Permission target, boolean enable) {
-        checkAsserted = false;
-        checkTarget = target;
-        enableAccess = enable;
-    }
-
-    public void checkPermission(Permission p) {
-        if (checkTarget.equals(p)) {
-            checkAsserted = true;
-            if (!enableAccess) {
-                throw new SecurityException();
-            }
-        }
-    }
-
-    public SecurityChecker reset() {
-        checkAsserted = false;
-        return this;
-    }
-}
\ No newline at end of file
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/TestUtils.java b/support/src/test/java/org/apache/harmony/security/tests/support/TestUtils.java
deleted file mode 100644
index d5d8842..0000000
--- a/support/src/test/java/org/apache/harmony/security/tests/support/TestUtils.java
+++ /dev/null
@@ -1,80 +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.
- */
-
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
-package org.apache.harmony.security.tests.support;
-
-import java.util.Properties;
-
-/**
- * Test utility class
- */
-public class TestUtils {
-
-    /**
-     * No need to instantiate
-     */
-    private TestUtils() {
-    }
-
-    /**
-     * Prints byte array <code>data</code> as hex to the
-     * <code>System.out</code> in the customizable form.
-     *
-     * @param perLine how many numbers put on single line
-     * @param prefix custom output number prefix
-     * @param delimiter custom output number delimiter
-     * @param data data to be printed
-     */
-    public static void printAsHex(int perLine,
-                                  String prefix,
-                                  String delimiter,
-                                  byte[] data) {
-        for (int i=0; i<data.length; i++) {
-            String tail = Integer.toHexString(0x000000ff & data[i]);
-            if (tail.length() == 1) {
-                tail = "0" + tail;
-            }
-            System.out.print(prefix + "0x" + tail + delimiter);
-
-            if (((i+1)%perLine) == 0) {
-                System.out.println("");
-            }
-        }
-        System.out.println("");
-    }
-
-    /**
-     * Sets system property
-     *
-     * @param key - the name of the system property.
-     * @param value - the value to be set
-     */
-    public static void setSystemProperty(String key, String value) {
-        Properties properties = System.getProperties();
-        if (value == null) {
-            properties.remove(key);
-        } else {
-            properties.setProperty(key, value);
-        }
-        System.setProperties(properties);
-    }
-}
diff --git a/support/src/test/java/org/apache/harmony/xnet/tests/support/X509KeyManagerImpl.java b/support/src/test/java/org/apache/harmony/xnet/tests/support/X509KeyManagerImpl.java
deleted file mode 100644
index ade99d2..0000000
--- a/support/src/test/java/org/apache/harmony/xnet/tests/support/X509KeyManagerImpl.java
+++ /dev/null
@@ -1,225 +0,0 @@
-package org.apache.harmony.xnet.tests.support;
-
-import java.io.ByteArrayInputStream;
-import java.security.KeyStore;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.cert.Certificate;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.net.Socket;
-
-import javax.net.ssl.X509KeyManager;
-
-public class X509KeyManagerImpl implements X509KeyManager {
-
-    private String keyType;
-    private String client = "CLIENT";
-    private String server = "SERVER";
-    private KeyStore keyTest;
-    private X509Certificate[] cert = null;
-
-    // creating a certificate
-    String certificate = "-----BEGIN CERTIFICATE-----\n"
-            + "MIICZTCCAdICBQL3AAC2MA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw\n"
-            + "HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl\n"
-            + "IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NzAyMjAwMDAwMDBa\n"
-            + "Fw05ODAyMjAyMzU5NTlaMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZv\n"
-            + "cm5pYTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0\n"
-            + "ZW1zLCBJbmMuMSEwHwYDVQQLExhUZXN0IGFuZCBFdmFsdWF0aW9uIE9ubHkxGjAY\n"
-            + "BgNVBAMTEWFyZ29uLmVuZy5zdW4uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
-            + "iQKBgQCofmdY+PiUWN01FOzEewf+GaG+lFf132UpzATmYJkA4AEA/juW7jSi+LJk\n"
-            + "wJKi5GO4RyZoyimAL/5yIWDV6l1KlvxyKslr0REhMBaD/3Z3EsLTTEf5gVrQS6sT\n"
-            + "WMoSZAyzB39kFfsB6oUXNtV8+UKKxSxKbxvhQn267PeCz5VX2QIDAQABMA0GCSqG\n"
-            + "SIb3DQEBAgUAA34AXl3at6luiV/7I9MN5CXYoPJYI8Bcdc1hBagJvTMcmlqL2uOZ\n"
-            + "H9T5hNMEL9Tk6aI7yZPXcw/xI2K6pOR/FrMp0UwJmdxX7ljV6ZtUZf7pY492UqwC\n"
-            + "1777XQ9UEZyrKJvF5ntleeO0ayBqLGVKCWzWZX9YsXCpv47FNLZbupE=\n"
-            + "-----END CERTIFICATE-----\n";
-
-    ByteArrayInputStream certArray = new ByteArrayInputStream(certificate
-            .getBytes());
-
-    String certificate2 = "-----BEGIN CERTIFICATE-----\n"
-            + "MIICZzCCAdCgAwIBAgIBGzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJVUzEY\n"
-            + "MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT\n"
-            + "A1BLSTEcMBoGA1UEAxMTRG9EIFBLSSBNZWQgUm9vdCBDQTAeFw05ODA4MDMyMjAy\n"
-            + "MjlaFw0wODA4MDQyMjAyMjlaMGExCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMu\n"
-            + "IEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEMMAoGA1UECxMDUEtJMRwwGgYDVQQD\n"
-            + "ExNEb0QgUEtJIE1lZCBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
-            + "gQDbrM/J9FrJSX+zxFUbsI9Vw5QbguVBIa95rwW/0M8+sM0r5gd+DY6iubm6wnXk\n"
-            + "CSvbfQlFEDSKr4WYeeGp+d9WlDnQdtDFLdA45tCi5SHjnW+hGAmZnld0rz6wQekF\n"
-            + "5xQaa5A6wjhMlLOjbh27zyscrorMJ1O5FBOWnEHcRv6xqQIDAQABoy8wLTAdBgNV\n"
-            + "HQ4EFgQUVrmYR6m9701cHQ3r5kXyG7zsCN0wDAYDVR0TBAUwAwEB/zANBgkqhkiG\n"
-            + "9w0BAQUFAAOBgQDVX1Y0YqC7vekeZjVxtyuC8Mnxbrz6D109AX07LEIRzNYzwZ0w\n"
-            + "MTImSp9sEzWW+3FueBIU7AxGys2O7X0qmN3zgszPfSiocBuQuXIYQctJhKjF5KVc\n"
-            + "VGQRYYlt+myhl2vy6yPzEVCjiKwMEb1Spu0irCf+lFW2hsdjvmSQMtZvOw==\n"
-            + "-----END CERTIFICATE-----\n";
-
-    ByteArrayInputStream certArray2 = new ByteArrayInputStream(certificate2
-            .getBytes());
-
-    String certificate3 = "-----BEGIN CERTIFICATE-----\n"
-            + "MIIDXDCCAsWgAwIBAgIBSjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEY\n"
-            + "MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsT\n"
-            + "A1BLSTERMA8GA1UEAxMITWVkIENBLTEwHhcNOTgwODAyMTgwMjQwWhcNMDEwODAy\n"
-            + "MTgwMjQwWjB0MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50\n"
-            + "MQwwCgYDVQQLEwNEb0QxDDAKBgNVBAsTA1BLSTENMAsGA1UECxMEVVNBRjEgMB4G\n"
-            + "A1UEAxMXR3VtYnkuSm9zZXBoLjAwMDAwMDUwNDQwgZ8wDQYJKoZIhvcNAQEBBQAD\n"
-            + "gY0AMIGJAoGBALT/R7bPqs1c1YqXAg5HNpZLgW2HuAc7RCaP06cE4R44GBLw/fQc\n"
-            + "VRNLn5pgbTXsDnjiZVd8qEgYqjKFQka4/tNhaF7No2tBZB+oYL/eP0IWtP+h/W6D\n"
-            + "KR5+UvIIdgmx7k3t9jp2Q51JpHhhKEb9WN54trCO9Yu7PYU+LI85jEIBAgMBAAGj\n"
-            + "ggEaMIIBFjAWBgNVHSAEDzANMAsGCWCGSAFlAgELAzAfBgNVHSMEGDAWgBQzOhTo\n"
-            + "CWdhiGUkIOx5cELXppMe9jAdBgNVHQ4EFgQUkLBJl+ayKgzOp/wwBX9M1lSkCg4w\n"
-            + "DgYDVR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwgZ0GA1UdHwSBlTCBkjCBj6CB\n"
-            + "jKCBiYaBhmxkYXA6Ly9kcy0xLmNoYW1iLmRpc2EubWlsL2NuJTNkTWVkJTIwQ0El\n"
-            + "MmQxJTJjb3UlM2RQS0klMmNvdSUzZERvRCUyY28lM2RVLlMuJTIwR292ZXJubWVu\n"
-            + "dCUyY2MlM2RVUz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0JTNiYmluYXJ5MA0G\n"
-            + "CSqGSIb3DQEBBQUAA4GBAFjapuDHMvIdUeYRyEYdShBR1JZC20tJ3MQnyBQveddz\n"
-            + "LGFDGpIkRAQU7T/5/ne8lMexyxViC21xOlK9LdbJCbVyywvb9uEm/1je9wieQQtr\n"
-            + "kjykuB+WB6qTCIslAO/eUmgzfzIENvnH8O+fH7QTr2PdkFkiPIqBJYHvw7F3XDqy\n"
-            + "-----END CERTIFICATE-----\n";
-
-    ByteArrayInputStream certArray3 = new ByteArrayInputStream(certificate3
-            .getBytes());
-
-
-    public X509KeyManagerImpl(String name) {
-        keyType = name;
-        try {
-            CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            keyTest = KeyStore.getInstance(KeyStore.getDefaultType());
-            keyTest.load(null, null);
-            if (keyType.equals(client)) {
-                cert = new X509Certificate[2];
-                cert[0] = (X509Certificate) cf.generateCertificate(certArray);
-                cert[1] = (X509Certificate) cf.generateCertificate(certArray2);
-                //keyTest = KeyStore.getInstance(KeyStore.getDefaultType());
-                //keyTest.load(null, null);
-                keyTest.setCertificateEntry("clientAlias_01", cert[0]);
-                keyTest.setCertificateEntry("clientAlias_02", cert[0]);
-                keyTest.setCertificateEntry("clientAlias_03", cert[1]);
-            } else if (keyType.equals(server)) {
-                //CertificateFactory cf = CertificateFactory.getInstance("X.509");
-                cert = new X509Certificate[1];
-                cert[0] = (X509Certificate) cf.generateCertificate(certArray3);
-                //keyTest = KeyStore.getInstance(KeyStore.getDefaultType());
-                //keyTest.load(null, null);
-                keyTest.setCertificateEntry("serverAlias_00", cert[0]);
-            }
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }
-    }
-
-    public String[] getClientAliases(String s, Principal[] aprincipal) {
-        if (s == null || s.equals("")) {
-            return null;
-        }
-        try {
-            if (s.equals(client)) {
-                Enumeration<String> aliase = keyTest.aliases();
-                Vector vec = new Vector();
-                int i = 0;
-                while (aliase.hasMoreElements()) {
-                    vec.addElement(aliase.nextElement());
-                    i++;
-                }
-                String[] res = new String[vec.size()];
-                for (i = 0; i < vec.size(); i++) {
-                    res[i] = vec.elementAt(i).toString();
-                }
-                return res;
-            } else return null;
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }
-    }
-
-    public String chooseClientAlias(String[] as, Principal[] aprincipal, Socket socket) {
-        String alias = null;
-        if (as == null || as.length == 0) {
-            return null;
-        }
-        try {
-            if (as.length == 1 && as[0].equals(client)) {
-                if (socket == null) {
-                    alias = keyTest.getCertificateAlias(cert[0]);
-                } else {
-                    alias = keyTest.getCertificateAlias(cert[1]);
-                }
-                return alias;
-            }
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }
-        return null;
-    }
-
-    public String[] getServerAliases(String s, Principal aprincipal[]) {
-        if (s == null || s.equals("")) {
-            return null;
-        }
-        try {
-            if (s.equals(server)) {
-                Enumeration<String> aliase = keyTest.aliases();
-                Vector vec = new Vector();
-                int i = 0;
-                while (aliase.hasMoreElements()) {
-                    vec.addElement(aliase.nextElement());
-                    i++;
-                }
-                String[] res = new String[vec.size()];
-                for (i = 0; i < vec.size(); i++) {
-                    res[i] = vec.elementAt(i).toString();
-                }
-                return res;
-            } else return null;
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }
-    }
-
-    public String chooseServerAlias(String as, Principal[] aprincipal, Socket socket) {
-        String alias = null;
-        if (as == null || as.equals("")) {
-            return null;
-        }
-        try {
-            if (as.equals(server) && socket != null) {
-                return alias = keyTest.getCertificateAlias(cert[0]);
-            } else {
-                return null;
-            }
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }
-    }
-
-    public X509Certificate[] getCertificateChain(String s) {
-        /*try {
-            if (s != null && !s.equals("")) {
-                X509Certificate[] cert = (X509Certificate[]) keyTest.getCertificateChain(s);
-                return cert;
-            } else return null;
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }*/
-        return null;
-    }
-
-    public PrivateKey getPrivateKey(String s) {
-        /*try {
-            if (s != null && !s.equals("")) {
-                Certificate[] cert = keyTest.getCertificateChain(s);
-                PrivateKey pk = (PrivateKey) keyTest.getKey(s, null);
-                return pk;
-            } else return null;
-        } catch (Exception ex) {
-            throw new IllegalArgumentException(ex.getMessage());
-        }*/
-        return null;
-    }
-
-}
diff --git a/support/src/test/java/tests/http/MockResponse.java b/support/src/test/java/tests/http/MockResponse.java
deleted file mode 100644
index d3aaa9d..0000000
--- a/support/src/test/java/tests/http/MockResponse.java
+++ /dev/null
@@ -1,147 +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 tests.http;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-import static tests.http.MockWebServer.ASCII;
-
-/**
- * A scripted response to be replayed by the mock web server.
- */
-public class MockResponse implements Cloneable {
-    private static final String RFC_1123_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
-    private static final String EMPTY_BODY_HEADER = "Content-Length: 0";
-    private static final String CHUNKED_BODY_HEADER = "Transfer-encoding: chunked";
-    private static final byte[] EMPTY_BODY = new byte[0];
-
-    private String status = "HTTP/1.1 200 OK";
-    private List<String> headers = new ArrayList<String>();
-    private byte[] body = EMPTY_BODY;
-    private SocketPolicy socketPolicy = SocketPolicy.KEEP_OPEN;
-
-    public MockResponse() {
-        headers.add(EMPTY_BODY_HEADER);
-    }
-
-    @Override public MockResponse clone() {
-        try {
-            MockResponse result = (MockResponse) super.clone();
-            result.headers = new ArrayList<String>(result.headers);
-            return result;
-        } catch (CloneNotSupportedException e) {
-            throw new AssertionError();
-        }
-    }
-
-    /**
-     * Returns the HTTP response line, such as "HTTP/1.1 200 OK".
-     */
-    public String getStatus() {
-        return status;
-    }
-
-    public MockResponse setResponseCode(int code) {
-        this.status = "HTTP/1.1 " + code + " OK";
-        return this;
-    }
-
-    public MockResponse setStatus(String status) {
-        this.status = status;
-        return this;
-    }
-
-    /**
-     * Returns the HTTP headers, such as "Content-Length: 0".
-     */
-    public List<String> getHeaders() {
-        return headers;
-    }
-
-    public MockResponse clearHeaders() {
-        headers.clear();
-        return this;
-    }
-
-    public MockResponse addHeader(String header) {
-        headers.add(header);
-        return this;
-    }
-
-    /**
-     * Returns an input stream containing the raw HTTP payload.
-     */
-    public byte[] getBody() {
-        return body;
-    }
-
-    public MockResponse setBody(byte[] body) {
-        if (this.body == EMPTY_BODY) {
-            headers.remove(EMPTY_BODY_HEADER);
-        }
-        this.headers.add("Content-Length: " + body.length);
-        this.body = body;
-        return this;
-    }
-
-    public MockResponse setBody(String body) {
-        try {
-            return setBody(body.getBytes(ASCII));
-        } catch (UnsupportedEncodingException e) {
-            throw new AssertionError();
-        }
-    }
-
-    public MockResponse setChunkedBody(byte[] body, int maxChunkSize) throws IOException {
-        headers.remove(EMPTY_BODY_HEADER);
-        headers.add(CHUNKED_BODY_HEADER);
-
-        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
-        int pos = 0;
-        while (pos < body.length) {
-            int chunkSize = Math.min(body.length - pos, maxChunkSize);
-            bytesOut.write(Integer.toHexString(chunkSize).getBytes(ASCII));
-            bytesOut.write("\r\n".getBytes(ASCII));
-            bytesOut.write(body, pos, chunkSize);
-            bytesOut.write("\r\n".getBytes(ASCII));
-            pos += chunkSize;
-        }
-        bytesOut.write("0\r\n\r\n".getBytes(ASCII)); // last chunk + empty trailer + crlf
-        this.body = bytesOut.toByteArray();
-        return this;
-    }
-
-    public MockResponse setChunkedBody(String body, int maxChunkSize) throws IOException {
-        return setChunkedBody(body.getBytes(ASCII), maxChunkSize);
-    }
-
-    public SocketPolicy getSocketPolicy() {
-        return socketPolicy;
-    }
-
-    public MockResponse setSocketPolicy(SocketPolicy socketPolicy) {
-        this.socketPolicy = socketPolicy;
-        return this;
-    }
-
-    @Override public String toString() {
-        return status;
-    }
-}
diff --git a/support/src/test/java/tests/http/MockWebServer.java b/support/src/test/java/tests/http/MockWebServer.java
deleted file mode 100644
index 1b776b2..0000000
--- a/support/src/test/java/tests/http/MockWebServer.java
+++ /dev/null
@@ -1,503 +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 tests.http;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.MalformedURLException;
-import java.net.Proxy;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import static tests.http.SocketPolicy.DISCONNECT_AT_START;
-
-/**
- * A scriptable web server. Callers supply canned responses and the server
- * replays them upon request in sequence.
- *
- * @deprecated Use {@code com.google.mockwebserver.MockWebServer} instead.
- */
-@Deprecated
-public final class MockWebServer {
-
-    static final String ASCII = "US-ASCII";
-
-    private static final Logger logger = Logger.getLogger(MockWebServer.class.getName());
-    private final BlockingQueue<RecordedRequest> requestQueue
-            = new LinkedBlockingQueue<RecordedRequest>();
-    private final BlockingQueue<MockResponse> responseQueue
-            = new LinkedBlockingDeque<MockResponse>();
-    private final Set<Socket> openClientSockets
-            = Collections.newSetFromMap(new ConcurrentHashMap<Socket, Boolean>());
-    private boolean singleResponse;
-    private final AtomicInteger requestCount = new AtomicInteger();
-    private int bodyLimit = Integer.MAX_VALUE;
-    private ServerSocket serverSocket;
-    private SSLSocketFactory sslSocketFactory;
-    private ExecutorService executor;
-    private boolean tunnelProxy;
-
-    private int port = -1;
-
-    public int getPort() {
-        if (port == -1) {
-            throw new IllegalStateException("Cannot retrieve port before calling play()");
-        }
-        return port;
-    }
-
-    public String getHostName() {
-        return InetAddress.getLoopbackAddress().getHostName();
-    }
-
-    public Proxy toProxyAddress() {
-        return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(getHostName(), getPort()));
-    }
-
-    /**
-     * Returns a URL for connecting to this server.
-     *
-     * @param path the request path, such as "/".
-     */
-    public URL getUrl(String path) throws MalformedURLException, UnknownHostException {
-        return sslSocketFactory != null
-                ? new URL("https://" + getHostName() + ":" + getPort() + path)
-                : new URL("http://" + getHostName() + ":" + getPort() + path);
-    }
-
-    /**
-     * Sets the number of bytes of the POST body to keep in memory to the given
-     * limit.
-     */
-    public void setBodyLimit(int maxBodyLength) {
-        this.bodyLimit = maxBodyLength;
-    }
-
-    /**
-     * Serve requests with HTTPS rather than otherwise.
-     *
-     * @param tunnelProxy whether to expect the HTTP CONNECT method before
-     *     negotiating TLS.
-     */
-    public void useHttps(SSLSocketFactory sslSocketFactory, boolean tunnelProxy) {
-        this.sslSocketFactory = sslSocketFactory;
-        this.tunnelProxy = tunnelProxy;
-    }
-
-    /**
-     * Awaits the next HTTP request, removes it, and returns it. Callers should
-     * use this to verify the request sent was as intended.
-     */
-    public RecordedRequest takeRequest() throws InterruptedException {
-        return requestQueue.take();
-    }
-
-    /**
-     * Returns the number of HTTP requests received thus far by this server.
-     * This may exceed the number of HTTP connections when connection reuse is
-     * in practice.
-     */
-    public int getRequestCount() {
-        return requestCount.get();
-    }
-
-    public void enqueue(MockResponse response) {
-        responseQueue.add(response.clone());
-    }
-
-    /**
-     * By default, this class processes requests coming in by adding them to a
-     * queue and serves responses by removing them from another queue. This mode
-     * is appropriate for correctness testing.
-     *
-     * <p>Serving a single response causes the server to be stateless: requests
-     * are not enqueued, and responses are not dequeued. This mode is appropriate
-     * for benchmarking.
-     */
-    public void setSingleResponse(boolean singleResponse) {
-        this.singleResponse = singleResponse;
-    }
-
-    /**
-     * Equivalent to {@code play(0)}.
-     */
-    public void play() throws IOException {
-        play(0);
-    }
-
-    /**
-     * Starts the server, serves all enqueued requests, and shuts the server
-     * down.
-     *
-     * @param port the port to listen to, or 0 for any available port.
-     *     Automated tests should always use port 0 to avoid flakiness when a
-     *     specific port is unavailable.
-     */
-    public void play(int port) throws IOException {
-        executor = Executors.newCachedThreadPool();
-        serverSocket = new ServerSocket(port);
-        serverSocket.setReuseAddress(true);
-
-        this.port = serverSocket.getLocalPort();
-        executor.execute(namedRunnable("MockWebServer-accept-" + port, new Runnable() {
-            public void run() {
-                try {
-                    acceptConnections();
-                } catch (Throwable e) {
-                    logger.log(Level.WARNING, "MockWebServer connection failed", e);
-                }
-
-                /*
-                 * This gnarly block of code will release all sockets and
-                 * all thread, even if any close fails.
-                 */
-                try {
-                    serverSocket.close();
-                } catch (Throwable e) {
-                    logger.log(Level.WARNING, "MockWebServer server socket close failed", e);
-                }
-                for (Iterator<Socket> s = openClientSockets.iterator(); s.hasNext();) {
-                    try {
-                        s.next().close();
-                        s.remove();
-                    } catch (Throwable e) {
-                        logger.log(Level.WARNING, "MockWebServer socket close failed", e);
-                    }
-                }
-                try {
-                    executor.shutdown();
-                } catch (Throwable e) {
-                    logger.log(Level.WARNING, "MockWebServer executor shutdown failed", e);
-                }
-            }
-
-            private void acceptConnections() throws Exception {
-                do {
-                    Socket socket;
-                    try {
-                        socket = serverSocket.accept();
-                    } catch (SocketException ignored) {
-                        continue;
-                    }
-                    MockResponse peek = responseQueue.peek();
-                    if (peek != null && peek.getSocketPolicy() == DISCONNECT_AT_START) {
-                        responseQueue.take();
-                        socket.close();
-                    } else {
-                        openClientSockets.add(socket);
-                        serveConnection(socket);
-                    }
-                } while (!responseQueue.isEmpty());
-            }
-        }));
-    }
-
-    public void shutdown() throws IOException {
-        if (serverSocket != null) {
-            serverSocket.close(); // should cause acceptConnections() to break out
-        }
-    }
-
-    private void serveConnection(final Socket raw) {
-        String name = "MockWebServer-" + raw.getRemoteSocketAddress();
-        executor.execute(namedRunnable(name, new Runnable() {
-            int sequenceNumber = 0;
-
-            public void run() {
-                try {
-                    processConnection();
-                } catch (Exception e) {
-                    logger.log(Level.WARNING, "MockWebServer connection failed", e);
-                }
-            }
-
-            public void processConnection() throws Exception {
-                Socket socket;
-                if (sslSocketFactory != null) {
-                    if (tunnelProxy) {
-                        createTunnel();
-                    }
-                    socket = sslSocketFactory.createSocket(
-                            raw, raw.getInetAddress().getHostAddress(), raw.getPort(), true);
-                    ((SSLSocket) socket).setUseClientMode(false);
-                    openClientSockets.add(socket);
-                    openClientSockets.remove(raw);
-                } else {
-                    socket = raw;
-                }
-
-                InputStream in = new BufferedInputStream(socket.getInputStream());
-                OutputStream out = new BufferedOutputStream(socket.getOutputStream());
-
-                while (!responseQueue.isEmpty() && processOneRequest(in, out, socket)) {}
-
-                if (sequenceNumber == 0) {
-                    logger.warning("MockWebServer connection didn't make a request");
-                }
-
-                in.close();
-                out.close();
-                socket.close();
-                if (responseQueue.isEmpty()) {
-                    shutdown();
-                }
-                openClientSockets.remove(socket);
-            }
-
-            /**
-             * Respond to CONNECT requests until a SWITCH_TO_SSL_AT_END response
-             * is dispatched.
-             */
-            private void createTunnel() throws IOException, InterruptedException {
-                while (true) {
-                    MockResponse connect = responseQueue.peek();
-                    if (!processOneRequest(raw.getInputStream(), raw.getOutputStream(), raw)) {
-                        throw new IllegalStateException("Tunnel without any CONNECT!");
-                    }
-                    if (connect.getSocketPolicy() == SocketPolicy.UPGRADE_TO_SSL_AT_END) {
-                        return;
-                    }
-                }
-            }
-
-            /**
-             * Reads a request and writes its response. Returns true if a request
-             * was processed.
-             */
-            private boolean processOneRequest(InputStream in, OutputStream out, Socket socket)
-                    throws IOException, InterruptedException {
-                RecordedRequest request = readRequest(in, sequenceNumber);
-                if (request == null) {
-                    return false;
-                }
-                MockResponse response = dispatch(request);
-                writeResponse(out, response);
-                if (response.getSocketPolicy() == SocketPolicy.DISCONNECT_AT_END) {
-                    in.close();
-                    out.close();
-                } else if (response.getSocketPolicy() == SocketPolicy.SHUTDOWN_INPUT_AT_END) {
-                    socket.shutdownInput();
-                } else if (response.getSocketPolicy() == SocketPolicy.SHUTDOWN_OUTPUT_AT_END) {
-                    socket.shutdownOutput();
-                }
-                sequenceNumber++;
-                return true;
-            }
-        }));
-    }
-
-    /**
-     * @param sequenceNumber the index of this request on this connection.
-     */
-    private RecordedRequest readRequest(InputStream in, int sequenceNumber) throws IOException {
-        String request;
-        try {
-            request = readAsciiUntilCrlf(in);
-        } catch (IOException streamIsClosed) {
-            return null; // no request because we closed the stream
-        }
-        if (request.isEmpty()) {
-            return null; // no request because the stream is exhausted
-        }
-
-        List<String> headers = new ArrayList<String>();
-        int contentLength = -1;
-        boolean chunked = false;
-        String header;
-        while (!(header = readAsciiUntilCrlf(in)).isEmpty()) {
-            headers.add(header);
-            String lowercaseHeader = header.toLowerCase(Locale.ROOT);
-            if (contentLength == -1 && lowercaseHeader.startsWith("content-length:")) {
-                contentLength = Integer.parseInt(header.substring(15).trim());
-            }
-            if (lowercaseHeader.startsWith("transfer-encoding:") &&
-                    lowercaseHeader.substring(18).trim().equals("chunked")) {
-                chunked = true;
-            }
-        }
-
-        boolean hasBody = false;
-        TruncatingOutputStream requestBody = new TruncatingOutputStream();
-        List<Integer> chunkSizes = new ArrayList<Integer>();
-        if (contentLength != -1) {
-            hasBody = true;
-            transfer(contentLength, in, requestBody);
-        } else if (chunked) {
-            hasBody = true;
-            while (true) {
-                int chunkSize = Integer.parseInt(readAsciiUntilCrlf(in).trim(), 16);
-                if (chunkSize == 0) {
-                    readEmptyLine(in);
-                    break;
-                }
-                chunkSizes.add(chunkSize);
-                transfer(chunkSize, in, requestBody);
-                readEmptyLine(in);
-            }
-        }
-
-        if (request.startsWith("OPTIONS ") || request.startsWith("GET ")
-                || request.startsWith("HEAD ") || request.startsWith("DELETE ")
-                || request .startsWith("TRACE ") || request.startsWith("CONNECT ")) {
-            if (hasBody) {
-                throw new IllegalArgumentException("Request must not have a body: " + request);
-            }
-        } else if (request.startsWith("POST ") || request.startsWith("PUT ")) {
-            if (!hasBody) {
-                throw new IllegalArgumentException("Request must have a body: " + request);
-            }
-        } else {
-            throw new UnsupportedOperationException("Unexpected method: " + request);
-        }
-
-        return new RecordedRequest(request, headers, chunkSizes,
-                requestBody.numBytesReceived, requestBody.toByteArray(), sequenceNumber);
-    }
-
-    /**
-     * Returns a response to satisfy {@code request}.
-     */
-    private MockResponse dispatch(RecordedRequest request) throws InterruptedException {
-        if (responseQueue.isEmpty()) {
-            throw new IllegalStateException("Unexpected request: " + request);
-        }
-
-        // to permit interactive/browser testing, ignore requests for favicons
-        if (request.getRequestLine().equals("GET /favicon.ico HTTP/1.1")) {
-            System.out.println("served " + request.getRequestLine());
-            return new MockResponse()
-                        .setResponseCode(HttpURLConnection.HTTP_NOT_FOUND);
-        }
-
-        if (singleResponse) {
-            return responseQueue.peek();
-        } else {
-            requestCount.incrementAndGet();
-            requestQueue.add(request);
-            return responseQueue.take();
-        }
-    }
-
-    private void writeResponse(OutputStream out, MockResponse response) throws IOException {
-        out.write((response.getStatus() + "\r\n").getBytes(ASCII));
-        for (String header : response.getHeaders()) {
-            out.write((header + "\r\n").getBytes(ASCII));
-        }
-        out.write(("\r\n").getBytes(ASCII));
-        out.write(response.getBody());
-        out.flush();
-    }
-
-    /**
-     * Transfer bytes from {@code in} to {@code out} until either {@code length}
-     * bytes have been transferred or {@code in} is exhausted.
-     */
-    private void transfer(int length, InputStream in, OutputStream out) throws IOException {
-        byte[] buffer = new byte[1024];
-        while (length > 0) {
-            int count = in.read(buffer, 0, Math.min(buffer.length, length));
-            if (count == -1) {
-                return;
-            }
-            out.write(buffer, 0, count);
-            length -= count;
-        }
-    }
-
-    /**
-     * Returns the text from {@code in} until the next "\r\n", or null if
-     * {@code in} is exhausted.
-     */
-    private String readAsciiUntilCrlf(InputStream in) throws IOException {
-        StringBuilder builder = new StringBuilder();
-        while (true) {
-            int c = in.read();
-            if (c == '\n' && builder.length() > 0 && builder.charAt(builder.length() - 1) == '\r') {
-                builder.deleteCharAt(builder.length() - 1);
-                return builder.toString();
-            } else if (c == -1) {
-                return builder.toString();
-            } else {
-                builder.append((char) c);
-            }
-        }
-    }
-
-    private void readEmptyLine(InputStream in) throws IOException {
-        String line = readAsciiUntilCrlf(in);
-        if (!line.isEmpty()) {
-            throw new IllegalStateException("Expected empty but was: " + line);
-        }
-    }
-
-    /**
-     * An output stream that drops data after bodyLimit bytes.
-     */
-    private class TruncatingOutputStream extends ByteArrayOutputStream {
-        private int numBytesReceived = 0;
-        @Override public void write(byte[] buffer, int offset, int len) {
-            numBytesReceived += len;
-            super.write(buffer, offset, Math.min(len, bodyLimit - count));
-        }
-        @Override public void write(int oneByte) {
-            numBytesReceived++;
-            if (count < bodyLimit) {
-                super.write(oneByte);
-            }
-        }
-    }
-
-    private static Runnable namedRunnable(final String name, final Runnable runnable) {
-        return new Runnable() {
-            public void run() {
-                String originalName = Thread.currentThread().getName();
-                Thread.currentThread().setName(name);
-                try {
-                    runnable.run();
-                } finally {
-                    Thread.currentThread().setName(originalName);
-                }
-            }
-        };
-    }
-}
diff --git a/support/src/test/java/tests/http/RecordedRequest.java b/support/src/test/java/tests/http/RecordedRequest.java
deleted file mode 100644
index c805006..0000000
--- a/support/src/test/java/tests/http/RecordedRequest.java
+++ /dev/null
@@ -1,85 +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 tests.http;
-
-import java.util.List;
-
-/**
- * An HTTP request that came into the mock web server.
- */
-public final class RecordedRequest {
-    private final String requestLine;
-    private final List<String> headers;
-    private final List<Integer> chunkSizes;
-    private final int bodySize;
-    private final byte[] body;
-    private final int sequenceNumber;
-
-    RecordedRequest(String requestLine, List<String> headers, List<Integer> chunkSizes,
-            int bodySize, byte[] body, int sequenceNumber) {
-        this.requestLine = requestLine;
-        this.headers = headers;
-        this.chunkSizes = chunkSizes;
-        this.bodySize = bodySize;
-        this.body = body;
-        this.sequenceNumber = sequenceNumber;
-    }
-
-    public String getRequestLine() {
-        return requestLine;
-    }
-
-    public List<String> getHeaders() {
-        return headers;
-    }
-
-    /**
-     * Returns the sizes of the chunks of this request's body, or an empty list
-     * if the request's body was empty or unchunked.
-     */
-    public List<Integer> getChunkSizes() {
-        return chunkSizes;
-    }
-
-    /**
-     * Returns the total size of the body of this POST request (before
-     * truncation).
-     */
-    public int getBodySize() {
-        return bodySize;
-    }
-
-    /**
-     * Returns the body of this POST request. This may be truncated.
-     */
-    public byte[] getBody() {
-        return body;
-    }
-
-    /**
-     * Returns the index of this request on its HTTP connection. Since a single
-     * HTTP connection may serve multiple requests, each request is assigned its
-     * own sequence number.
-     */
-    public int getSequenceNumber() {
-        return sequenceNumber;
-    }
-
-    @Override public String toString() {
-        return requestLine;
-    }
-}
diff --git a/support/src/test/java/tests/http/SocketPolicy.java b/support/src/test/java/tests/http/SocketPolicy.java
deleted file mode 100644
index 820b400..0000000
--- a/support/src/test/java/tests/http/SocketPolicy.java
+++ /dev/null
@@ -1,64 +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 tests.http;
-
-/**
- * What should be done with the incoming socket.
- */
-public enum SocketPolicy {
-
-    /**
-     * Keep the socket open after the response. This is the default HTTP/1.1
-     * behavior.
-     */
-    KEEP_OPEN,
-
-    /**
-     * Close the socket after the response. This is the default HTTP/1.0
-     * behavior.
-     */
-    DISCONNECT_AT_END,
-
-    /**
-     * Wrap the socket with SSL at the completion of this request/response
-     * pair. Used for CONNECT messages to tunnel SSL over an HTTP proxy.
-     */
-    UPGRADE_TO_SSL_AT_END,
-
-    /**
-     * Request immediate close of connection without even reading the
-     * request.
-     *
-     * <p>Use to simulate the real life case of losing connection
-     * because of bugger SSL server close connection when it seems
-     * something like a compression method or TLS extension it doesn't
-     * understand, instead of simply ignoring it like it should.
-     */
-    DISCONNECT_AT_START,
-
-    /**
-     * Shutdown the socket input after sending the response. For testing bad
-     * behavior.
-     */
-    SHUTDOWN_INPUT_AT_END,
-
-    /**
-     * Shutdown the socket output after sending the response. For testing bad
-     * behavior.
-     */
-    SHUTDOWN_OUTPUT_AT_END
-}
diff --git a/support/src/test/java/tests/net/DelegatingSSLSocketFactory.java b/support/src/test/java/tests/net/DelegatingSSLSocketFactory.java
deleted file mode 100644
index 5cbde84..0000000
--- a/support/src/test/java/tests/net/DelegatingSSLSocketFactory.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 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 tests.net;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * {@link SSLSocketFactory} which delegates all invocations to the provided delegate
- * {@code SSLSocketFactory}.
- */
-public class DelegatingSSLSocketFactory extends SSLSocketFactory {
-
-  private final SSLSocketFactory mDelegate;
-
-  public DelegatingSSLSocketFactory(SSLSocketFactory delegate) {
-    this.mDelegate = delegate;
-  }
-
-  /**
-   * Invoked after obtaining a socket from the delegate and before returning it to the caller.
-   *
-   * <p>The default implementation does nothing.
-   */
-  protected SSLSocket configureSocket(SSLSocket socket) throws IOException {
-    return socket;
-  }
-
-  @Override
-  public String[] getDefaultCipherSuites() {
-    return mDelegate.getDefaultCipherSuites();
-  }
-
-  @Override
-  public String[] getSupportedCipherSuites() {
-    return mDelegate.getSupportedCipherSuites();
-  }
-
-  @Override
-  public Socket createSocket() throws IOException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket();
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(Socket s, String host, int port, boolean autoClose)
-      throws IOException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket(s, host, port, autoClose);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
-      throws IOException, UnknownHostException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port, localHost, localPort);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(InetAddress host, int port) throws IOException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
-      int localPort) throws IOException {
-    SSLSocket socket = (SSLSocket) mDelegate.createSocket(address, port, localAddress, localPort);
-    return configureSocket(socket);
-  }
-}
diff --git a/support/src/test/java/tests/net/DelegatingSocketFactory.java b/support/src/test/java/tests/net/DelegatingSocketFactory.java
deleted file mode 100644
index b544773..0000000
--- a/support/src/test/java/tests/net/DelegatingSocketFactory.java
+++ /dev/null
@@ -1,77 +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 tests.net;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import javax.net.SocketFactory;
-
-/**
- * {@link SocketFactory} which delegates all invocations to the provided delegate
- * {@code SocketFactory}.
- */
-public class DelegatingSocketFactory extends SocketFactory {
-
-  private final SocketFactory mDelegate;
-
-  public DelegatingSocketFactory(SocketFactory delegate) {
-    this.mDelegate = delegate;
-  }
-
-  /**
-   * Invoked after obtaining a socket from the delegate and before returning it to the caller.
-   *
-   * <p>The default implementation does nothing.
-   */
-  protected Socket configureSocket(Socket socket) throws IOException {
-    return socket;
-  }
-
-  @Override
-  public Socket createSocket() throws IOException {
-    Socket socket = mDelegate.createSocket();
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
-    Socket socket = mDelegate.createSocket(host, port);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
-      throws IOException, UnknownHostException {
-    Socket socket = mDelegate.createSocket(host, port, localHost, localPort);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(InetAddress host, int port) throws IOException {
-    Socket socket = mDelegate.createSocket(host, port);
-    return configureSocket(socket);
-  }
-
-  @Override
-  public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
-      int localPort) throws IOException {
-    Socket socket = mDelegate.createSocket(address, port, localAddress, localPort);
-    return configureSocket(socket);
-  }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParameterAsymmetricHelper.java b/support/src/test/java/tests/security/AlgorithmParameterAsymmetricHelper.java
deleted file mode 100644
index f92ba24..0000000
--- a/support/src/test/java/tests/security/AlgorithmParameterAsymmetricHelper.java
+++ /dev/null
@@ -1,55 +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 tests.security;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import junit.framework.Assert;
-
-public class AlgorithmParameterAsymmetricHelper extends TestHelper<AlgorithmParameters> {
-
-    private static final String plainData = "some data to encrypt and decrypt";
-    private final String algorithmName;
-
-    public AlgorithmParameterAsymmetricHelper(String algorithmName) {
-        this.algorithmName = algorithmName;
-    }
-
-    @Override
-    public void test(AlgorithmParameters parameters) throws Exception {
-        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithmName);
-        generator.initialize(1024);
-        KeyPair keyPair = generator.generateKeyPair();
-
-        Cipher cipher = Cipher.getInstance(algorithmName);
-        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), parameters);
-        byte[] bs = cipher.doFinal(plainData.getBytes());
-
-        cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate(), parameters);
-        byte[] decrypted = cipher.doFinal(bs);
-        Assert.assertTrue(Arrays.equals(plainData.getBytes(), decrypted));
-    }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParameterGeneratorTest.java b/support/src/test/java/tests/security/AlgorithmParameterGeneratorTest.java
deleted file mode 100644
index 1578c0a..0000000
--- a/support/src/test/java/tests/security/AlgorithmParameterGeneratorTest.java
+++ /dev/null
@@ -1,41 +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 tests.security;
-
-import java.security.AlgorithmParameterGenerator;
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import junit.framework.TestCase;
-
-public abstract class AlgorithmParameterGeneratorTest extends TestCase {
-
-    private final String algorithmName;
-    private final TestHelper<AlgorithmParameters> helper;
-
-    protected AlgorithmParameterGeneratorTest(String algorithmName, TestHelper<AlgorithmParameters> helper) {
-        this.algorithmName = algorithmName;
-        this.helper = helper;
-    }
-
-    public void testAlgorithmParameterGenerator() throws Exception {
-        AlgorithmParameterGenerator generator = AlgorithmParameterGenerator.getInstance(algorithmName);
-        generator.init(1024);
-
-        AlgorithmParameters parameters = generator.generateParameters();
-        assertNotNull("generated parameters are null", parameters);
-        helper.test(parameters);
-    }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParameterKeyAgreementHelper.java b/support/src/test/java/tests/security/AlgorithmParameterKeyAgreementHelper.java
deleted file mode 100644
index 92b9ff1..0000000
--- a/support/src/test/java/tests/security/AlgorithmParameterKeyAgreementHelper.java
+++ /dev/null
@@ -1,46 +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 tests.security;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import javax.crypto.KeyAgreement;
-import junit.framework.Assert;
-
-public class AlgorithmParameterKeyAgreementHelper extends TestHelper<AlgorithmParameters> {
-
-    private final String algorithmName;
-
-    public AlgorithmParameterKeyAgreementHelper(String algorithmName) {
-        this.algorithmName = algorithmName;
-    }
-
-    @Override
-    public void test(AlgorithmParameters parameters) throws Exception {
-        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithmName);
-        generator.initialize(1024);
-
-        KeyPair keyPair = generator.generateKeyPair();
-        KeyAgreement keyAgreement = KeyAgreement.getInstance(algorithmName);
-        keyAgreement.init(keyPair.getPrivate());
-        keyAgreement.doPhase(keyPair.getPublic(), true);
-        Assert.assertNotNull("generated secret is null", keyAgreement.generateSecret());
-    }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParameterSignatureHelper.java b/support/src/test/java/tests/security/AlgorithmParameterSignatureHelper.java
deleted file mode 100644
index c4d5e4b..0000000
--- a/support/src/test/java/tests/security/AlgorithmParameterSignatureHelper.java
+++ /dev/null
@@ -1,60 +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 tests.security;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import junit.framework.Assert;
-
-public class AlgorithmParameterSignatureHelper<T extends AlgorithmParameterSpec>
-        extends TestHelper<AlgorithmParameters> {
-
-    private final String algorithmName;
-    private final String plainData = "some data do sign and verify";
-    private final Class<T> parameterSpecClass;
-
-    public AlgorithmParameterSignatureHelper(String algorithmName, Class<T> parameterSpecCla1ss) {
-        this.algorithmName = algorithmName;
-        this.parameterSpecClass = parameterSpecCla1ss;
-    }
-
-    @Override
-    public void test(AlgorithmParameters parameters) throws Exception {
-        Signature signature = Signature.getInstance(algorithmName);
-        T parameterSpec = parameters.getParameterSpec(parameterSpecClass);
-        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithmName);
-
-        generator.initialize(parameterSpec);
-        KeyPair keyPair = generator.genKeyPair();
-
-        signature.initSign(keyPair.getPrivate());
-        signature.update(plainData.getBytes());
-        byte[] signed = signature.sign();
-
-        signature.initVerify(keyPair.getPublic());
-        signature.update(plainData.getBytes());
-        Assert.assertTrue("signature should verify", signature.verify(signed));
-    }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParameterSymmetricHelper.java b/support/src/test/java/tests/security/AlgorithmParameterSymmetricHelper.java
deleted file mode 100644
index 09fabd1..0000000
--- a/support/src/test/java/tests/security/AlgorithmParameterSymmetricHelper.java
+++ /dev/null
@@ -1,70 +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 tests.security;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import junit.framework.Assert;
-
-public class AlgorithmParameterSymmetricHelper extends TestHelper<AlgorithmParameters> {
-
-    private static final String plainData = "some data to encrypt and decrypt";
-    private final String algorithmName;
-    private final int keySize;
-    private String blockmode;
-
-    public AlgorithmParameterSymmetricHelper(String algorithmName, int keySize) {
-        this.algorithmName = algorithmName;
-        this.keySize = keySize;
-    }
-
-    public AlgorithmParameterSymmetricHelper(String algorithmName, String blockmode, int keySize) {
-        this(algorithmName, keySize);
-        this.blockmode = blockmode;
-    }
-
-    @Override
-    public void test(AlgorithmParameters parameters) throws Exception {
-        KeyGenerator generator = KeyGenerator.getInstance(algorithmName);
-        generator.init(keySize);
-
-        Key key = generator.generateKey();
-        String transformation = algorithmName;
-        if (blockmode != null)
-        {
-            transformation += "/" + blockmode;
-        }
-
-        Cipher cipher = Cipher.getInstance(transformation);
-        cipher.init(Cipher.ENCRYPT_MODE, key, parameters);
-        byte[] bs = cipher.doFinal(plainData.getBytes());
-
-        cipher.init(Cipher.DECRYPT_MODE, key, parameters);
-        byte[] decrypted = cipher.doFinal(bs);
-
-        Assert.assertTrue(Arrays.equals(plainData.getBytes(), decrypted));
-    }
-}
diff --git a/support/src/test/java/tests/security/AlgorithmParametersTest.java b/support/src/test/java/tests/security/AlgorithmParametersTest.java
deleted file mode 100644
index fc85642..0000000
--- a/support/src/test/java/tests/security/AlgorithmParametersTest.java
+++ /dev/null
@@ -1,42 +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 tests.security;
-
-import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import junit.framework.TestCase;
-
-public abstract class AlgorithmParametersTest extends TestCase {
-
-    private final String algorithmName;
-    private final TestHelper<AlgorithmParameters> helper;
-    private final AlgorithmParameterSpec parameterData;
-
-    public AlgorithmParametersTest(String algorithmName,
-            TestHelper<AlgorithmParameters> helper, AlgorithmParameterSpec parameterData) {
-        this.algorithmName = algorithmName;
-        this.helper = helper;
-        this.parameterData = parameterData;
-    }
-
-    public void testAlgorithmParameters() throws Exception {
-        AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(algorithmName);
-        algorithmParameters.init(parameterData);
-        helper.test(algorithmParameters);
-    }
-}
diff --git a/support/src/test/java/tests/security/CipherAsymmetricCryptHelper.java b/support/src/test/java/tests/security/CipherAsymmetricCryptHelper.java
deleted file mode 100644
index 5742d1c..0000000
--- a/support/src/test/java/tests/security/CipherAsymmetricCryptHelper.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 tests.security;
-
-import java.security.KeyPair;
-import javax.crypto.Cipher;
-
-public class CipherAsymmetricCryptHelper extends CipherHelper<KeyPair> {
-
-    private static final String plainData = "some data to encrypt and decrypt test";
-
-    public CipherAsymmetricCryptHelper(String algorithmName) {
-        super(algorithmName, plainData, Cipher.ENCRYPT_MODE,
-                Cipher.DECRYPT_MODE);
-    }
-
-    public void test(KeyPair keyPair) throws Exception {
-        test(keyPair.getPrivate(), keyPair.getPublic());
-    }
-}
diff --git a/support/src/test/java/tests/security/CipherHelper.java b/support/src/test/java/tests/security/CipherHelper.java
deleted file mode 100644
index e1d64bf..0000000
--- a/support/src/test/java/tests/security/CipherHelper.java
+++ /dev/null
@@ -1,53 +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 tests.security;
-
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import junit.framework.Assert;
-
-public abstract class CipherHelper<T> extends TestHelper<T> {
-
-    private final String algorithmName;
-    private final String plainData;
-    private final int mode1;
-    private final int mode2;
-
-    public CipherHelper(String algorithmName, String plainData, int mode1, int mode2) {
-        this.algorithmName = algorithmName;
-        this.plainData = plainData;
-        this.mode1 = mode1;
-        this.mode2 = mode2;
-    }
-
-    public void test(Key encryptKey, Key decryptKey) throws Exception {
-        Cipher cipher = Cipher.getInstance(algorithmName);
-        cipher.init(mode1, encryptKey);
-        byte[] encrypted = cipher.doFinal(plainData.getBytes());
-
-        cipher.init(mode2, decryptKey);
-        byte[] decrypted = cipher.doFinal(encrypted);
-        String decryptedString = new String(decrypted);
-
-        Assert.assertEquals("transformed data does not match", plainData, decryptedString);
-    }
-}
diff --git a/support/src/test/java/tests/security/CipherSymmetricCryptHelper.java b/support/src/test/java/tests/security/CipherSymmetricCryptHelper.java
deleted file mode 100644
index 42d644c..0000000
--- a/support/src/test/java/tests/security/CipherSymmetricCryptHelper.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 tests.security;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-
-public class CipherSymmetricCryptHelper extends CipherHelper<SecretKey/*, U*/> {
-
-    private static final String plainData = "some data to encrypt and decrypt test";
-
-    public CipherSymmetricCryptHelper(String algorithmName) {
-        super(algorithmName, plainData, Cipher.ENCRYPT_MODE,
-                Cipher.DECRYPT_MODE);
-    }
-
-    public void test(SecretKey key) throws Exception {
-        test(key, key);
-    }
-}
diff --git a/support/src/test/java/tests/security/DefaultKeys.java b/support/src/test/java/tests/security/DefaultKeys.java
deleted file mode 100644
index e83efc6..0000000
--- a/support/src/test/java/tests/security/DefaultKeys.java
+++ /dev/null
@@ -1,206 +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 tests.security;
-
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.HashMap;
-
-public class DefaultKeys {
-    private static final byte[] RSA_private = new byte[] {
-        (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x75, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D,
-        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, (byte) 0x02, (byte) 0x5F, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5B, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02,
-        (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x99, (byte) 0xA5, (byte) 0x96, (byte) 0x72, (byte) 0xAE, (byte) 0xBB, (byte) 0x59, (byte) 0x36, (byte) 0xA8, (byte) 0x12, (byte) 0x17, (byte) 0x05, (byte) 0x4C, (byte) 0x63,
-        (byte) 0x9E, (byte) 0xB8, (byte) 0x85, (byte) 0xD4, (byte) 0x2D, (byte) 0x71, (byte) 0xD7, (byte) 0x29, (byte) 0xB9, (byte) 0x05, (byte) 0x0F, (byte) 0xB4, (byte) 0x57, (byte) 0xFB, (byte) 0xD3, (byte) 0x95, (byte) 0x5C,
-        (byte) 0x21, (byte) 0xEC, (byte) 0xB5, (byte) 0xEB, (byte) 0x67, (byte) 0xA2, (byte) 0x4F, (byte) 0xC1, (byte) 0x93, (byte) 0xEF, (byte) 0x96, (byte) 0x41, (byte) 0x05, (byte) 0x3D, (byte) 0xC5, (byte) 0x3E, (byte) 0x04,
-        (byte) 0x4D, (byte) 0xC6, (byte) 0xCF, (byte) 0x32, (byte) 0x7C, (byte) 0x1F, (byte) 0x66, (byte) 0xA3, (byte) 0xC5, (byte) 0x27, (byte) 0x79, (byte) 0xEC, (byte) 0x2E, (byte) 0x67, (byte) 0xFA, (byte) 0x19, (byte) 0x5B,
-        (byte) 0xE3, (byte) 0xB1, (byte) 0x69, (byte) 0xDA, (byte) 0x63, (byte) 0xBC, (byte) 0xDA, (byte) 0xD3, (byte) 0xBB, (byte) 0xAD, (byte) 0x8C, (byte) 0x38, (byte) 0x7B, (byte) 0x4A, (byte) 0x9C, (byte) 0xD4, (byte) 0x4D,
-        (byte) 0xD2, (byte) 0x33, (byte) 0xB7, (byte) 0x4E, (byte) 0x04, (byte) 0xB6, (byte) 0xDF, (byte) 0x62, (byte) 0x55, (byte) 0x48, (byte) 0x5C, (byte) 0x94, (byte) 0x02, (byte) 0xF7, (byte) 0x84, (byte) 0xE6, (byte) 0x9B,
-        (byte) 0x57, (byte) 0xFF, (byte) 0x17, (byte) 0x2A, (byte) 0xA1, (byte) 0x74, (byte) 0x8D, (byte) 0x07, (byte) 0xD8, (byte) 0xCE, (byte) 0xF7, (byte) 0x0B, (byte) 0x59, (byte) 0xFB, (byte) 0x13, (byte) 0x6E, (byte) 0xF1,
-        (byte) 0xC3, (byte) 0xAB, (byte) 0x3E, (byte) 0x72, (byte) 0x1B, (byte) 0x62, (byte) 0x09, (byte) 0xE8, (byte) 0xD8, (byte) 0x41, (byte) 0x69, (byte) 0xE1, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01,
-        (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x57, (byte) 0xD6, (byte) 0x1C, (byte) 0x2E, (byte) 0x2F, (byte) 0xCA, (byte) 0x16, (byte) 0xF4, (byte) 0x72, (byte) 0x1C, (byte) 0xF5, (byte) 0x60, (byte) 0x28, (byte) 0x0D,
-        (byte) 0x83, (byte) 0x7D, (byte) 0x85, (byte) 0xB4, (byte) 0x88, (byte) 0xCE, (byte) 0x5D, (byte) 0xED, (byte) 0x12, (byte) 0x42, (byte) 0xDC, (byte) 0x79, (byte) 0x83, (byte) 0x1B, (byte) 0x0A, (byte) 0x18, (byte) 0x86,
-        (byte) 0xF5, (byte) 0x35, (byte) 0xF7, (byte) 0xC2, (byte) 0x3E, (byte) 0x1A, (byte) 0xC2, (byte) 0x71, (byte) 0xAD, (byte) 0xFA, (byte) 0xF7, (byte) 0xF0, (byte) 0xEF, (byte) 0xE8, (byte) 0x22, (byte) 0x4C, (byte) 0x93,
-        (byte) 0xF5, (byte) 0x4A, (byte) 0xC4, (byte) 0xC4, (byte) 0xDD, (byte) 0xC4, (byte) 0xAD, (byte) 0xCE, (byte) 0xCE, (byte) 0x35, (byte) 0x05, (byte) 0x34, (byte) 0x8A, (byte) 0x4B, (byte) 0x12, (byte) 0xE4, (byte) 0x69,
-        (byte) 0xE6, (byte) 0xDA, (byte) 0x07, (byte) 0x1A, (byte) 0x77, (byte) 0x5C, (byte) 0xA7, (byte) 0x21, (byte) 0x41, (byte) 0x89, (byte) 0x8C, (byte) 0x95, (byte) 0x6A, (byte) 0x5D, (byte) 0x9C, (byte) 0x3C, (byte) 0xAE,
-        (byte) 0xC3, (byte) 0xE4, (byte) 0x64, (byte) 0x54, (byte) 0xDA, (byte) 0xFB, (byte) 0xBA, (byte) 0xA6, (byte) 0xE5, (byte) 0x8A, (byte) 0x7F, (byte) 0xFA, (byte) 0x1A, (byte) 0x3F, (byte) 0x9B, (byte) 0xAB, (byte) 0xDA,
-        (byte) 0x3D, (byte) 0x3B, (byte) 0x43, (byte) 0xF0, (byte) 0x0C, (byte) 0x06, (byte) 0x57, (byte) 0x43, (byte) 0x45, (byte) 0xEE, (byte) 0x8C, (byte) 0x27, (byte) 0x05, (byte) 0xAF, (byte) 0xCD, (byte) 0x5A, (byte) 0x47,
-        (byte) 0xB9, (byte) 0xEA, (byte) 0xD9, (byte) 0xAA, (byte) 0x66, (byte) 0xDB, (byte) 0xE3, (byte) 0xDC, (byte) 0x54, (byte) 0x47, (byte) 0x60, (byte) 0x01, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xED, (byte) 0xE9,
-        (byte) 0xBD, (byte) 0xD5, (byte) 0x02, (byte) 0x6D, (byte) 0x44, (byte) 0x0E, (byte) 0x3F, (byte) 0x74, (byte) 0x0C, (byte) 0x45, (byte) 0x54, (byte) 0x88, (byte) 0xFE, (byte) 0x5C, (byte) 0xFC, (byte) 0xF2, (byte) 0x31,
-        (byte) 0x7B, (byte) 0xAF, (byte) 0x15, (byte) 0x77, (byte) 0x7A, (byte) 0xDC, (byte) 0xC6, (byte) 0x9E, (byte) 0x7E, (byte) 0xC1, (byte) 0xCA, (byte) 0x84, (byte) 0xC7, (byte) 0x4B, (byte) 0xC4, (byte) 0x41, (byte) 0xE1,
-        (byte) 0x85, (byte) 0xE4, (byte) 0x5A, (byte) 0xA7, (byte) 0x3D, (byte) 0x54, (byte) 0x87, (byte) 0x0D, (byte) 0x7A, (byte) 0xC5, (byte) 0x47, (byte) 0x5C, (byte) 0xF2, (byte) 0xAD, (byte) 0x14, (byte) 0x4D, (byte) 0x63,
-        (byte) 0xB0, (byte) 0xDC, (byte) 0x34, (byte) 0xB5, (byte) 0xDA, (byte) 0x17, (byte) 0x0D, (byte) 0x4E, (byte) 0x2B, (byte) 0x9E, (byte) 0x81, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xA5, (byte) 0x53, (byte) 0xDB,
-        (byte) 0xD8, (byte) 0x28, (byte) 0x57, (byte) 0x65, (byte) 0x2B, (byte) 0xFA, (byte) 0xF2, (byte) 0x21, (byte) 0xB8, (byte) 0x60, (byte) 0xAE, (byte) 0x43, (byte) 0x4B, (byte) 0x51, (byte) 0x85, (byte) 0xCB, (byte) 0xDA,
-        (byte) 0x89, (byte) 0x5A, (byte) 0x7D, (byte) 0x05, (byte) 0xDA, (byte) 0xFC, (byte) 0xAF, (byte) 0x46, (byte) 0x86, (byte) 0xBC, (byte) 0x3F, (byte) 0xD1, (byte) 0xEA, (byte) 0xA4, (byte) 0x56, (byte) 0xA3, (byte) 0xE6,
-        (byte) 0xD4, (byte) 0xA2, (byte) 0x08, (byte) 0x93, (byte) 0x63, (byte) 0x21, (byte) 0x0E, (byte) 0xC5, (byte) 0x3C, (byte) 0x97, (byte) 0x7E, (byte) 0x71, (byte) 0x0B, (byte) 0x79, (byte) 0xF8, (byte) 0x60, (byte) 0x73,
-        (byte) 0xD1, (byte) 0xF9, (byte) 0xD4, (byte) 0x66, (byte) 0x29, (byte) 0x7D, (byte) 0xDC, (byte) 0x22, (byte) 0xDB, (byte) 0x61, (byte) 0x02, (byte) 0x40, (byte) 0x5D, (byte) 0x3D, (byte) 0xEF, (byte) 0x85, (byte) 0x4D,
-        (byte) 0x27, (byte) 0x2F, (byte) 0xB5, (byte) 0xF9, (byte) 0xCE, (byte) 0x6C, (byte) 0x84, (byte) 0xBB, (byte) 0x85, (byte) 0xD9, (byte) 0x52, (byte) 0xEE, (byte) 0x5B, (byte) 0xA9, (byte) 0x63, (byte) 0x15, (byte) 0x12,
-        (byte) 0x6F, (byte) 0xBA, (byte) 0x3A, (byte) 0x4E, (byte) 0xA9, (byte) 0x8D, (byte) 0x7A, (byte) 0x3B, (byte) 0xF9, (byte) 0xDF, (byte) 0xF5, (byte) 0xE4, (byte) 0xDC, (byte) 0x01, (byte) 0x1C, (byte) 0x2D, (byte) 0x8C,
-        (byte) 0x0D, (byte) 0xE1, (byte) 0x6E, (byte) 0x80, (byte) 0x63, (byte) 0x9B, (byte) 0x0B, (byte) 0x38, (byte) 0x55, (byte) 0xC8, (byte) 0x52, (byte) 0x67, (byte) 0x13, (byte) 0x91, (byte) 0x8F, (byte) 0x9E, (byte) 0x2E,
-        (byte) 0x16, (byte) 0x5B, (byte) 0x7C, (byte) 0x0F, (byte) 0x5D, (byte) 0xE4, (byte) 0xA0, (byte) 0x81, (byte) 0x02, (byte) 0x40, (byte) 0x20, (byte) 0x12, (byte) 0x11, (byte) 0x5E, (byte) 0x70, (byte) 0x0C, (byte) 0xEC,
-        (byte) 0x02, (byte) 0x49, (byte) 0x0E, (byte) 0xB9, (byte) 0x3D, (byte) 0xD3, (byte) 0xFB, (byte) 0x59, (byte) 0xF0, (byte) 0x7D, (byte) 0x62, (byte) 0xEF, (byte) 0xF5, (byte) 0x77, (byte) 0x99, (byte) 0x87, (byte) 0x11,
-        (byte) 0x20, (byte) 0xB6, (byte) 0xCD, (byte) 0xA5, (byte) 0x67, (byte) 0xB3, (byte) 0x92, (byte) 0xC9, (byte) 0xBC, (byte) 0xB3, (byte) 0x9E, (byte) 0x5E, (byte) 0xF3, (byte) 0x03, (byte) 0x22, (byte) 0x5F, (byte) 0x79,
-        (byte) 0x7F, (byte) 0xCC, (byte) 0x44, (byte) 0xDA, (byte) 0x3B, (byte) 0xF3, (byte) 0xC3, (byte) 0x42, (byte) 0x58, (byte) 0x90, (byte) 0x93, (byte) 0x7E, (byte) 0xDA, (byte) 0x58, (byte) 0xCC, (byte) 0x16, (byte) 0xC8,
-        (byte) 0xAE, (byte) 0x99, (byte) 0xCC, (byte) 0x9F, (byte) 0x32, (byte) 0x61, (byte) 0x02, (byte) 0x40, (byte) 0x02, (byte) 0x29, (byte) 0xDB, (byte) 0x00, (byte) 0x0F, (byte) 0x0A, (byte) 0x17, (byte) 0x33, (byte) 0x7E,
-        (byte) 0xC5, (byte) 0xEC, (byte) 0x21, (byte) 0x47, (byte) 0x65, (byte) 0xDC, (byte) 0xE5, (byte) 0xC2, (byte) 0x0D, (byte) 0x42, (byte) 0x28, (byte) 0xE1, (byte) 0x17, (byte) 0x1A, (byte) 0x00, (byte) 0xBD, (byte) 0xBE,
-        (byte) 0x1C, (byte) 0x7D, (byte) 0xCA, (byte) 0x93, (byte) 0x67, (byte) 0x8F, (byte) 0x28, (byte) 0xB7, (byte) 0x60, (byte) 0x8E, (byte) 0xF0, (byte) 0x5D, (byte) 0xCD, (byte) 0xFA, (byte) 0xDD, (byte) 0x6B, (byte) 0x72,
-        (byte) 0xF7, (byte) 0x48, (byte) 0xD9, (byte) 0x3C, (byte) 0x40, (byte) 0x7C, (byte) 0xB0, (byte) 0xD7, (byte) 0x58, (byte) 0xC2, (byte) 0x53, (byte) 0xAD, (byte) 0x04, (byte) 0xF6, (byte) 0x0B, (byte) 0x35, (byte) 0x51,
-        (byte) 0x45, (byte) 0xB9, (byte) 0x4F, (byte) 0x49  };
-        private static final byte[] RSA_public = new byte[] {
-        (byte) 0x30, (byte) 0x81, (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05,
-        (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x99, (byte) 0xA5, (byte) 0x96, (byte) 0x72, (byte) 0xAE,
-        (byte) 0xBB, (byte) 0x59, (byte) 0x36, (byte) 0xA8, (byte) 0x12, (byte) 0x17, (byte) 0x05, (byte) 0x4C, (byte) 0x63, (byte) 0x9E, (byte) 0xB8, (byte) 0x85, (byte) 0xD4, (byte) 0x2D, (byte) 0x71, (byte) 0xD7, (byte) 0x29,
-        (byte) 0xB9, (byte) 0x05, (byte) 0x0F, (byte) 0xB4, (byte) 0x57, (byte) 0xFB, (byte) 0xD3, (byte) 0x95, (byte) 0x5C, (byte) 0x21, (byte) 0xEC, (byte) 0xB5, (byte) 0xEB, (byte) 0x67, (byte) 0xA2, (byte) 0x4F, (byte) 0xC1,
-        (byte) 0x93, (byte) 0xEF, (byte) 0x96, (byte) 0x41, (byte) 0x05, (byte) 0x3D, (byte) 0xC5, (byte) 0x3E, (byte) 0x04, (byte) 0x4D, (byte) 0xC6, (byte) 0xCF, (byte) 0x32, (byte) 0x7C, (byte) 0x1F, (byte) 0x66, (byte) 0xA3,
-        (byte) 0xC5, (byte) 0x27, (byte) 0x79, (byte) 0xEC, (byte) 0x2E, (byte) 0x67, (byte) 0xFA, (byte) 0x19, (byte) 0x5B, (byte) 0xE3, (byte) 0xB1, (byte) 0x69, (byte) 0xDA, (byte) 0x63, (byte) 0xBC, (byte) 0xDA, (byte) 0xD3,
-        (byte) 0xBB, (byte) 0xAD, (byte) 0x8C, (byte) 0x38, (byte) 0x7B, (byte) 0x4A, (byte) 0x9C, (byte) 0xD4, (byte) 0x4D, (byte) 0xD2, (byte) 0x33, (byte) 0xB7, (byte) 0x4E, (byte) 0x04, (byte) 0xB6, (byte) 0xDF, (byte) 0x62,
-        (byte) 0x55, (byte) 0x48, (byte) 0x5C, (byte) 0x94, (byte) 0x02, (byte) 0xF7, (byte) 0x84, (byte) 0xE6, (byte) 0x9B, (byte) 0x57, (byte) 0xFF, (byte) 0x17, (byte) 0x2A, (byte) 0xA1, (byte) 0x74, (byte) 0x8D, (byte) 0x07,
-        (byte) 0xD8, (byte) 0xCE, (byte) 0xF7, (byte) 0x0B, (byte) 0x59, (byte) 0xFB, (byte) 0x13, (byte) 0x6E, (byte) 0xF1, (byte) 0xC3, (byte) 0xAB, (byte) 0x3E, (byte) 0x72, (byte) 0x1B, (byte) 0x62, (byte) 0x09, (byte) 0xE8,
-        (byte) 0xD8, (byte) 0x41, (byte) 0x69, (byte) 0xE1, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01     };
-        private static final byte[] DSA_private = new byte[] {
-        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4B, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2C, (byte) 0x06, (byte) 0x07, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0xCE,
-        (byte) 0x38, (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1F, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75,
-        (byte) 0x12, (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44,
-        (byte) 0x00, (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D,
-        (byte) 0x8D, (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80,
-        (byte) 0x1D, (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B,
-        (byte) 0x10, (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8,
-        (byte) 0xA6, (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16,
-        (byte) 0x91, (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1,
-        (byte) 0x48, (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8F, (byte) 0x15, (byte) 0x23, (byte) 0x0B, (byte) 0xCC, (byte) 0xB2, (byte) 0x92, (byte) 0xB9,
-        (byte) 0x82, (byte) 0xA2, (byte) 0xEB, (byte) 0x84, (byte) 0x0B, (byte) 0xF0, (byte) 0x58, (byte) 0x1C, (byte) 0xF5, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85,
-        (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA,
-        (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4,
-        (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16,
-        (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28,
-        (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62,
-        (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83,
-        (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C,
-        (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49, (byte) 0x2A, (byte) 0x04, (byte) 0x16, (byte) 0x02, (byte) 0x14, (byte) 0x0E, (byte) 0x90, (byte) 0xB7, (byte) 0x92, (byte) 0x01, (byte) 0x98, (byte) 0xCD, (byte) 0x85,
-        (byte) 0x87, (byte) 0x77, (byte) 0x2F, (byte) 0xB4, (byte) 0x31, (byte) 0xFD, (byte) 0xDE, (byte) 0xFA, (byte) 0x08, (byte) 0x6D, (byte) 0x0C, (byte) 0xE3  };
-        private static final byte[] DSA_public = new byte[] {
-        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xB8, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2C, (byte) 0x06, (byte) 0x07, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0xCE, (byte) 0x38, (byte) 0x04, (byte) 0x01,
-        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1F, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75, (byte) 0x12, (byte) 0x29, (byte) 0x52,
-        (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44, (byte) 0x00, (byte) 0xC3, (byte) 0x1E,
-        (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D, (byte) 0x8D, (byte) 0x58, (byte) 0xFA,
-        (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80, (byte) 0x1D, (byte) 0x34, (byte) 0x6F,
-        (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B, (byte) 0x10, (byte) 0x22, (byte) 0xC2,
-        (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8, (byte) 0xA6, (byte) 0x15, (byte) 0x0F,
-        (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xF6,
-        (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1, (byte) 0x48, (byte) 0x01, (byte) 0xC7,
-        (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8F, (byte) 0x15, (byte) 0x23, (byte) 0x0B, (byte) 0xCC, (byte) 0xB2, (byte) 0x92, (byte) 0xB9, (byte) 0x82, (byte) 0xA2, (byte) 0xEB,
-        (byte) 0x84, (byte) 0x0B, (byte) 0xF0, (byte) 0x58, (byte) 0x1C, (byte) 0xF5, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D,
-        (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82,
-        (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6,
-        (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF,
-        (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE,
-        (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62,
-        (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A,
-        (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF,
-        (byte) 0x49, (byte) 0x2A, (byte) 0x03, (byte) 0x81, (byte) 0x85, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x98, (byte) 0x33, (byte) 0x90, (byte) 0x14, (byte) 0x79, (byte) 0xC7, (byte) 0xC8,
-        (byte) 0x57, (byte) 0xE1, (byte) 0x82, (byte) 0x53, (byte) 0x5B, (byte) 0x6E, (byte) 0x01, (byte) 0x07, (byte) 0x1E, (byte) 0xA5, (byte) 0x98, (byte) 0xC4, (byte) 0x57, (byte) 0x5D, (byte) 0x23, (byte) 0xAB, (byte) 0x72,
-        (byte) 0x9A, (byte) 0xB3, (byte) 0x2F, (byte) 0x39, (byte) 0xCB, (byte) 0xC5, (byte) 0xD0, (byte) 0x97, (byte) 0xD5, (byte) 0x62, (byte) 0x8C, (byte) 0xD9, (byte) 0xE6, (byte) 0xE2, (byte) 0x05, (byte) 0xC6, (byte) 0x05,
-        (byte) 0x71, (byte) 0x16, (byte) 0xE3, (byte) 0xE8, (byte) 0x04, (byte) 0xE8, (byte) 0x46, (byte) 0x12, (byte) 0x0C, (byte) 0xF8, (byte) 0xFC, (byte) 0x8E, (byte) 0x15, (byte) 0x26, (byte) 0x32, (byte) 0xF7, (byte) 0x8C,
-        (byte) 0x04, (byte) 0x3B, (byte) 0x53, (byte) 0x68, (byte) 0x9A, (byte) 0xA3, (byte) 0xB7, (byte) 0x4D, (byte) 0x13, (byte) 0x40, (byte) 0x0F, (byte) 0xBE, (byte) 0x03, (byte) 0x87, (byte) 0xD8, (byte) 0xF1, (byte) 0xFE,
-        (byte) 0x4B, (byte) 0xF5, (byte) 0x44, (byte) 0x19, (byte) 0x29, (byte) 0xBB, (byte) 0x0D, (byte) 0x0C, (byte) 0x52, (byte) 0xC6, (byte) 0x84, (byte) 0x33, (byte) 0x62, (byte) 0x73, (byte) 0x5D, (byte) 0x03, (byte) 0xFF,
-        (byte) 0x6F, (byte) 0x0A, (byte) 0x5A, (byte) 0xF3, (byte) 0x9E, (byte) 0x52, (byte) 0xF2, (byte) 0xC2, (byte) 0xC8, (byte) 0x00, (byte) 0x52, (byte) 0xC7, (byte) 0x75, (byte) 0xA4, (byte) 0xFD, (byte) 0x71, (byte) 0x2D,
-        (byte) 0x7B, (byte) 0x7A, (byte) 0x31, (byte) 0x27, (byte) 0x6E, (byte) 0xAC, (byte) 0xB6, (byte) 0x40, (byte) 0x14, (byte) 0x4E, (byte) 0xB4, (byte) 0xBB, (byte) 0xB1, (byte) 0x51, (byte) 0x63, (byte) 0x29, (byte) 0x81,
-        (byte) 0x06, (byte) 0xF9    };
-        private static final byte[] DH_private = new byte[] {
-        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xA8, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1B, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81,
-        (byte) 0x1D, (byte) 0x75, (byte) 0x12, (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C,
-        (byte) 0xEF, (byte) 0x44, (byte) 0x00, (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB,
-        (byte) 0x59, (byte) 0x3D, (byte) 0x8D, (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81,
-        (byte) 0x3B, (byte) 0x80, (byte) 0x1D, (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8,
-        (byte) 0x04, (byte) 0x7B, (byte) 0x10, (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7,
-        (byte) 0xC6, (byte) 0xA8, (byte) 0xA6, (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13,
-        (byte) 0x5A, (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19,
-        (byte) 0x9D, (byte) 0xD1, (byte) 0x48, (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE,
-        (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9,
-        (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71,
-        (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09,
-        (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E,
-        (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A,
-        (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5,
-        (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49,
-        (byte) 0x2A, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0xFE, (byte) 0x04, (byte) 0x81, (byte) 0x83, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x35, (byte) 0xFE, (byte) 0x44, (byte) 0x0A, (byte) 0xA3, (byte) 0xA0,
-        (byte) 0xCB, (byte) 0x52, (byte) 0xC2, (byte) 0x32, (byte) 0xCA, (byte) 0x38, (byte) 0x1F, (byte) 0x18, (byte) 0xEB, (byte) 0x27, (byte) 0x6E, (byte) 0x77, (byte) 0x25, (byte) 0x40, (byte) 0x1F, (byte) 0x64, (byte) 0x5D,
-        (byte) 0x4B, (byte) 0x59, (byte) 0x41, (byte) 0xB6, (byte) 0xCB, (byte) 0xDF, (byte) 0x73, (byte) 0xE0, (byte) 0x01, (byte) 0x5A, (byte) 0x79, (byte) 0x0D, (byte) 0x8D, (byte) 0x08, (byte) 0xE6, (byte) 0x7F, (byte) 0x86,
-        (byte) 0x58, (byte) 0xCF, (byte) 0x7F, (byte) 0x4B, (byte) 0x2E, (byte) 0xDB, (byte) 0x4C, (byte) 0xDF, (byte) 0x75, (byte) 0xB5, (byte) 0x16, (byte) 0xC4, (byte) 0xA9, (byte) 0x49, (byte) 0xEE, (byte) 0x00, (byte) 0x56,
-        (byte) 0xA0, (byte) 0x60, (byte) 0x08, (byte) 0x8E, (byte) 0x0D, (byte) 0xC7, (byte) 0xC9, (byte) 0x45, (byte) 0x0C, (byte) 0x5D, (byte) 0xB7, (byte) 0x4C, (byte) 0xC4, (byte) 0x7E, (byte) 0xAB, (byte) 0x1F, (byte) 0xEA,
-        (byte) 0xCF, (byte) 0x08, (byte) 0x6D, (byte) 0x05, (byte) 0xA1, (byte) 0x7F, (byte) 0x63, (byte) 0x6F, (byte) 0xB3, (byte) 0x91, (byte) 0xA3, (byte) 0xE1, (byte) 0xB0, (byte) 0x36, (byte) 0x02, (byte) 0x3F, (byte) 0x55,
-        (byte) 0x71, (byte) 0x38, (byte) 0x37, (byte) 0x9A, (byte) 0x19, (byte) 0xA3, (byte) 0xAF, (byte) 0xC8, (byte) 0xD5, (byte) 0x22, (byte) 0xDD, (byte) 0x00, (byte) 0x81, (byte) 0x19, (byte) 0xB6, (byte) 0x3C, (byte) 0x5F,
-        (byte) 0xD9, (byte) 0xDF, (byte) 0xFD, (byte) 0x58, (byte) 0xB1, (byte) 0xE6, (byte) 0xD1, (byte) 0xD2, (byte) 0x58, (byte) 0xEF, (byte) 0x44, (byte) 0x6E, (byte) 0x66, (byte) 0x92, (byte) 0x1E, (byte) 0x30, (byte) 0x0B,
-        (byte) 0x90, (byte) 0x8E, (byte) 0x29   };
-        private static final byte[] DH_public = new byte[] {
-        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xA7, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1B, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01,
-        (byte) 0x03, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75, (byte) 0x12,
-        (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44, (byte) 0x00,
-        (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D, (byte) 0x8D,
-        (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80, (byte) 0x1D,
-        (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B, (byte) 0x10,
-        (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8, (byte) 0xA6,
-        (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16, (byte) 0x91,
-        (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1, (byte) 0x48,
-        (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB,
-        (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B,
-        (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81,
-        (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8,
-        (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6,
-        (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B,
-        (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92,
-        (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49, (byte) 0x2A, (byte) 0x02, (byte) 0x02,
-        (byte) 0x03, (byte) 0xFE, (byte) 0x03, (byte) 0x81, (byte) 0x85, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xD4, (byte) 0xC2, (byte) 0xC2, (byte) 0x84, (byte) 0xEB, (byte) 0xEC, (byte) 0xB6,
-        (byte) 0xF1, (byte) 0x29, (byte) 0x2B, (byte) 0xAB, (byte) 0x8F, (byte) 0xC1, (byte) 0x48, (byte) 0x4C, (byte) 0x47, (byte) 0xCE, (byte) 0x0B, (byte) 0x97, (byte) 0x4C, (byte) 0xFC, (byte) 0x27, (byte) 0x10, (byte) 0x0A,
-        (byte) 0x5F, (byte) 0x3E, (byte) 0xE6, (byte) 0xF9, (byte) 0x9B, (byte) 0x15, (byte) 0xDF, (byte) 0x83, (byte) 0x01, (byte) 0xFA, (byte) 0x69, (byte) 0x57, (byte) 0xEC, (byte) 0x6B, (byte) 0x68, (byte) 0xC7, (byte) 0x96,
-        (byte) 0x33, (byte) 0x98, (byte) 0xA4, (byte) 0xB0, (byte) 0xA3, (byte) 0x18, (byte) 0x01, (byte) 0x66, (byte) 0x7A, (byte) 0x4A, (byte) 0xF3, (byte) 0x3C, (byte) 0xD9, (byte) 0x2A, (byte) 0x48, (byte) 0xFD, (byte) 0x3A,
-        (byte) 0x31, (byte) 0xFC, (byte) 0x97, (byte) 0x52, (byte) 0x36, (byte) 0x20, (byte) 0x0E, (byte) 0x69, (byte) 0xB6, (byte) 0x32, (byte) 0x8B, (byte) 0x4E, (byte) 0xDA, (byte) 0x8B, (byte) 0x04, (byte) 0x88, (byte) 0xF8,
-        (byte) 0x30, (byte) 0xA9, (byte) 0x65, (byte) 0x68, (byte) 0x47, (byte) 0xBB, (byte) 0xA1, (byte) 0xF6, (byte) 0xD6, (byte) 0x18, (byte) 0x11, (byte) 0x48, (byte) 0x8D, (byte) 0x8F, (byte) 0x4B, (byte) 0xC1, (byte) 0xE1,
-        (byte) 0xA4, (byte) 0x43, (byte) 0x83, (byte) 0x1F, (byte) 0x6B, (byte) 0x6D, (byte) 0xEE, (byte) 0xA7, (byte) 0xA3, (byte) 0x5F, (byte) 0xD2, (byte) 0x95, (byte) 0x09, (byte) 0xD4, (byte) 0xEA, (byte) 0x85, (byte) 0x0C,
-        (byte) 0xA5, (byte) 0xC9, (byte) 0x93, (byte) 0xCE, (byte) 0xC1, (byte) 0x1D, (byte) 0x30, (byte) 0x73, (byte) 0xA3, (byte) 0xE1, (byte) 0x69, (byte) 0xA8, (byte) 0x11, (byte) 0x98, (byte) 0x78, (byte) 0xF3, (byte) 0xF9,
-        (byte) 0x8F, (byte) 0x04    };
-
-
-
-    private static final HashMap<String, KeySpec> keys = new HashMap<String, KeySpec>();
-    static {
-        keys.put("DH_public", new X509EncodedKeySpec(DH_public));
-        keys.put("DH_private", new PKCS8EncodedKeySpec(DH_private));
-        keys.put("DSA_public", new X509EncodedKeySpec(DSA_public));
-        keys.put("DSA_private", new PKCS8EncodedKeySpec(DSA_private));
-        keys.put("RSA_public", new X509EncodedKeySpec(RSA_public));
-        keys.put("RSA_private", new PKCS8EncodedKeySpec(RSA_private));
-    }
-
-    public static PrivateKey getPrivateKey(String algorithmName) throws NoSuchAlgorithmException, InvalidKeySpecException
-    {
-        KeyFactory factory = KeyFactory.getInstance(algorithmName);
-        return factory.generatePrivate(keys.get(algorithmName + "_private"));
-    }
-
-    public static PublicKey getPublicKey(String algorithmName) throws NoSuchAlgorithmException, InvalidKeySpecException
-    {
-        KeyFactory factory = KeyFactory.getInstance(algorithmName);
-        return factory.generatePublic(keys.get(algorithmName + "_public"));
-    }
-}
diff --git a/support/src/test/java/tests/security/KeyAgreementHelper.java b/support/src/test/java/tests/security/KeyAgreementHelper.java
deleted file mode 100644
index f2c2792..0000000
--- a/support/src/test/java/tests/security/KeyAgreementHelper.java
+++ /dev/null
@@ -1,45 +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 tests.security;
-
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import javax.crypto.KeyAgreement;
-import junit.framework.Assert;
-
-public class KeyAgreementHelper extends TestHelper<KeyPair> {
-
-    private final String algorithmName;
-
-    public KeyAgreementHelper(String algorithmName) {
-        this.algorithmName = algorithmName;
-    }
-
-    @Override public void test(KeyPair keyPair) throws Exception {
-        test(keyPair.getPrivate(), keyPair.getPublic());
-    }
-
-    void test(PrivateKey encryptKey, PublicKey decryptKey) throws Exception {
-        KeyAgreement keyAgreement = KeyAgreement.getInstance(algorithmName);
-        keyAgreement.init(encryptKey);
-        keyAgreement.doPhase(decryptKey, true);
-        Assert.assertNotNull("generated secret is null", keyAgreement.generateSecret());
-    }
-}
diff --git a/support/src/test/java/tests/security/KeyFactoryTest.java b/support/src/test/java/tests/security/KeyFactoryTest.java
deleted file mode 100644
index 46a6502..0000000
--- a/support/src/test/java/tests/security/KeyFactoryTest.java
+++ /dev/null
@@ -1,64 +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 tests.security;
-
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import junit.framework.TestCase;
-
-public abstract class KeyFactoryTest<PublicKeySpec extends KeySpec, PrivateKeySpec extends KeySpec>
-        extends TestCase {
-
-    private final String algorithmName;
-    private final Class<PublicKeySpec> publicKeySpecClass;
-    private final Class<PrivateKeySpec> privateKeySpecClass;
-    private KeyFactory factory;
-
-    public KeyFactoryTest(String algorithmName,
-            Class<PublicKeySpec> publicKeySpecClass,
-            Class<PrivateKeySpec> privateKeySpecClass) {
-        this.algorithmName = algorithmName;
-        this.publicKeySpecClass = publicKeySpecClass;
-        this.privateKeySpecClass = privateKeySpecClass;
-    }
-
-    protected void setUp() throws Exception {
-        super.setUp();
-        factory = getFactory();
-    }
-
-    private KeyFactory getFactory() throws Exception {
-        return KeyFactory.getInstance(algorithmName);
-    }
-
-    public void testKeyFactory() throws Exception {
-        PrivateKeySpec privateKeySpec = factory.getKeySpec(DefaultKeys.getPrivateKey(algorithmName),
-                                                           privateKeySpecClass);
-        PrivateKey privateKey =  factory.generatePrivate(privateKeySpec);
-        PublicKeySpec publicKeySpec = factory.getKeySpec(DefaultKeys.getPublicKey(algorithmName),
-                                                         publicKeySpecClass);
-        PublicKey publicKey = factory.generatePublic(publicKeySpec);
-        check(new KeyPair(publicKey, privateKey));
-    }
-
-    protected void check(KeyPair keyPair) throws Exception {}
-}
diff --git a/support/src/test/java/tests/security/KeyPairGeneratorTest.java b/support/src/test/java/tests/security/KeyPairGeneratorTest.java
deleted file mode 100644
index 89e7e69..0000000
--- a/support/src/test/java/tests/security/KeyPairGeneratorTest.java
+++ /dev/null
@@ -1,52 +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 tests.security;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import junit.framework.TestCase;
-
-public abstract class KeyPairGeneratorTest extends TestCase {
-
-    private final String algorithmName;
-    private final TestHelper<KeyPair> helper;
-
-    private KeyPairGenerator generator;
-
-    protected KeyPairGeneratorTest(String algorithmName, TestHelper<KeyPair> helper) {
-        this.algorithmName = algorithmName;
-        this.helper = helper;
-    }
-
-    protected void setUp() throws Exception {
-        super.setUp();
-        generator = KeyPairGenerator.getInstance(algorithmName);
-    }
-
-    public void testKeyPairGenerator() throws Exception {
-        generator.initialize(1024);
-
-        KeyPair keyPair = generator.generateKeyPair();
-
-        assertNotNull("no keypair generated", keyPair);
-        assertNotNull("no public key generated", keyPair.getPublic());
-        assertNotNull("no private key generated", keyPair.getPrivate());
-
-        helper.test(keyPair);
-    }
-}
diff --git a/support/src/test/java/tests/security/MessageDigestTest.java b/support/src/test/java/tests/security/MessageDigestTest.java
deleted file mode 100644
index c8dbf72..0000000
--- a/support/src/test/java/tests/security/MessageDigestTest.java
+++ /dev/null
@@ -1,194 +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 tests.security;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import junit.framework.TestCase;
-
-public abstract class MessageDigestTest extends TestCase {
-
-    private String digestAlgorithmName;
-
-    protected MessageDigestTest(String digestAlgorithmName) {
-        super();
-        this.digestAlgorithmName = digestAlgorithmName;
-    }
-
-    private MessageDigest digest;
-    private InputStream sourceData;
-    private byte[] checkDigest;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        this.source3 = getLongMessage(1000000);
-        this.digest = MessageDigest.getInstance(digestAlgorithmName);
-        this.sourceData = getSourceData();
-        this.checkDigest = getCheckDigest();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        // This is critical. The MessageDigest tests consume a lot of memory due
-        // to the 1 MB buffers being allocated. We need to make sure all data is
-        // freed after each test. Otherwise the Android runtime simply dies at
-        // some point.
-        source1 = null;
-        source2 = null;
-        source3 = null;
-
-        expected1 = null;
-        expected2 = null;
-        expected3 = null;
-
-        digest = null;
-        sourceData.close();
-        sourceData = null;
-        checkDigest = null;
-
-        System.gc();
-    }
-
-    InputStream getSourceData() {
-        InputStream sourceStream = getClass().getResourceAsStream(digestAlgorithmName + ".data");
-        assertNotNull("digest source data not found: " + digestAlgorithmName, sourceStream);
-        return sourceStream;
-    }
-
-    byte[] getCheckDigest() throws Exception {
-        InputStream checkDigestStream =
-                getClass().getResourceAsStream(digestAlgorithmName + ".check");
-        byte[] checkDigest = new byte[digest.getDigestLength()];
-        int read = 0;
-        int index = 0;
-        while ((read = checkDigestStream.read()) != -1) {
-            checkDigest[index++] = (byte)read;
-        }
-        checkDigestStream.close();
-        return checkDigest;
-    }
-
-    public void testMessageDigest1() throws Exception {
-        byte[] buf = new byte[128];
-        int read = 0;
-        while ((read = sourceData.read(buf)) != -1) {
-            digest.update(buf, 0, read);
-        }
-        sourceData.close();
-
-        byte[] computedDigest = digest.digest();
-
-        assertNotNull("computed digest is is null", computedDigest);
-        assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
-
-        for (int i = 0; i < checkDigest.length; i++) {
-            assertEquals("byte " + i + " of computed and check digest differ",
-                         checkDigest[i], computedDigest[i]);
-        }
-    }
-
-    public void testMessageDigest2() throws Exception {
-        int val;
-        while ((val = sourceData.read()) != -1) {
-            digest.update((byte)val);
-        }
-        sourceData.close();
-
-        byte[] computedDigest = digest.digest();
-
-        assertNotNull("computed digest is is null", computedDigest);
-        assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
-
-        for (int i = 0; i < checkDigest.length; i++) {
-            assertEquals("byte " + i + " of computed and check digest differ",
-                         checkDigest[i], computedDigest[i]);
-        }
-    }
-
-
-    /**
-     * Official FIPS180-2 testcases
-     */
-
-    protected String source1;
-    protected String source2;
-    protected String source3;
-    protected String expected1;
-    protected String expected2;
-    protected String expected3;
-
-    String getLongMessage(int length) {
-        StringBuilder sourceBuilder = new StringBuilder(length);
-        for (int i = 0; i < length / 10; i++) {
-            sourceBuilder.append("aaaaaaaaaa");
-        }
-        return sourceBuilder.toString();
-    }
-
-    public void testfips180_2_singleblock() throws Exception {
-
-        digest.update(source1.getBytes(), 0, source1.length());
-
-        byte[] computedDigest = digest.digest();
-
-        assertNotNull("computed digest is null", computedDigest);
-
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < computedDigest.length; i++) {
-            String res = Integer.toHexString(computedDigest[i] & 0xFF);
-            sb.append((res.length() == 1 ? "0" : "") + res);
-        }
-        assertEquals("computed and check digest differ", expected1, sb.toString());
-    }
-
-    public void testfips180_2_multiblock() throws Exception {
-
-        digest.update(source2.getBytes(), 0, source2.length());
-
-        byte[] computedDigest = digest.digest();
-
-        assertNotNull("computed digest is null", computedDigest);
-
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < computedDigest.length; i++) {
-            String res = Integer.toHexString(computedDigest[i] & 0xFF);
-            sb.append((res.length() == 1 ? "0" : "") + res);
-        }
-        assertEquals("computed and check digest differ", expected2, sb.toString());
-    }
-
-    public void testfips180_2_longMessage() throws Exception {
-
-        digest.update(source3.getBytes(), 0, source3.length());
-
-        byte[] computedDigest = digest.digest();
-
-        assertNotNull("computed digest is null", computedDigest);
-
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < computedDigest.length; i++) {
-            String res = Integer.toHexString(computedDigest[i] & 0xFF);
-            sb.append((res.length() == 1 ? "0" : "") + res);
-        }
-        assertEquals("computed and check digest differ", expected3, sb.toString());
-    }
-}
diff --git a/support/src/test/java/tests/security/SignatureHelper.java b/support/src/test/java/tests/security/SignatureHelper.java
deleted file mode 100644
index b4fc1db..0000000
--- a/support/src/test/java/tests/security/SignatureHelper.java
+++ /dev/null
@@ -1,52 +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 tests.security;
-
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import junit.framework.Assert;
-
-public class SignatureHelper extends TestHelper<KeyPair> {
-
-    private final String algorithmName;
-    private final String plainData = "some data do sign and verify";
-
-    public SignatureHelper(String algorithmName) {
-        this.algorithmName = algorithmName;
-    }
-
-    @Override
-    public void test(KeyPair keyPair) throws Exception {
-        test(keyPair.getPrivate(), keyPair.getPublic());
-    }
-
-    public void test(PrivateKey encryptKey, PublicKey decryptKey) throws Exception {
-        Signature signature = Signature.getInstance(algorithmName);
-        signature.initSign(encryptKey);
-        signature.update(plainData.getBytes());
-        byte[] signed = signature.sign();
-
-        signature.initVerify(decryptKey);
-        signature.update(plainData.getBytes());
-        Assert.assertTrue("signature could not be verified", signature.verify(signed));
-    }
-}
diff --git a/support/src/test/java/tests/security/TestHelper.java b/support/src/test/java/tests/security/TestHelper.java
deleted file mode 100644
index be146b2..0000000
--- a/support/src/test/java/tests/security/TestHelper.java
+++ /dev/null
@@ -1,21 +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 tests.security;
-
-public abstract class TestHelper<T> {
-    public abstract void test(T testObject) throws Exception;
-}
diff --git a/support/src/test/java/tests/util/CallVerificationStack.java b/support/src/test/java/tests/util/CallVerificationStack.java
deleted file mode 100644
index 6c1881b..0000000
--- a/support/src/test/java/tests/util/CallVerificationStack.java
+++ /dev/null
@@ -1,353 +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 tests.util;
-
-import java.util.Stack;
-
-/**
- * A stack to store the parameters of a call, as well as the call stack.
- *
- */
-public class CallVerificationStack extends Stack<Object> {
-
-    /*
-     * --------------------------------------------------------------------
-     * Class variables
-     * --------------------------------------------------------------------
-     */
-
-    private static final long serialVersionUID = 1L;
-
-    // the singleton
-    private static final CallVerificationStack _instance = new CallVerificationStack();
-
-    /*
-     * --------------------------------------------------------------------
-     * Instance variables
-     * --------------------------------------------------------------------
-     */
-
-    // the call stack, store StackTraceElement
-    private final Stack<StackTraceElement> callStack = new Stack<StackTraceElement>();
-
-    /*
-     * -------------------------------------------------------------------
-     * Constructors
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Can't be instantiated.
-     */
-    private CallVerificationStack() {
-        // empty
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Gets the singleton instance.
-     *
-     * @return the singleton instance
-     */
-    public static CallVerificationStack getInstance() {
-        return _instance;
-    }
-
-    /**
-     * Pushes the call stack.
-     */
-    private void pushCallStack() {
-        StackTraceElement[] eles = (new Throwable()).getStackTrace();
-        int i;
-        for (i = 1; i < eles.length; i++) {
-            if (!eles[i].getClassName().equals(this.getClass().getName())) {
-                break;
-            }
-        }
-        this.callStack.push(eles[i]);
-    }
-
-    /**
-     * Gets the "current" calling class name.
-     *
-     * @return the "current" calling class name
-     */
-    public String getCurrentSourceClass() {
-        return this.callStack.peek().getClassName();
-    }
-
-    /**
-     * Gets the "current" calling method name.
-     *
-     * @return the "current" calling method name
-     */
-    public String getCurrentSourceMethod() {
-        return this.callStack.peek().getMethodName();
-    }
-
-    /**
-     * Clear the parameter stack and the call stack.
-     *
-     */
-    @Override
-    public void clear() {
-        this.callStack.clear();
-        super.clear();
-    }
-
-    @Override
-    public Object push(Object o) {
-        pushCallStack();
-        return super.push(o);
-    }
-
-    /**
-     * Pushes a boolean onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(boolean val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes a char onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(char val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes a double onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(double val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes a float onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(float val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes an int onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(int val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes a long onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(long val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pushes a short onto the top of this stack.
-     *
-     * @param val
-     *            the value to push
-     */
-    public void push(short val) {
-        this.push(new BaseTypeWrapper(val));
-    }
-
-    /**
-     * Pop an object.
-     *
-     * @return the object
-     */
-    @Override
-    public Object pop() {
-        this.callStack.pop();
-        return super.pop();
-    }
-
-    /**
-     * Pop a boolean.
-     *
-     * @return the value
-     */
-    public boolean popBoolean() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Boolean value = (Boolean) wrapper.getValue();
-        return value.booleanValue();
-    }
-
-    /**
-     * Pop a char.
-     *
-     * @return the value
-     */
-    public char popChar() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Character value = (Character) wrapper.getValue();
-        return value.charValue();
-    }
-
-    /**
-     * Pop a double.
-     *
-     * @return the value
-     */
-    public double popDouble() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Double value = (Double) wrapper.getValue();
-        return value.doubleValue();
-    }
-
-    /**
-     * Pop a float.
-     *
-     * @return the value
-     */
-    public float popFloat() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Float value = (Float) wrapper.getValue();
-        return value.floatValue();
-    }
-
-    /**
-     * Pop a int.
-     *
-     * @return the value
-     */
-    public int popInt() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Integer value = (Integer) wrapper.getValue();
-        return value.intValue();
-    }
-
-    /**
-     * Pop a long.
-     *
-     * @return the value
-     */
-    public long popLong() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Long value = (Long) wrapper.getValue();
-        return value.longValue();
-    }
-
-    /**
-     * Pop a short.
-     *
-     * @return the value
-     */
-    public short popShort() {
-        BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop();
-        Short value = (Short) wrapper.getValue();
-        return value.shortValue();
-    }
-
-    /*
-     * Wrapper of base types.
-     */
-    class BaseTypeWrapper {
-
-        // the internal value
-        private Object value;
-
-        /*
-         * Constructs a wrapper object for the base type <code> boolean </code> .
-         */
-        public BaseTypeWrapper(boolean val) {
-            this.value = new Boolean(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> c </code> .
-         */
-        public BaseTypeWrapper(byte val) {
-            this.value = new Byte(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> char </code> .
-         */
-        public BaseTypeWrapper(char val) {
-            this.value = new Character(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> double </code> .
-         */
-        public BaseTypeWrapper(double val) {
-            this.value = new Double(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> float </code> .
-         */
-        public BaseTypeWrapper(float val) {
-            this.value = new Float(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> int </code> .
-         */
-        public BaseTypeWrapper(int val) {
-            this.value = new Integer(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> long </code> .
-         */
-        public BaseTypeWrapper(long val) {
-            this.value = new Long(val);
-        }
-
-        /*
-         * Constructs a wrapper object for the base type <code> short </code> .
-         */
-        public BaseTypeWrapper(short val) {
-            this.value = new Short(val);
-        }
-
-        /*
-         * Gets the internal value.
-         */
-        public Object getValue() {
-            return this.value;
-        }
-    }
-}
diff --git a/support/src/test/java/tests/util/ForEachRunner.java b/support/src/test/java/tests/util/ForEachRunner.java
deleted file mode 100644
index 2c222b2..0000000
--- a/support/src/test/java/tests/util/ForEachRunner.java
+++ /dev/null
@@ -1,54 +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 tests.util;
-
-/**
- * Runner which executes the provided code under test (via a callback) for each provided input
- * value.
- */
-public final class ForEachRunner {
-
-  /**
-   * Callback parameterized with a value.
-   */
-  public interface Callback<T> {
-    /**
-     * Invokes the callback for the provided value.
-     */
-    void run(T value) throws Exception;
-  }
-
-  private ForEachRunner() {}
-
-  /**
-   * Invokes the provided callback for each of the provided named values.
-   *
-   * @param namesAndValues named values represented as name-value pairs.
-   *
-   * @param <T> type of value.
-   */
-  public static <T> void runNamed(Callback<T> callback, Iterable<Pair<String, T>> namesAndValues)
-      throws Exception {
-    for (Pair<String, T> nameAndValue : namesAndValues) {
-      try {
-        callback.run(nameAndValue.getSecond());
-      } catch (Throwable e) {
-        throw new Exception("Failed for " + nameAndValue.getFirst() + ": " + e.getMessage(), e);
-      }
-    }
-  }
-}
diff --git a/support/src/test/java/tests/util/Pair.java b/support/src/test/java/tests/util/Pair.java
deleted file mode 100644
index 9b0906d..0000000
--- a/support/src/test/java/tests/util/Pair.java
+++ /dev/null
@@ -1,107 +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 tests.util;
-
-/**
- * Pair of typed values.
- *
- * <p>Pairs are obtained using {@link #of(Object, Object) of}.
- *
- * @param <F> type of the first value.
- * @param <S> type of the second value.
- */
-public class Pair<F, S> {
-  private final F mFirst;
-  private final S mSecond;
-
-  private Pair(F first, S second) {
-    mFirst = first;
-    mSecond = second;
-  }
-
-  /**
-   * Gets the pair consisting of the two provided values.
-   *
-   * @param first first value or {@code null}.
-   * @param second second value or {@code null}.
-   */
-  public static <F, S> Pair<F, S> of(F first, S second) {
-    return new Pair<F, S>(first, second);
-  }
-
-  /**
-   * Gets the first value from this pair.
-   *
-   * @return value or {@code null}.
-   */
-  public F getFirst() {
-    return mFirst;
-  }
-
-  /**
-   * Gets the second value from this pair.
-   *
-   * @return value or {@code null}.
-   */
-  public S getSecond() {
-    return mSecond;
-  }
-
-  @Override
-  public String toString() {
-    return "Pair[" + mFirst + ", " + mSecond + "]";
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode());
-    result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode());
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    @SuppressWarnings("rawtypes")
-    Pair other = (Pair) obj;
-    if (mFirst == null) {
-      if (other.mFirst != null) {
-        return false;
-      }
-    } else if (!mFirst.equals(other.mFirst)) {
-      return false;
-    }
-    if (mSecond == null) {
-      if (other.mSecond != null) {
-        return false;
-      }
-    } else if (!mSecond.equals(other.mSecond)) {
-      return false;
-    }
-    return true;
-  }
-}
diff --git a/test-rules/src/main/java/libcore/junit/util/SwitchTargetSdkVersionRule.java b/test-rules/src/main/java/libcore/junit/util/SwitchTargetSdkVersionRule.java
new file mode 100644
index 0000000..455d3cb
--- /dev/null
+++ b/test-rules/src/main/java/libcore/junit/util/SwitchTargetSdkVersionRule.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2019 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.junit.util;
+
+import static org.junit.Assert.fail;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Allows tests to specify the target SDK version that they want to run as.
+ *
+ * <p>To use add the following to the test class. It will only change the behavior of a test method
+ * if it is annotated with {@link TargetSdkVersion}.
+ *
+ * <pre>
+ * &#64;Rule
+ * public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+ * </pre>
+ *
+ * <p>Each test method that needs to run with a specific target SDK version needs to be annotated
+ * with {@link TargetSdkVersion} specifying the required SDK version. e.g.
+ *
+ * <pre>
+ *   &#64;Test
+ *   &#64;TargetSdkVersion(23)
+ *   public void testAsIfTargetedAtSDK23() {
+ *     assertEquals(23, VMRuntime.getRuntime().getTargetSdkVersion());
+ *   }
+ * </pre>
+ *
+ * <p>Within the body of the method the {@code VMRuntime.getTargetSdkVersion()} will be set to the
+ * value specified in the annotation.
+ *
+ * <p>If used on a platform that does not support the {@code dalvik.system.VMRuntime} class then any
+ * test annotated with {@link TargetSdkVersion} will fail with a message explaining that it is not
+ * supported.
+ */
+public abstract class SwitchTargetSdkVersionRule implements TestRule {
+
+  private static final TestRule INSTANCE;
+
+  private static final String VMRUNTIME = "dalvik.system.VMRuntime";
+
+  // Use reflection so that this rule can compile and run against RI core libraries.
+  static {
+    TestRule rule;
+    try {
+      // Assume that VMRuntime is supported and create a rule instance that will use it.
+      rule = new SwitchVMRuntimeUsingReflection();
+    } catch (ClassNotFoundException | NoSuchMethodException e) {
+      // VMRuntime is not supported.
+      rule = new VMRuntimeNotSupported();
+    }
+
+    INSTANCE = rule;
+  }
+
+  public static TestRule getInstance() {
+    return INSTANCE;
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target(ElementType.METHOD)
+  public @interface TargetSdkVersion {
+    int value();
+  }
+
+  private SwitchTargetSdkVersionRule() {
+  }
+
+  @Override
+  public Statement apply(final Statement statement, Description description) {
+    TargetSdkVersion targetSdkVersion = description.getAnnotation(TargetSdkVersion.class);
+    if (targetSdkVersion == null) {
+      return statement;
+    }
+
+    return createStatement(statement, targetSdkVersion.value());
+  }
+
+  /**
+   * Create the {@link Statement} that will be run for the specific {@code targetSdkVersion}.
+   *
+   * @param statement the {@link Statement} encapsulating the test method.
+   * @param targetSdkVersion the target SDK version to use within the body of the test.
+   * @return the created {@link Statement}.
+   */
+  protected abstract Statement createStatement(Statement statement, int targetSdkVersion);
+
+  /**
+   * Switch the value of {@code VMRuntime.getTargetSdkVersion()} for tests annotated with
+   * {@link TargetSdkVersion}.
+   *
+   * <p>Uses reflection so this class can compile and run on OpenJDK.
+   */
+  private static class SwitchVMRuntimeUsingReflection extends SwitchTargetSdkVersionRule {
+
+    private final Method runtimeInstanceGetter;
+    private final Method targetSdkVersionGetter;
+    private final Method targetSdkVersionSetter;
+
+    private SwitchVMRuntimeUsingReflection() throws ClassNotFoundException, NoSuchMethodException {
+      ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+      Class<?> runtimeClass = classLoader.loadClass(VMRUNTIME);
+
+      this.runtimeInstanceGetter = runtimeClass.getMethod("getRuntime");
+      this.targetSdkVersionGetter = runtimeClass.getMethod("getTargetSdkVersion");
+      this.targetSdkVersionSetter = runtimeClass.getMethod("setTargetSdkVersion", int.class);
+    }
+
+    @Override
+    protected Statement createStatement(Statement statement, int targetSdkVersion) {
+      return new Statement() {
+        @Override
+        public void evaluate() throws Throwable {
+          Object runtime = runtimeInstanceGetter.invoke(null);
+          int oldTargetSdkVersion = (int) targetSdkVersionGetter.invoke(runtime);
+          try {
+            targetSdkVersionSetter.invoke(runtime, targetSdkVersion);
+            statement.evaluate();
+          } finally {
+            targetSdkVersionSetter.invoke(runtime, oldTargetSdkVersion);
+          }
+        }
+      };
+    }
+  }
+
+  /**
+   * VMRuntime is not supported on this platform so fail all tests that target a specific SDK
+   * version
+   */
+  private static class VMRuntimeNotSupported extends SwitchTargetSdkVersionRule {
+
+    @Override
+    protected Statement createStatement(Statement statement, int targetSdkVersion) {
+      return new Statement() {
+        @Override
+        public void evaluate() {
+          fail("Targeting SDK version not supported as " + VMRUNTIME + " is not supported");
+        }
+      };
+    }
+  }
+}
diff --git a/test-rules/src/test/java/libcore/junit/util/SwitchTargetSdkVersionRuleTest.java b/test-rules/src/test/java/libcore/junit/util/SwitchTargetSdkVersionRuleTest.java
new file mode 100644
index 0000000..ca15a1e
--- /dev/null
+++ b/test-rules/src/test/java/libcore/junit/util/SwitchTargetSdkVersionRuleTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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.junit.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import dalvik.system.VMRuntime;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link SwitchTargetSdkVersionRule}.
+ */
+@RunWith(JUnit4.class)
+public class SwitchTargetSdkVersionRuleTest {
+
+  @Rule
+  public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
+  @Test
+  @TargetSdkVersion(23)
+  public void testRunningAsIfTargetedAtSDKVersion23() {
+    assertEquals(23, VMRuntime.getRuntime().getTargetSdkVersion());
+  }
+
+  @Test
+  public void testRunningAsIfTargetedAtCurrentSDKVersion() {
+    assertNotEquals(23, VMRuntime.getRuntime().getTargetSdkVersion());
+  }
+}
diff --git a/tools/checkstyle/checkstyle-forbid-apache.xml b/tools/checkstyle/checkstyle-forbid-apache.xml
new file mode 100644
index 0000000..1bdb007
--- /dev/null
+++ b/tools/checkstyle/checkstyle-forbid-apache.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+          "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- Copyright (C) 2019 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.
+-->
+<!-- Ensures that files checked with this checker do not contain Apache
+     license text. This is done by searching for license name preceded by
+     comment asterisk:
+     " * ... Apache License ..."
+-->
+
+<module name="Checker">
+  <property name="fileExtensions" value="java"/>
+
+  <module name="RegexpSingleline">
+    <property name="severity" value="error"/>
+    <property name="format" value="^\W+\*.*Apache License.*$" />
+    <property name="message" value="files MUST NOT have Apache license"/>
+  </module>
+
+</module>
diff --git a/tools/checkstyle/checkstyle-forbid-gpl.xml b/tools/checkstyle/checkstyle-forbid-gpl.xml
new file mode 100644
index 0000000..96ce191
--- /dev/null
+++ b/tools/checkstyle/checkstyle-forbid-gpl.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+          "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- Copyright (C) 2019 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.
+-->
+<!-- Ensures that files checked with this checker do not contain GPL
+     license text. This is done by searching for license name preceded by
+     comment asterisk:
+     " * ... GNU General Public License ..."
+-->
+
+<module name="Checker">
+  <property name="fileExtensions" value="java"/>
+
+  <module name="RegexpSingleline">
+    <property name="severity" value="error"/>
+    <property name="format" value="^\W+\*.*GNU General Public License.*$" />
+    <property name="message" value="files MUST NOT have GPL license"/>
+  </module>
+
+</module>
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index ce5f793..3eb2344 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -1,6 +1,6 @@
 # This file is autogenerated.  See libcore/tools/docs/crypto/README for details.
 {
-  "api_level": "28",
+  "api_level": "29",
   "categories": [
     {
       "algorithms": [
@@ -902,6 +902,10 @@
         {
           "name": "TLSv1.2",
           "supported_api_levels": "16+"
+        },
+        {
+          "name": "TLSv1.3",
+          "supported_api_levels": "29+"
         }
       ],
       "name": "SSLContext"
@@ -969,6 +973,18 @@
           "supported_api_levels": "9-23"
         },
         {
+          "name": "TLS_AES_128_GCM_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_AES_256_GCM_SHA384",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
           "deprecated": "true",
           "name": "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
           "supported_api_levels": "1-8"
@@ -1238,6 +1254,18 @@
           "supported_api_levels": "9-25"
         },
         {
+          "name": "TLS_AES_128_GCM_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_AES_256_GCM_SHA384",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
           "deprecated": "true",
           "name": "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
           "supported_api_levels": "1-8"
@@ -1412,8 +1440,9 @@
           "supported_api_levels": "20+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
@@ -1424,8 +1453,9 @@
           "supported_api_levels": "20+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -1467,8 +1497,9 @@
           "supported_api_levels": "20+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
@@ -1479,8 +1510,9 @@
           "supported_api_levels": "20+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
@@ -1661,8 +1693,9 @@
           "supported_api_levels": "9+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_RSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
@@ -1673,8 +1706,9 @@
           "supported_api_levels": "9+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_RSA_WITH_AES_256_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
@@ -1766,6 +1800,18 @@
           "supported_api_levels": "9-23"
         },
         {
+          "name": "TLS_AES_128_GCM_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_AES_256_GCM_SHA384",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
           "deprecated": "true",
           "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
           "supported_api_levels": "9-22"
@@ -2040,6 +2086,18 @@
           "supported_api_levels": "9-25"
         },
         {
+          "name": "TLS_AES_128_GCM_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_AES_256_GCM_SHA384",
+          "supported_api_levels": "29+"
+        },
+        {
+          "name": "TLS_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "29+"
+        },
+        {
           "deprecated": "true",
           "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
           "supported_api_levels": "9-22"
@@ -2139,8 +2197,9 @@
           "supported_api_levels": "11+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
@@ -2151,8 +2210,9 @@
           "supported_api_levels": "11+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -2194,8 +2254,9 @@
           "supported_api_levels": "11+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
@@ -2206,8 +2267,9 @@
           "supported_api_levels": "11+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
@@ -2373,8 +2435,9 @@
           "supported_api_levels": "9+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_RSA_WITH_AES_128_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
@@ -2385,8 +2448,9 @@
           "supported_api_levels": "9+"
         },
         {
+          "deprecated": "true",
           "name": "TLS_RSA_WITH_AES_256_CBC_SHA256",
-          "supported_api_levels": "20+"
+          "supported_api_levels": "20-28"
         },
         {
           "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
@@ -2743,5 +2807,5 @@
       "name": "TrustManagerFactory"
     }
   ],
-  "last_updated": "2018-02-02 13:58:08 UTC"
+  "last_updated": "2019-01-11 16:02:08 UTC"
 }
\ No newline at end of file
diff --git a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
index ab25382..9b7e5f0 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -16,17 +16,20 @@
 
 package libcore.java.security;
 
-import android.net.PskKeyManager;
+import com.android.org.conscrypt.PSKKeyManager;
 
+import java.net.Socket;
 import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.Security;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 import javax.crypto.Cipher;
 import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
@@ -132,14 +135,16 @@
         }
         // SSLEngine and SSLSocket algorithms are handled outside the default provider system
         SSLContext defaultContext = SSLContext.getDefault();
+        SSLContext tls13Context = SSLContext.getInstance("TLSv1.3");
+        tls13Context.init(null, null, null);
         // PSK cipher suites are only enabled when a PskKeyManager is available, but some other
         // suites are disabled in that case, so check for both
         SSLContext pskContext = SSLContext.getInstance("TLS");
         pskContext.init(
-                new KeyManager[] {new PskKeyManager(){}},
+                new KeyManager[] {new DummyKeyManager()},
                 new TrustManager[0],
                 null);
-        for (SSLContext sslContext : new SSLContext[] {defaultContext, pskContext}) {
+        for (SSLContext sslContext : new SSLContext[] {defaultContext, tls13Context, pskContext}) {
             SSLEngine engine = sslContext.createSSLEngine();
             for (String suite : engine.getSupportedCipherSuites()) {
                 print(sslContext.getProvider(), "SSLEngine.Supported", suite);
@@ -157,4 +162,13 @@
         }
         System.out.println("END ALGORITHM LIST");
     }
+
+    private static class DummyKeyManager implements PSKKeyManager {
+        @Override public String chooseServerKeyIdentityHint(Socket socket) { return null; }
+        @Override public String chooseServerKeyIdentityHint(SSLEngine engine) { return null; }
+        @Override public String chooseClientKeyIdentity(String identityHint, Socket socket) { return null; }
+        @Override public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) { return null; }
+        @Override public SecretKey getKey(String identityHint, String identity, Socket socket) { return null; }
+        @Override public SecretKey getKey(String identityHint, String identity, SSLEngine engine) { return null; }
+    }
 }
\ No newline at end of file
diff --git a/tools/upstream/Android.bp b/tools/upstream/Android.bp
new file mode 100644
index 0000000..dd01c30
--- /dev/null
+++ b/tools/upstream/Android.bp
@@ -0,0 +1,31 @@
+//
+// 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.
+//
+
+//#############################################################
+
+java_library_host {
+    name: "libcore-compare-upstreams",
+    srcs: ["src/main/java/**/*.java"],
+    manifest: "src/main/libcore-compare-upstreams.mf",
+}
+
+//#############################################################
+
+java_library_host {
+    name: "libcore-copy-upstream-files",
+    srcs: ["src/main/java/**/*.java"],
+    manifest: "src/main/libcore-copy-upstream-files.mf",
+}
diff --git a/tools/upstream/Android.mk b/tools/upstream/Android.mk
deleted file mode 100644
index bc56f5d..0000000
--- a/tools/upstream/Android.mk
+++ /dev/null
@@ -1,34 +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.
-#
-LOCAL_PATH := $(call my-dir)
-
-##############################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcore-compare-upstreams
-LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
-LOCAL_JAR_MANIFEST := src/main/libcore-compare-upstreams.mf
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-##############################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcore-copy-upstream-files
-LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
-LOCAL_JAR_MANIFEST := src/main/libcore-copy-upstream-files.mf
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/upstream/src/main/java/libcore/CompareUpstreams.java b/tools/upstream/src/main/java/libcore/CompareUpstreams.java
index fa6bd4f..ca17f67 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;
@@ -63,6 +64,8 @@
  *  To get the 9b113+ upstream, follow the instructions from the commit
  *  message of AOSP libcore commit 29957558cf0db700bfaae360a80c42dc3871d0e5
  *  at https://android-review.googlesource.com/c/304056/
+ *
+ *  To get OpenJDK head: hg clone http://hg.openjdk.java.net/jdk/jdk/ head
  */
 public class CompareUpstreams {
 
@@ -119,45 +122,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 +154,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 +172,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 +195,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 +212,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/com/android/org/kxml2/io/KXmlParser.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
new file mode 100644
index 0000000..3814e63
--- /dev/null
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlParser.java
@@ -0,0 +1,2178 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+// Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
+
+package com.android.org.kxml2.io;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+import libcore.internal.StringPool;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * An XML pull parser with limited support for parsing internal DTDs.
+ */
+public class KXmlParser implements XmlPullParser, Closeable {
+
+    private static final String PROPERTY_XMLDECL_VERSION
+            = "http://xmlpull.org/v1/doc/properties.html#xmldecl-version";
+    private static final String PROPERTY_XMLDECL_STANDALONE
+            = "http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone";
+    private static final String PROPERTY_LOCATION = "http://xmlpull.org/v1/doc/properties.html#location";
+    private static final String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed";
+
+    private static final Map<String, String> DEFAULT_ENTITIES = new HashMap<String, String>();
+    static {
+        DEFAULT_ENTITIES.put("lt", "<");
+        DEFAULT_ENTITIES.put("gt", ">");
+        DEFAULT_ENTITIES.put("amp", "&");
+        DEFAULT_ENTITIES.put("apos", "'");
+        DEFAULT_ENTITIES.put("quot", "\"");
+    }
+
+    private static final int ELEMENTDECL = 11;
+    private static final int ENTITYDECL = 12;
+    private static final int ATTLISTDECL = 13;
+    private static final int NOTATIONDECL = 14;
+    private static final int PARAMETER_ENTITY_REF = 15;
+    private static final char[] START_COMMENT = { '<', '!', '-', '-' };
+    private static final char[] END_COMMENT = { '-', '-', '>' };
+    private static final char[] COMMENT_DOUBLE_DASH = { '-', '-' };
+    private static final char[] START_CDATA = { '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[' };
+    private static final char[] END_CDATA = { ']', ']', '>' };
+    private static final char[] START_PROCESSING_INSTRUCTION = { '<', '?' };
+    private static final char[] END_PROCESSING_INSTRUCTION = { '?', '>' };
+    private static final char[] START_DOCTYPE = { '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E' };
+    private static final char[] SYSTEM = { 'S', 'Y', 'S', 'T', 'E', 'M' };
+    private static final char[] PUBLIC = { 'P', 'U', 'B', 'L', 'I', 'C' };
+    private static final char[] START_ELEMENT = { '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T' };
+    private static final char[] START_ATTLIST = { '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T' };
+    private static final char[] START_ENTITY = { '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y' };
+    private static final char[] START_NOTATION = { '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N' };
+    private static final char[] EMPTY = new char[] { 'E', 'M', 'P', 'T', 'Y' };
+    private static final char[] ANY = new char[]{ 'A', 'N', 'Y' };
+    private static final char[] NDATA = new char[]{ 'N', 'D', 'A', 'T', 'A' };
+    private static final char[] NOTATION = new char[]{ 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N' };
+    private static final char[] REQUIRED = new char[] { 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D' };
+    private static final char[] IMPLIED = new char[] { 'I', 'M', 'P', 'L', 'I', 'E', 'D' };
+    private static final char[] FIXED = new char[] { 'F', 'I', 'X', 'E', 'D' };
+
+    static final private String UNEXPECTED_EOF = "Unexpected EOF";
+    static final private String ILLEGAL_TYPE = "Wrong event type";
+    static final private int XML_DECLARATION = 998;
+
+    // general
+    private String location;
+
+    private String version;
+    private Boolean standalone;
+    private String rootElementName;
+    private String systemId;
+    private String publicId;
+
+    /**
+     * True if the {@code <!DOCTYPE>} contents are handled. The DTD defines
+     * entity values and default attribute values. These values are parsed at
+     * inclusion time and may contain both tags and entity references.
+     *
+     * <p>If this is false, the user must {@link #defineEntityReplacementText
+     * define entity values manually}. Such entity values are literal strings
+     * and will not be parsed. There is no API to define default attributes
+     * manually.
+     */
+    private boolean processDocDecl;
+    private boolean processNsp;
+    private boolean relaxed;
+    private boolean keepNamespaceAttributes;
+
+    /**
+     * If non-null, the contents of the read buffer must be copied into this
+     * string builder before the read buffer is overwritten. This is used to
+     * capture the raw DTD text while parsing the DTD.
+     */
+    private StringBuilder bufferCapture;
+
+    /**
+     * Entities defined in or for this document. This map is created lazily.
+     */
+    private Map<String, char[]> documentEntities;
+
+    /**
+     * Default attributes in this document. The outer map's key is the element
+     * name; the inner map's key is the attribute name. Both keys should be
+     * without namespace adjustments. This map is created lazily.
+     */
+    private Map<String, Map<String, String>> defaultAttributes;
+
+
+    private int depth;
+    private String[] elementStack = new String[16];
+    private String[] nspStack = new String[8];
+    private int[] nspCounts = new int[4];
+
+    // source
+
+    private Reader reader;
+    private String encoding;
+    private ContentSource nextContentSource;
+    private char[] buffer = new char[8192];
+    private int position = 0;
+    private int limit = 0;
+
+    /*
+     * Track the number of newlines and columns preceding the current buffer. To
+     * compute the line and column of a position in the buffer, compute the line
+     * and column in the buffer and add the preceding values.
+     */
+    private int bufferStartLine;
+    private int bufferStartColumn;
+
+    // the current token
+
+    private int type;
+    private boolean isWhitespace;
+    private String namespace;
+    private String prefix;
+    private String name;
+    private String text;
+
+    private boolean degenerated;
+    private int attributeCount;
+
+    // true iff. we've encountered the START_TAG of an XML element at depth == 0;
+    private boolean parsedTopLevelStartTag;
+
+    /*
+     * The current element's attributes arranged in groups of 4:
+     * i + 0 = attribute namespace URI
+     * i + 1 = attribute namespace prefix
+     * i + 2 = attribute qualified name (may contain ":", as in "html:h1")
+     * i + 3 = attribute value
+     */
+    private String[] attributes = new String[16];
+
+    private String error;
+
+    private boolean unresolved;
+
+    public final StringPool stringPool = new StringPool();
+
+    /**
+     * Retains namespace attributes like {@code xmlns="http://foo"} or {@code xmlns:foo="http:foo"}
+     * in pulled elements. Most applications will only be interested in the effective namespaces of
+     * their elements, so these attributes aren't useful. But for structure preserving wrappers like
+     * DOM, it is necessary to keep the namespace data around.
+     */
+    public void keepNamespaceAttributes() {
+        this.keepNamespaceAttributes = true;
+    }
+
+    private boolean adjustNsp() throws XmlPullParserException {
+        boolean any = false;
+
+        for (int i = 0; i < attributeCount << 2; i += 4) {
+            String attrName = attributes[i + 2];
+            int cut = attrName.indexOf(':');
+            String prefix;
+
+            if (cut != -1) {
+                prefix = attrName.substring(0, cut);
+                attrName = attrName.substring(cut + 1);
+            } else if (attrName.equals("xmlns")) {
+                prefix = attrName;
+                attrName = null;
+            } else {
+                continue;
+            }
+
+            if (!prefix.equals("xmlns")) {
+                any = true;
+            } else {
+                int j = (nspCounts[depth]++) << 1;
+
+                nspStack = ensureCapacity(nspStack, j + 2);
+                nspStack[j] = attrName;
+                nspStack[j + 1] = attributes[i + 3];
+
+                if (attrName != null && attributes[i + 3].isEmpty()) {
+                    checkRelaxed("illegal empty namespace");
+                }
+
+                if (keepNamespaceAttributes) {
+                    // explicitly set the namespace for unprefixed attributes
+                    // such as xmlns="http://foo"
+                    attributes[i] = "http://www.w3.org/2000/xmlns/";
+                    any = true;
+                } else {
+                    System.arraycopy(
+                            attributes,
+                            i + 4,
+                            attributes,
+                            i,
+                            ((--attributeCount) << 2) - i);
+
+                    i -= 4;
+                }
+            }
+        }
+
+        if (any) {
+            for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
+
+                String attrName = attributes[i + 2];
+                int cut = attrName.indexOf(':');
+
+                if (cut == 0 && !relaxed) {
+                    throw new RuntimeException(
+                            "illegal attribute name: " + attrName + " at " + this);
+                } else if (cut != -1) {
+                    String attrPrefix = attrName.substring(0, cut);
+
+                    attrName = attrName.substring(cut + 1);
+
+                    String attrNs = getNamespace(attrPrefix);
+
+                    if (attrNs == null && !relaxed) {
+                        throw new RuntimeException(
+                                "Undefined Prefix: " + attrPrefix + " in " + this);
+                    }
+
+                    attributes[i] = attrNs;
+                    attributes[i + 1] = attrPrefix;
+                    attributes[i + 2] = attrName;
+                }
+            }
+        }
+
+        int cut = name.indexOf(':');
+
+        if (cut == 0) {
+            checkRelaxed("illegal tag name: " + name);
+        }
+
+        if (cut != -1) {
+            prefix = name.substring(0, cut);
+            name = name.substring(cut + 1);
+        }
+
+        this.namespace = getNamespace(prefix);
+
+        if (this.namespace == null) {
+            if (prefix != null) {
+                checkRelaxed("undefined prefix: " + prefix);
+            }
+            this.namespace = NO_NAMESPACE;
+        }
+
+        return any;
+    }
+
+    private String[] ensureCapacity(String[] arr, int required) {
+        if (arr.length >= required) {
+            return arr;
+        }
+        String[] bigger = new String[required + 16];
+        System.arraycopy(arr, 0, bigger, 0, arr.length);
+        return bigger;
+    }
+
+    private void checkRelaxed(String errorMessage) throws XmlPullParserException {
+        if (!relaxed) {
+            throw new XmlPullParserException(errorMessage, this, null);
+        }
+        if (error == null) {
+            error = "Error: " + errorMessage;
+        }
+    }
+
+    public int next() throws XmlPullParserException, IOException {
+        return next(false);
+    }
+
+    public int nextToken() throws XmlPullParserException, IOException {
+        return next(true);
+    }
+
+    private int next(boolean justOneToken) throws IOException, XmlPullParserException {
+        if (reader == null) {
+            throw new XmlPullParserException("setInput() must be called first.", this, null);
+        }
+
+        if (type == END_TAG) {
+            depth--;
+        }
+
+        // degenerated needs to be handled before error because of possible
+        // processor expectations(!)
+
+        if (degenerated) {
+            degenerated = false;
+            type = END_TAG;
+            return type;
+        }
+
+        if (error != null) {
+            if (justOneToken) {
+                text = error;
+                type = COMMENT;
+                error = null;
+                return type;
+            } else {
+                error = null;
+            }
+        }
+
+        type = peekType(false);
+
+        if (type == XML_DECLARATION) {
+            readXmlDeclaration();
+            type = peekType(false);
+        }
+
+        text = null;
+        isWhitespace = true;
+        prefix = null;
+        name = null;
+        namespace = null;
+        attributeCount = -1;
+        boolean throwOnResolveFailure = !justOneToken;
+
+        while (true) {
+            switch (type) {
+
+            /*
+             * Return immediately after encountering a start tag, end tag, or
+             * the end of the document.
+             */
+            case START_TAG:
+                parseStartTag(false, throwOnResolveFailure);
+                return type;
+            case END_TAG:
+                readEndTag();
+                return type;
+            case END_DOCUMENT:
+                return type;
+
+            /*
+             * Return after any text token when we're looking for a single
+             * token. Otherwise concatenate all text between tags.
+             */
+            case ENTITY_REF:
+                if (justOneToken) {
+                    StringBuilder entityTextBuilder = new StringBuilder();
+                    readEntity(entityTextBuilder, true, throwOnResolveFailure, ValueContext.TEXT);
+                    text = entityTextBuilder.toString();
+                    break;
+                }
+                // fall-through
+            case TEXT:
+                text = readValue('<', !justOneToken, throwOnResolveFailure, ValueContext.TEXT);
+                if (depth == 0 && isWhitespace) {
+                    type = IGNORABLE_WHITESPACE;
+                }
+                break;
+            case CDSECT:
+                read(START_CDATA);
+                text = readUntil(END_CDATA, true);
+                break;
+
+            /*
+             * Comments, processing instructions and declarations are returned
+             * when we're looking for a single token. Otherwise they're skipped.
+             */
+            case COMMENT:
+                String commentText = readComment(justOneToken);
+                if (justOneToken) {
+                    text = commentText;
+                }
+                break;
+            case PROCESSING_INSTRUCTION:
+                read(START_PROCESSING_INSTRUCTION);
+                String processingInstruction = readUntil(END_PROCESSING_INSTRUCTION, justOneToken);
+                if (justOneToken) {
+                    text = processingInstruction;
+                }
+                break;
+            case DOCDECL:
+                readDoctype(justOneToken);
+                if (parsedTopLevelStartTag) {
+                    throw new XmlPullParserException("Unexpected token", this, null);
+                }
+                break;
+
+            default:
+                throw new XmlPullParserException("Unexpected token", this, null);
+            }
+
+            if (depth == 0 && (type == ENTITY_REF || type == TEXT || type == CDSECT)) {
+                throw new XmlPullParserException("Unexpected token", this, null);
+            }
+
+            if (justOneToken) {
+                return type;
+            }
+
+            if (type == IGNORABLE_WHITESPACE) {
+                text = null;
+            }
+
+            /*
+             * We've read all that we can of a non-empty text block. Always
+             * report this as text, even if it was a CDATA block or entity
+             * reference.
+             */
+            int peek = peekType(false);
+            if (text != null && !text.isEmpty() && peek < TEXT) {
+                type = TEXT;
+                return type;
+            }
+
+            type = peek;
+        }
+    }
+
+    /**
+     * Reads text until the specified delimiter is encountered. Consumes the
+     * text and the delimiter.
+     *
+     * @param returnText true to return the read text excluding the delimiter;
+     *     false to return null.
+     */
+    private String readUntil(char[] delimiter, boolean returnText)
+            throws IOException, XmlPullParserException {
+        int start = position;
+        StringBuilder result = null;
+
+        if (returnText && text != null) {
+            result = new StringBuilder();
+            result.append(text);
+        }
+
+        search:
+        while (true) {
+            if (position + delimiter.length > limit) {
+                if (start < position && returnText) {
+                    if (result == null) {
+                        result = new StringBuilder();
+                    }
+                    result.append(buffer, start, position - start);
+                }
+                if (!fillBuffer(delimiter.length)) {
+                    checkRelaxed(UNEXPECTED_EOF);
+                    type = COMMENT;
+                    return null;
+                }
+                start = position;
+            }
+
+            // TODO: replace with Arrays.equals(buffer, position, delimiter, 0, delimiter.length)
+            // when the VM has better method inlining
+            for (int i = 0; i < delimiter.length; i++) {
+                if (buffer[position + i] != delimiter[i]) {
+                    position++;
+                    continue search;
+                }
+            }
+
+            break;
+        }
+
+        int end = position;
+        position += delimiter.length;
+
+        if (!returnText) {
+            return null;
+        } else if (result == null) {
+            return stringPool.get(buffer, start, end - start);
+        } else {
+            result.append(buffer, start, end - start);
+            return result.toString();
+        }
+    }
+
+    /**
+     * Returns true if an XML declaration was read.
+     */
+    private void readXmlDeclaration() throws IOException, XmlPullParserException {
+        if (bufferStartLine != 0 || bufferStartColumn != 0 || position != 0) {
+            checkRelaxed("processing instructions must not start with xml");
+        }
+
+        read(START_PROCESSING_INSTRUCTION);
+        parseStartTag(true, true);
+
+        if (attributeCount < 1 || !"version".equals(attributes[2])) {
+            checkRelaxed("version expected");
+        }
+
+        version = attributes[3];
+
+        int pos = 1;
+
+        if (pos < attributeCount && "encoding".equals(attributes[2 + 4])) {
+            encoding = attributes[3 + 4];
+            pos++;
+        }
+
+        if (pos < attributeCount && "standalone".equals(attributes[4 * pos + 2])) {
+            String st = attributes[3 + 4 * pos];
+            if ("yes".equals(st)) {
+                standalone = Boolean.TRUE;
+            } else if ("no".equals(st)) {
+                standalone = Boolean.FALSE;
+            } else {
+                checkRelaxed("illegal standalone value: " + st);
+            }
+            pos++;
+        }
+
+        if (pos != attributeCount) {
+            checkRelaxed("unexpected attributes in XML declaration");
+        }
+
+        isWhitespace = true;
+        text = null;
+    }
+
+    private String readComment(boolean returnText) throws IOException, XmlPullParserException {
+        read(START_COMMENT);
+
+        if (relaxed) {
+            return readUntil(END_COMMENT, returnText);
+        }
+
+        String commentText = readUntil(COMMENT_DOUBLE_DASH, returnText);
+        if (peekCharacter() != '>') {
+            throw new XmlPullParserException("Comments may not contain --", this, null);
+        }
+        position++;
+        return commentText;
+    }
+
+    /**
+     * Read the document's DTD. Although this parser is non-validating, the DTD
+     * must be parsed to capture entity values and default attribute values.
+     */
+    private void readDoctype(boolean saveDtdText) throws IOException, XmlPullParserException {
+        read(START_DOCTYPE);
+
+        int startPosition = -1;
+        if (saveDtdText) {
+            bufferCapture = new StringBuilder();
+            startPosition = position;
+        }
+        try {
+            skip();
+            rootElementName = readName();
+            readExternalId(true, true);
+            skip();
+            if (peekCharacter() == '[') {
+                readInternalSubset();
+            }
+            skip();
+        } finally {
+            if (saveDtdText) {
+                bufferCapture.append(buffer, 0, position);
+                bufferCapture.delete(0, startPosition);
+                text = bufferCapture.toString();
+                bufferCapture = null;
+            }
+        }
+
+        read('>');
+        skip();
+    }
+
+    /**
+     * Reads an external ID of one of these two forms:
+     *   SYSTEM "quoted system name"
+     *   PUBLIC "quoted public id" "quoted system name"
+     *
+     * If the system name is not required, this also supports lone public IDs of
+     * this form:
+     *   PUBLIC "quoted public id"
+     *
+     * Returns true if any ID was read.
+     */
+    private boolean readExternalId(boolean requireSystemName, boolean assignFields)
+            throws IOException, XmlPullParserException {
+        skip();
+        int c = peekCharacter();
+
+        if (c == 'S') {
+            read(SYSTEM);
+        } else if (c == 'P') {
+            read(PUBLIC);
+            skip();
+            if (assignFields) {
+                publicId = readQuotedId(true);
+            } else {
+                readQuotedId(false);
+            }
+        } else {
+            return false;
+        }
+
+        skip();
+
+        if (!requireSystemName) {
+            int delimiter = peekCharacter();
+            if (delimiter != '"' && delimiter != '\'') {
+                return true; // no system name!
+            }
+        }
+
+        if (assignFields) {
+            systemId = readQuotedId(true);
+        } else {
+            readQuotedId(false);
+        }
+        return true;
+    }
+
+    private static final char[] SINGLE_QUOTE = new char[] { '\'' };
+    private static final char[] DOUBLE_QUOTE = new char[] { '"' };
+
+    /**
+     * Reads a quoted string, performing no entity escaping of the contents.
+     */
+    private String readQuotedId(boolean returnText) throws IOException, XmlPullParserException {
+        int quote = peekCharacter();
+        char[] delimiter;
+        if (quote == '"') {
+            delimiter = DOUBLE_QUOTE;
+        } else if (quote == '\'') {
+            delimiter = SINGLE_QUOTE;
+        } else {
+            throw new XmlPullParserException("Expected a quoted string", this, null);
+        }
+        position++;
+        return readUntil(delimiter, returnText);
+    }
+
+    private void readInternalSubset() throws IOException, XmlPullParserException {
+        read('[');
+
+        while (true) {
+            skip();
+            if (peekCharacter() == ']') {
+                position++;
+                return;
+            }
+
+            int declarationType = peekType(true);
+            switch (declarationType) {
+            case ELEMENTDECL:
+                readElementDeclaration();
+                break;
+
+            case ATTLISTDECL:
+                readAttributeListDeclaration();
+                break;
+
+            case ENTITYDECL:
+                readEntityDeclaration();
+                break;
+
+            case NOTATIONDECL:
+                readNotationDeclaration();
+                break;
+
+            case PROCESSING_INSTRUCTION:
+                read(START_PROCESSING_INSTRUCTION);
+                readUntil(END_PROCESSING_INSTRUCTION, false);
+                break;
+
+            case COMMENT:
+                readComment(false);
+                break;
+
+            case PARAMETER_ENTITY_REF:
+                throw new XmlPullParserException(
+                        "Parameter entity references are not supported", this, null);
+
+            default:
+                throw new XmlPullParserException("Unexpected token", this, null);
+            }
+        }
+    }
+
+    /**
+     * Read an element declaration. This contains a name and a content spec.
+     *   <!ELEMENT foo EMPTY >
+     *   <!ELEMENT foo (bar?,(baz|quux)) >
+     *   <!ELEMENT foo (#PCDATA|bar)* >
+     */
+    private void readElementDeclaration() throws IOException, XmlPullParserException {
+        read(START_ELEMENT);
+        skip();
+        readName();
+        readContentSpec();
+        skip();
+        read('>');
+    }
+
+    /**
+     * Read an element content spec. This is a regular expression-like pattern
+     * of names or other content specs. The following operators are supported:
+     *   sequence:    (a,b,c)
+     *   choice:      (a|b|c)
+     *   optional:    a?
+     *   one or more: a+
+     *   any number:  a*
+     *
+     * The special name '#PCDATA' is permitted but only if it is the first
+     * element of the first group:
+     *   (#PCDATA|a|b)
+     *
+     * The top-level element must be either a choice, a sequence, or one of the
+     * special names EMPTY and ANY.
+     */
+    private void readContentSpec() throws IOException, XmlPullParserException {
+        // this implementation is very lenient; it scans for balanced parens only
+        skip();
+        int c = peekCharacter();
+        if (c == '(') {
+            int depth = 0;
+            do {
+                if (c == '(') {
+                    depth++;
+                } else if (c == ')') {
+                    depth--;
+                } else if (c == -1) {
+                    throw new XmlPullParserException(
+                            "Unterminated element content spec", this, null);
+                }
+                position++;
+                c = peekCharacter();
+            } while (depth > 0);
+
+            if (c == '*' || c == '?' || c == '+') {
+                position++;
+            }
+        } else if (c == EMPTY[0]) {
+            read(EMPTY);
+        } else if (c == ANY[0]) {
+            read(ANY);
+        } else {
+            throw new XmlPullParserException("Expected element content spec", this, null);
+        }
+    }
+
+    /**
+     * Reads an attribute list declaration such as the following:
+     *   <!ATTLIST foo
+     *       bar CDATA #IMPLIED
+     *       quux (a|b|c) "c"
+     *       baz NOTATION (a|b|c) #FIXED "c">
+     *
+     * Each attribute has a name, type and default.
+     *
+     * Types are one of the built-in types (CDATA, ID, IDREF, IDREFS, ENTITY,
+     * ENTITIES, NMTOKEN, or NMTOKENS), an enumerated type "(list|of|options)"
+     * or NOTATION followed by an enumerated type.
+     *
+     * The default is either #REQUIRED, #IMPLIED, #FIXED, a quoted value, or
+     * #FIXED with a quoted value.
+     */
+    private void readAttributeListDeclaration() throws IOException, XmlPullParserException {
+        read(START_ATTLIST);
+        skip();
+        String elementName = readName();
+
+        while (true) {
+            skip();
+            int c = peekCharacter();
+            if (c == '>') {
+                position++;
+                return;
+            }
+
+            // attribute name
+            String attributeName = readName();
+
+            // attribute type
+            skip();
+            if (position + 1 >= limit && !fillBuffer(2)) {
+                throw new XmlPullParserException("Malformed attribute list", this, null);
+            }
+            if (buffer[position] == NOTATION[0] && buffer[position + 1] == NOTATION[1]) {
+                read(NOTATION);
+                skip();
+            }
+            c = peekCharacter();
+            if (c == '(') {
+                position++;
+                while (true) {
+                    skip();
+                    readName();
+                    skip();
+                    c = peekCharacter();
+                    if (c == ')') {
+                        position++;
+                        break;
+                    } else if (c == '|') {
+                        position++;
+                    } else {
+                        throw new XmlPullParserException("Malformed attribute type", this, null);
+                    }
+                }
+            } else {
+                readName();
+            }
+
+            // default value
+            skip();
+            c = peekCharacter();
+            if (c == '#') {
+                position++;
+                c = peekCharacter();
+                if (c == 'R') {
+                    read(REQUIRED);
+                } else if (c == 'I') {
+                    read(IMPLIED);
+                } else if (c == 'F') {
+                    read(FIXED);
+                } else {
+                    throw new XmlPullParserException("Malformed attribute type", this, null);
+                }
+                skip();
+                c = peekCharacter();
+            }
+            if (c == '"' || c == '\'') {
+                position++;
+                // TODO: does this do escaping correctly?
+                String value = readValue((char) c, true, true, ValueContext.ATTRIBUTE);
+                if (peekCharacter() == c) {
+                    position++;
+                }
+                defineAttributeDefault(elementName, attributeName, value);
+            }
+        }
+    }
+
+    private void defineAttributeDefault(String elementName, String attributeName, String value) {
+        if (defaultAttributes == null) {
+            defaultAttributes = new HashMap<String, Map<String, String>>();
+        }
+        Map<String, String> elementAttributes = defaultAttributes.get(elementName);
+        if (elementAttributes == null) {
+            elementAttributes = new HashMap<String, String>();
+            defaultAttributes.put(elementName, elementAttributes);
+        }
+        elementAttributes.put(attributeName, value);
+    }
+
+    /**
+     * Read an entity declaration. The value of internal entities are inline:
+     *   <!ENTITY foo "bar">
+     *
+     * The values of external entities must be retrieved by URL or path:
+     *   <!ENTITY foo SYSTEM "http://host/file">
+     *   <!ENTITY foo PUBLIC "-//Android//Foo//EN" "http://host/file">
+     *   <!ENTITY foo SYSTEM "../file.png" NDATA png>
+     *
+     * Entities may be general or parameterized. Parameterized entities are
+     * marked by a percent sign. Such entities may only be used in the DTD:
+     *   <!ENTITY % foo "bar">
+     */
+    private void readEntityDeclaration() throws IOException, XmlPullParserException {
+        read(START_ENTITY);
+        boolean generalEntity = true;
+
+        skip();
+        if (peekCharacter() == '%') {
+            generalEntity = false;
+            position++;
+            skip();
+        }
+
+        String name = readName();
+
+        skip();
+        int quote = peekCharacter();
+        String entityValue;
+        if (quote == '"' || quote == '\'') {
+            position++;
+            entityValue = readValue((char) quote, true, false, ValueContext.ENTITY_DECLARATION);
+            if (peekCharacter() == quote) {
+                position++;
+            }
+        } else if (readExternalId(true, false)) {
+            /*
+             * Map external entities to the empty string. This is dishonest,
+             * but it's consistent with Android's Expat pull parser.
+             */
+            entityValue = "";
+            skip();
+            if (peekCharacter() == NDATA[0]) {
+                read(NDATA);
+                skip();
+                readName();
+            }
+        } else {
+            throw new XmlPullParserException("Expected entity value or external ID", this, null);
+        }
+
+        if (generalEntity && processDocDecl) {
+            if (documentEntities == null) {
+                documentEntities = new HashMap<String, char[]>();
+            }
+            documentEntities.put(name, entityValue.toCharArray());
+        }
+
+        skip();
+        read('>');
+    }
+
+    private void readNotationDeclaration() throws IOException, XmlPullParserException {
+        read(START_NOTATION);
+        skip();
+        readName();
+        if (!readExternalId(false, false)) {
+            throw new XmlPullParserException(
+                    "Expected external ID or public ID for notation", this, null);
+        }
+        skip();
+        read('>');
+    }
+
+    private void readEndTag() throws IOException, XmlPullParserException {
+        read('<');
+        read('/');
+        name = readName(); // TODO: pass the expected name in as a hint?
+        skip();
+        read('>');
+
+        int sp = (depth - 1) * 4;
+
+        if (depth == 0) {
+            checkRelaxed("read end tag " + name + " with no tags open");
+            type = COMMENT;
+            return;
+        }
+
+        if (name.equals(elementStack[sp + 3])) {
+            namespace = elementStack[sp];
+            prefix = elementStack[sp + 1];
+            name = elementStack[sp + 2];
+        } else if (!relaxed) {
+            throw new XmlPullParserException(
+                    "expected: /" + elementStack[sp + 3] + " read: " + name, this, null);
+        }
+    }
+
+    /**
+     * Returns the type of the next token.
+     */
+    private int peekType(boolean inDeclaration) throws IOException, XmlPullParserException {
+        if (position >= limit && !fillBuffer(1)) {
+            return END_DOCUMENT;
+        }
+
+        switch (buffer[position]) {
+        case '&':
+            return ENTITY_REF; // &
+        case '<':
+            if (position + 3 >= limit && !fillBuffer(4)) {
+                throw new XmlPullParserException("Dangling <", this, null);
+            }
+
+            switch (buffer[position + 1]) {
+            case '/':
+                return END_TAG; // </
+            case '?':
+                // we're looking for "<?xml " with case insensitivity
+                if ((position + 5 < limit || fillBuffer(6))
+                        && (buffer[position + 2] == 'x' || buffer[position + 2] == 'X')
+                        && (buffer[position + 3] == 'm' || buffer[position + 3] == 'M')
+                        && (buffer[position + 4] == 'l' || buffer[position + 4] == 'L')
+                        && (buffer[position + 5] == ' ')) {
+                    return XML_DECLARATION; // <?xml
+                } else {
+                    return PROCESSING_INSTRUCTION; // <?
+                }
+            case '!':
+                switch (buffer[position + 2]) {
+                case 'D':
+                    return DOCDECL; // <!D
+                case '[':
+                    return CDSECT; // <![
+                case '-':
+                    return COMMENT; // <!-
+                case 'E':
+                    switch (buffer[position + 3]) {
+                    case 'L':
+                        return ELEMENTDECL; // <!EL
+                    case 'N':
+                        return ENTITYDECL; // <!EN
+                    }
+                    break;
+                case 'A':
+                    return ATTLISTDECL;  // <!A
+                case 'N':
+                    return NOTATIONDECL; // <!N
+                }
+                throw new XmlPullParserException("Unexpected <!", this, null);
+            default:
+                return START_TAG; // <
+            }
+        case '%':
+            return inDeclaration ? PARAMETER_ENTITY_REF : TEXT;
+        default:
+            return TEXT;
+        }
+    }
+
+    /**
+     * Sets name and attributes
+     */
+    private void parseStartTag(boolean xmldecl, boolean throwOnResolveFailure)
+            throws IOException, XmlPullParserException {
+        if (!xmldecl) {
+            read('<');
+        }
+        name = readName();
+        attributeCount = 0;
+
+        while (true) {
+            skip();
+
+            if (position >= limit && !fillBuffer(1)) {
+                checkRelaxed(UNEXPECTED_EOF);
+                return;
+            }
+
+            int c = buffer[position];
+
+            if (xmldecl) {
+                if (c == '?') {
+                    position++;
+                    read('>');
+                    return;
+                }
+            } else {
+                if (c == '/') {
+                    degenerated = true;
+                    position++;
+                    skip();
+                    read('>');
+                    break;
+                } else if (c == '>') {
+                    position++;
+                    break;
+                }
+            }
+
+            String attrName = readName();
+
+            int i = (attributeCount++) * 4;
+            attributes = ensureCapacity(attributes, i + 4);
+            attributes[i] = "";
+            attributes[i + 1] = null;
+            attributes[i + 2] = attrName;
+
+            skip();
+            if (position >= limit && !fillBuffer(1)) {
+                checkRelaxed(UNEXPECTED_EOF);
+                return;
+            }
+
+            if (buffer[position] == '=') {
+                position++;
+
+                skip();
+                if (position >= limit && !fillBuffer(1)) {
+                    checkRelaxed(UNEXPECTED_EOF);
+                    return;
+                }
+                char delimiter = buffer[position];
+
+                if (delimiter == '\'' || delimiter == '"') {
+                    position++;
+                } else if (relaxed) {
+                    delimiter = ' ';
+                } else {
+                    throw new XmlPullParserException("attr value delimiter missing!", this, null);
+                }
+
+                attributes[i + 3] = readValue(delimiter, true, throwOnResolveFailure,
+                        ValueContext.ATTRIBUTE);
+
+                if (delimiter != ' ' && peekCharacter() == delimiter) {
+                    position++; // end quote
+                }
+            } else if (relaxed) {
+                attributes[i + 3] = attrName;
+            } else {
+                checkRelaxed("Attr.value missing f. " + attrName);
+                attributes[i + 3] = attrName;
+            }
+        }
+
+        int sp = depth++ * 4;
+        if (depth == 1) {
+            parsedTopLevelStartTag = true;
+        }
+        elementStack = ensureCapacity(elementStack, sp + 4);
+        elementStack[sp + 3] = name;
+
+        if (depth >= nspCounts.length) {
+            int[] bigger = new int[depth + 4];
+            System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
+            nspCounts = bigger;
+        }
+
+        nspCounts[depth] = nspCounts[depth - 1];
+
+        if (processNsp) {
+            adjustNsp();
+        } else {
+            namespace = "";
+        }
+
+        // For consistency with Expat, add default attributes after fixing namespaces.
+        if (defaultAttributes != null) {
+            Map<String, String> elementDefaultAttributes = defaultAttributes.get(name);
+            if (elementDefaultAttributes != null) {
+                for (Map.Entry<String, String> entry : elementDefaultAttributes.entrySet()) {
+                    if (getAttributeValue(null, entry.getKey()) != null) {
+                        continue; // an explicit value overrides the default
+                    }
+
+                    int i = (attributeCount++) * 4;
+                    attributes = ensureCapacity(attributes, i + 4);
+                    attributes[i] = "";
+                    attributes[i + 1] = null;
+                    attributes[i + 2] = entry.getKey();
+                    attributes[i + 3] = entry.getValue();
+                }
+            }
+        }
+
+        elementStack[sp] = namespace;
+        elementStack[sp + 1] = prefix;
+        elementStack[sp + 2] = name;
+    }
+
+    /**
+     * Reads an entity reference from the buffer, resolves it, and writes the
+     * resolved entity to {@code out}. If the entity cannot be read or resolved,
+     * {@code out} will contain the partial entity reference.
+     */
+    private void readEntity(StringBuilder out, boolean isEntityToken, boolean throwOnResolveFailure,
+            ValueContext valueContext) throws IOException, XmlPullParserException {
+        int start = out.length();
+
+        if (buffer[position++] != '&') {
+            throw new AssertionError();
+        }
+
+        out.append('&');
+
+        while (true) {
+            int c = peekCharacter();
+
+            if (c == ';') {
+                out.append(';');
+                position++;
+                break;
+
+            } else if (c >= 128
+                    || (c >= '0' && c <= '9')
+                    || (c >= 'a' && c <= 'z')
+                    || (c >= 'A' && c <= 'Z')
+                    || c == '_'
+                    || c == '-'
+                    || c == '#') {
+                position++;
+                out.append((char) c);
+
+            } else if (relaxed) {
+                // intentionally leave the partial reference in 'out'
+                return;
+
+            } else {
+                throw new XmlPullParserException("unterminated entity ref", this, null);
+            }
+        }
+
+        String code = out.substring(start + 1, out.length() - 1);
+
+        if (isEntityToken) {
+            name = code;
+        }
+
+        if (code.startsWith("#")) {
+            try {
+                int c = code.startsWith("#x")
+                        ? Integer.parseInt(code.substring(2), 16)
+                        : Integer.parseInt(code.substring(1));
+                out.delete(start, out.length());
+                out.appendCodePoint(c);
+                unresolved = false;
+                return;
+            } catch (NumberFormatException notANumber) {
+                throw new XmlPullParserException("Invalid character reference: &" + code);
+            } catch (IllegalArgumentException invalidCodePoint) {
+                throw new XmlPullParserException("Invalid character reference: &" + code);
+            }
+        }
+
+        if (valueContext == ValueContext.ENTITY_DECLARATION) {
+            // keep the unresolved &code; in the text to resolve later
+            return;
+        }
+
+        String defaultEntity = DEFAULT_ENTITIES.get(code);
+        if (defaultEntity != null) {
+            out.delete(start, out.length());
+            unresolved = false;
+            out.append(defaultEntity);
+            return;
+        }
+
+        char[] resolved;
+        if (documentEntities != null && (resolved = documentEntities.get(code)) != null) {
+            out.delete(start, out.length());
+            unresolved = false;
+            if (processDocDecl) {
+                pushContentSource(resolved); // parse the entity as XML
+            } else {
+                out.append(resolved); // include the entity value as text
+            }
+            return;
+        }
+
+        /*
+         * The parser skipped an external DTD, and now we've encountered an
+         * unknown entity that could have been declared there. Map it to the
+         * empty string. This is dishonest, but it's consistent with Android's
+         * old ExpatPullParser.
+         */
+        if (systemId != null) {
+            out.delete(start, out.length());
+            return;
+        }
+
+        // keep the unresolved entity "&code;" in the text for relaxed clients
+        unresolved = true;
+        if (throwOnResolveFailure) {
+            checkRelaxed("unresolved: &" + code + ";");
+        }
+    }
+
+    /**
+     * Where a value is found impacts how that value is interpreted. For
+     * example, in attributes, "\n" must be replaced with a space character. In
+     * text, "]]>" is forbidden. In entity declarations, named references are
+     * not resolved.
+     */
+    enum ValueContext {
+        ATTRIBUTE,
+        TEXT,
+        ENTITY_DECLARATION
+    }
+
+    /**
+     * Returns the current text or attribute value. This also has the side
+     * effect of setting isWhitespace to false if a non-whitespace character is
+     * encountered.
+     *
+     * @param delimiter {@code <} for text, {@code "} and {@code '} for quoted
+     *     attributes, or a space for unquoted attributes.
+     */
+    private String readValue(char delimiter, boolean resolveEntities, boolean throwOnResolveFailure,
+            ValueContext valueContext) throws IOException, XmlPullParserException {
+
+        /*
+         * This method returns all of the characters from the current position
+         * through to an appropriate delimiter.
+         *
+         * If we're lucky (which we usually are), we'll return a single slice of
+         * the buffer. This fast path avoids allocating a string builder.
+         *
+         * There are 6 unlucky characters we could encounter:
+         *  - "&":  entities must be resolved.
+         *  - "%":  parameter entities are unsupported in entity values.
+         *  - "<":  this isn't permitted in attributes unless relaxed.
+         *  - "]":  this requires a lookahead to defend against the forbidden
+         *          CDATA section delimiter "]]>".
+         *  - "\r": If a "\r" is followed by a "\n", we discard the "\r". If it
+         *          isn't followed by "\n", we replace "\r" with either a "\n"
+         *          in text nodes or a space in attribute values.
+         *  - "\n": In attribute values, "\n" must be replaced with a space.
+         *
+         * We could also get unlucky by needing to refill the buffer midway
+         * through the text.
+         */
+
+        int start = position;
+        StringBuilder result = null;
+
+        // if a text section was already started, prefix the start
+        if (valueContext == ValueContext.TEXT && text != null) {
+            result = new StringBuilder();
+            result.append(text);
+        }
+
+        while (true) {
+
+            /*
+             * Make sure we have at least a single character to read from the
+             * buffer. This mutates the buffer, so save the partial result
+             * to the slow path string builder first.
+             */
+            if (position >= limit) {
+                if (start < position) {
+                    if (result == null) {
+                        result = new StringBuilder();
+                    }
+                    result.append(buffer, start, position - start);
+                }
+                if (!fillBuffer(1)) {
+                    return result != null ? result.toString() : "";
+                }
+                start = position;
+            }
+
+            char c = buffer[position];
+
+            if (c == delimiter
+                    || (delimiter == ' ' && (c <= ' ' || c == '>'))
+                    || c == '&' && !resolveEntities) {
+                break;
+            }
+
+            if (c != '\r'
+                    && (c != '\n' || valueContext != ValueContext.ATTRIBUTE)
+                    && c != '&'
+                    && c != '<'
+                    && (c != ']' || valueContext != ValueContext.TEXT)
+                    && (c != '%' || valueContext != ValueContext.ENTITY_DECLARATION)) {
+                isWhitespace &= (c <= ' ');
+                position++;
+                continue;
+            }
+
+            /*
+             * We've encountered an unlucky character! Convert from fast
+             * path to slow path if we haven't done so already.
+             */
+            if (result == null) {
+                result = new StringBuilder();
+            }
+            result.append(buffer, start, position - start);
+
+            if (c == '\r') {
+                if ((position + 1 < limit || fillBuffer(2)) && buffer[position + 1] == '\n') {
+                    position++;
+                }
+                c = (valueContext == ValueContext.ATTRIBUTE) ? ' ' : '\n';
+
+            } else if (c == '\n') {
+                c = ' ';
+
+            } else if (c == '&') {
+                isWhitespace = false; // TODO: what if the entity resolves to whitespace?
+                readEntity(result, false, throwOnResolveFailure, valueContext);
+                start = position;
+                continue;
+
+            } else if (c == '<') {
+                if (valueContext == ValueContext.ATTRIBUTE) {
+                    checkRelaxed("Illegal: \"<\" inside attribute value");
+                }
+                isWhitespace = false;
+
+            } else if (c == ']') {
+                if ((position + 2 < limit || fillBuffer(3))
+                        && buffer[position + 1] == ']' && buffer[position + 2] == '>') {
+                    checkRelaxed("Illegal: \"]]>\" outside CDATA section");
+                }
+                isWhitespace = false;
+
+            } else if (c == '%') {
+                throw new XmlPullParserException("This parser doesn't support parameter entities",
+                        this, null);
+
+            } else {
+                throw new AssertionError();
+            }
+
+            position++;
+            result.append(c);
+            start = position;
+        }
+
+        if (result == null) {
+            return stringPool.get(buffer, start, position - start);
+        } else {
+            result.append(buffer, start, position - start);
+            return result.toString();
+        }
+    }
+
+    private void read(char expected) throws IOException, XmlPullParserException {
+        int c = peekCharacter();
+        if (c != expected) {
+            checkRelaxed("expected: '" + expected + "' actual: '" + ((char) c) + "'");
+            if (c == -1) {
+                return; // On EOF, don't move position beyond limit
+            }
+        }
+        position++;
+    }
+
+    private void read(char[] chars) throws IOException, XmlPullParserException {
+        if (position + chars.length > limit && !fillBuffer(chars.length)) {
+            checkRelaxed("expected: '" + new String(chars) + "' but was EOF");
+            return;
+        }
+
+        // TODO: replace with Arrays.equals(buffer, position, delimiter, 0, delimiter.length)
+        // when the VM has better method inlining
+        for (int i = 0; i < chars.length; i++) {
+            if (buffer[position + i] != chars[i]) {
+                checkRelaxed("expected: \"" + new String(chars) + "\" but was \""
+                        + new String(buffer, position, chars.length) + "...\"");
+            }
+        }
+
+        position += chars.length;
+    }
+
+    private int peekCharacter() throws IOException, XmlPullParserException {
+        if (position < limit || fillBuffer(1)) {
+            return buffer[position];
+        }
+        return -1;
+    }
+
+    /**
+     * Returns true once {@code limit - position >= minimum}. If the data is
+     * exhausted before that many characters are available, this returns
+     * false.
+     */
+    private boolean fillBuffer(int minimum) throws IOException, XmlPullParserException {
+        // If we've exhausted the current content source, remove it
+        while (nextContentSource != null) {
+            if (position < limit) {
+                throw new XmlPullParserException("Unbalanced entity!", this, null);
+            }
+            popContentSource();
+            if (limit - position >= minimum) {
+                return true;
+            }
+        }
+
+        // Before clobbering the old characters, update where buffer starts
+        for (int i = 0; i < position; i++) {
+            if (buffer[i] == '\n') {
+                bufferStartLine++;
+                bufferStartColumn = 0;
+            } else {
+                bufferStartColumn++;
+            }
+        }
+
+        if (bufferCapture != null) {
+            bufferCapture.append(buffer, 0, position);
+        }
+
+        if (limit != position) {
+            limit -= position;
+            System.arraycopy(buffer, position, buffer, 0, limit);
+        } else {
+            limit = 0;
+        }
+
+        position = 0;
+        int total;
+        while ((total = reader.read(buffer, limit, buffer.length - limit)) != -1) {
+            limit += total;
+            if (limit >= minimum) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns an element or attribute name. This is always non-empty for
+     * non-relaxed parsers.
+     */
+    private String readName() throws IOException, XmlPullParserException {
+        if (position >= limit && !fillBuffer(1)) {
+            checkRelaxed("name expected");
+            return "";
+        }
+
+        int start = position;
+        StringBuilder result = null;
+
+        // read the first character
+        char c = buffer[position];
+        if ((c >= 'a' && c <= 'z')
+                || (c >= 'A' && c <= 'Z')
+                || c == '_'
+                || c == ':'
+                || c >= '\u00c0' // TODO: check the XML spec
+                || relaxed) {
+            position++;
+        } else {
+            checkRelaxed("name expected");
+            return "";
+        }
+
+        while (true) {
+            /*
+             * Make sure we have at least a single character to read from the
+             * buffer. This mutates the buffer, so save the partial result
+             * to the slow path string builder first.
+             */
+            if (position >= limit) {
+                if (result == null) {
+                    result = new StringBuilder();
+                }
+                result.append(buffer, start, position - start);
+                if (!fillBuffer(1)) {
+                    return result.toString();
+                }
+                start = position;
+            }
+
+            // read another character
+            c = buffer[position];
+            if ((c >= 'a' && c <= 'z')
+                    || (c >= 'A' && c <= 'Z')
+                    || (c >= '0' && c <= '9')
+                    || c == '_'
+                    || c == '-'
+                    || c == ':'
+                    || c == '.'
+                    || c >= '\u00b7') {  // TODO: check the XML spec
+                position++;
+                continue;
+            }
+
+            // we encountered a non-name character. done!
+            if (result == null) {
+                return stringPool.get(buffer, start, position - start);
+            } else {
+                result.append(buffer, start, position - start);
+                return result.toString();
+            }
+        }
+    }
+
+    private void skip() throws IOException, XmlPullParserException {
+        while (position < limit || fillBuffer(1)) {
+            int c = buffer[position];
+            if (c > ' ') {
+                break;
+            }
+            position++;
+        }
+    }
+
+    //  public part starts here...
+
+    public void setInput(Reader reader) throws XmlPullParserException {
+        this.reader = reader;
+
+        type = START_DOCUMENT;
+        parsedTopLevelStartTag = false;
+        name = null;
+        namespace = null;
+        degenerated = false;
+        attributeCount = -1;
+        encoding = null;
+        version = null;
+        standalone = null;
+
+        if (reader == null) {
+            return;
+        }
+
+        position = 0;
+        limit = 0;
+        bufferStartLine = 0;
+        bufferStartColumn = 0;
+        depth = 0;
+        documentEntities = null;
+    }
+
+    public void setInput(InputStream is, String charset) throws XmlPullParserException {
+        position = 0;
+        limit = 0;
+        boolean detectCharset = (charset == null);
+
+        if (is == null) {
+            throw new IllegalArgumentException("is == null");
+        }
+
+        try {
+            if (detectCharset) {
+                // read the four bytes looking for an indication of the encoding in use
+                int firstFourBytes = 0;
+                while (limit < 4) {
+                    int i = is.read();
+                    if (i == -1) {
+                        break;
+                    }
+                    firstFourBytes = (firstFourBytes << 8) | i;
+                    buffer[limit++] = (char) i;
+                }
+
+                if (limit == 4) {
+                    switch (firstFourBytes) {
+                    case 0x00000FEFF: // UTF-32BE BOM
+                        charset = "UTF-32BE";
+                        limit = 0;
+                        break;
+
+                    case 0x0FFFE0000: // UTF-32LE BOM
+                        charset = "UTF-32LE";
+                        limit = 0;
+                        break;
+
+                    case 0x0000003c: // '<' in UTF-32BE
+                        charset = "UTF-32BE";
+                        buffer[0] = '<';
+                        limit = 1;
+                        break;
+
+                    case 0x03c000000: // '<' in UTF-32LE
+                        charset = "UTF-32LE";
+                        buffer[0] = '<';
+                        limit = 1;
+                        break;
+
+                    case 0x0003c003f: // "<?" in UTF-16BE
+                        charset = "UTF-16BE";
+                        buffer[0] = '<';
+                        buffer[1] = '?';
+                        limit = 2;
+                        break;
+
+                    case 0x03c003f00: // "<?" in UTF-16LE
+                        charset = "UTF-16LE";
+                        buffer[0] = '<';
+                        buffer[1] = '?';
+                        limit = 2;
+                        break;
+
+                    case 0x03c3f786d: // "<?xm" in ASCII etc.
+                        while (true) {
+                            int i = is.read();
+                            if (i == -1) {
+                                break;
+                            }
+                            buffer[limit++] = (char) i;
+                            if (i == '>') {
+                                String s = new String(buffer, 0, limit);
+                                int i0 = s.indexOf("encoding");
+                                if (i0 != -1) {
+                                    while (s.charAt(i0) != '"' && s.charAt(i0) != '\'') {
+                                        i0++;
+                                    }
+                                    char deli = s.charAt(i0++);
+                                    int i1 = s.indexOf(deli, i0);
+                                    charset = s.substring(i0, i1);
+                                }
+                                break;
+                            }
+                        }
+                        break;
+
+                    default:
+                        // handle a byte order mark followed by something other than <?
+                        if ((firstFourBytes & 0x0ffff0000) == 0x0feff0000) {
+                            charset = "UTF-16BE";
+                            buffer[0] = (char) ((buffer[2] << 8) | buffer[3]);
+                            limit = 1;
+                        } else if ((firstFourBytes & 0x0ffff0000) == 0x0fffe0000) {
+                            charset = "UTF-16LE";
+                            buffer[0] = (char) ((buffer[3] << 8) | buffer[2]);
+                            limit = 1;
+                        } else if ((firstFourBytes & 0x0ffffff00) == 0x0efbbbf00) {
+                            charset = "UTF-8";
+                            buffer[0] = buffer[3];
+                            limit = 1;
+                        }
+                    }
+                }
+            }
+
+            if (charset == null) {
+                charset = "UTF-8";
+            }
+
+            int savedLimit = limit;
+            setInput(new InputStreamReader(is, charset));
+            encoding = charset;
+            limit = savedLimit;
+
+            /*
+             * Skip the optional BOM if we didn't above. This decrements limit
+             * rather than incrementing position so that <?xml version='1.0'?>
+             * is still at character 0.
+             */
+            if (!detectCharset && peekCharacter() == 0xfeff) {
+                limit--;
+                System.arraycopy(buffer, 1, buffer, 0, limit);
+            }
+        } catch (Exception e) {
+            throw new XmlPullParserException("Invalid stream or encoding: " + e, this, e);
+        }
+    }
+
+    public void close() throws IOException {
+        if (reader != null) {
+            reader.close();
+        }
+    }
+
+    public boolean getFeature(String feature) {
+        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature)) {
+            return processNsp;
+        } else if (FEATURE_RELAXED.equals(feature)) {
+            return relaxed;
+        } else if (FEATURE_PROCESS_DOCDECL.equals(feature)) {
+            return processDocDecl;
+        } else {
+            return false;
+        }
+    }
+
+    public String getInputEncoding() {
+        return encoding;
+    }
+
+    public void defineEntityReplacementText(String entity, String value)
+            throws XmlPullParserException {
+        if (processDocDecl) {
+            throw new IllegalStateException(
+                    "Entity replacement text may not be defined with DOCTYPE processing enabled.");
+        }
+        if (reader == null) {
+            throw new IllegalStateException(
+                    "Entity replacement text must be defined after setInput()");
+        }
+        if (documentEntities == null) {
+            documentEntities = new HashMap<String, char[]>();
+        }
+        documentEntities.put(entity, value.toCharArray());
+    }
+
+    public Object getProperty(String property) {
+        if (property.equals(PROPERTY_XMLDECL_VERSION)) {
+            return version;
+        } else if (property.equals(PROPERTY_XMLDECL_STANDALONE)) {
+            return standalone;
+        } else if (property.equals(PROPERTY_LOCATION)) {
+            return location != null ? location : reader.toString();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the root element's name if it was declared in the DTD. This
+     * equals the first tag's name for valid documents.
+     */
+    public String getRootElementName() {
+        return rootElementName;
+    }
+
+    /**
+     * Returns the document's system ID if it was declared. This is typically a
+     * string like {@code http://www.w3.org/TR/html4/strict.dtd}.
+     */
+    public String getSystemId() {
+        return systemId;
+    }
+
+    /**
+     * Returns the document's public ID if it was declared. This is typically a
+     * string like {@code -//W3C//DTD HTML 4.01//EN}.
+     */
+    public String getPublicId() {
+        return publicId;
+    }
+
+    public int getNamespaceCount(int depth) {
+        if (depth > this.depth) {
+            throw new IndexOutOfBoundsException();
+        }
+        return nspCounts[depth];
+    }
+
+    public String getNamespacePrefix(int pos) {
+        return nspStack[pos * 2];
+    }
+
+    public String getNamespaceUri(int pos) {
+        return nspStack[(pos * 2) + 1];
+    }
+
+    public String getNamespace(String prefix) {
+        if ("xml".equals(prefix)) {
+            return "http://www.w3.org/XML/1998/namespace";
+        }
+        if ("xmlns".equals(prefix)) {
+            return "http://www.w3.org/2000/xmlns/";
+        }
+
+        for (int i = (getNamespaceCount(depth) << 1) - 2; i >= 0; i -= 2) {
+            if (prefix == null) {
+                if (nspStack[i] == null) {
+                    return nspStack[i + 1];
+                }
+            } else if (prefix.equals(nspStack[i])) {
+                return nspStack[i + 1];
+            }
+        }
+        return null;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
+    public String getPositionDescription() {
+        StringBuilder buf = new StringBuilder(type < TYPES.length ? TYPES[type] : "unknown");
+        buf.append(' ');
+
+        if (type == START_TAG || type == END_TAG) {
+            if (degenerated) {
+                buf.append("(empty) ");
+            }
+            buf.append('<');
+            if (type == END_TAG) {
+                buf.append('/');
+            }
+
+            if (prefix != null) {
+                buf.append("{" + namespace + "}" + prefix + ":");
+            }
+            buf.append(name);
+
+            int cnt = attributeCount * 4;
+            for (int i = 0; i < cnt; i += 4) {
+                buf.append(' ');
+                if (attributes[i + 1] != null) {
+                    buf.append("{" + attributes[i] + "}" + attributes[i + 1] + ":");
+                }
+                buf.append(attributes[i + 2] + "='" + attributes[i + 3] + "'");
+            }
+
+            buf.append('>');
+        } else if (type == IGNORABLE_WHITESPACE) {
+            ;
+        } else if (type != TEXT) {
+            buf.append(getText());
+        } else if (isWhitespace) {
+            buf.append("(whitespace)");
+        } else {
+            String text = getText();
+            if (text.length() > 16) {
+                text = text.substring(0, 16) + "...";
+            }
+            buf.append(text);
+        }
+
+        buf.append("@" + getLineNumber() + ":" + getColumnNumber());
+        if (location != null) {
+            buf.append(" in ");
+            buf.append(location);
+        } else if (reader != null) {
+            buf.append(" in ");
+            buf.append(reader.toString());
+        }
+        return buf.toString();
+    }
+
+    public int getLineNumber() {
+        int result = bufferStartLine;
+        for (int i = 0; i < position; i++) {
+            if (buffer[i] == '\n') {
+                result++;
+            }
+        }
+        return result + 1; // the first line is '1'
+    }
+
+    public int getColumnNumber() {
+        int result = bufferStartColumn;
+        for (int i = 0; i < position; i++) {
+            if (buffer[i] == '\n') {
+                result = 0;
+            } else {
+                result++;
+            }
+        }
+        return result + 1; // the first column is '1'
+    }
+
+    public boolean isWhitespace() throws XmlPullParserException {
+        if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT) {
+            throw new XmlPullParserException(ILLEGAL_TYPE, this, null);
+        }
+        return isWhitespace;
+    }
+
+    public String getText() {
+        if (type < TEXT || (type == ENTITY_REF && unresolved)) {
+            return null;
+        } else if (text == null) {
+            return "";
+        } else {
+            return text;
+        }
+    }
+
+    public char[] getTextCharacters(int[] poslen) {
+        String text = getText();
+        if (text == null) {
+            poslen[0] = -1;
+            poslen[1] = -1;
+            return null;
+        }
+        char[] result = text.toCharArray();
+        poslen[0] = 0;
+        poslen[1] = result.length;
+        return result;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public boolean isEmptyElementTag() throws XmlPullParserException {
+        if (type != START_TAG) {
+            throw new XmlPullParserException(ILLEGAL_TYPE, this, null);
+        }
+        return degenerated;
+    }
+
+    public int getAttributeCount() {
+        return attributeCount;
+    }
+
+    public String getAttributeType(int index) {
+        return "CDATA";
+    }
+
+    public boolean isAttributeDefault(int index) {
+        return false;
+    }
+
+    public String getAttributeNamespace(int index) {
+        if (index >= attributeCount) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes[index * 4];
+    }
+
+    public String getAttributeName(int index) {
+        if (index >= attributeCount) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes[(index * 4) + 2];
+    }
+
+    public String getAttributePrefix(int index) {
+        if (index >= attributeCount) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes[(index * 4) + 1];
+    }
+
+    public String getAttributeValue(int index) {
+        if (index >= attributeCount) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes[(index * 4) + 3];
+    }
+
+    public String getAttributeValue(String namespace, String name) {
+        for (int i = (attributeCount * 4) - 4; i >= 0; i -= 4) {
+            if (attributes[i + 2].equals(name)
+                    && (namespace == null || attributes[i].equals(namespace))) {
+                return attributes[i + 3];
+            }
+        }
+
+        return null;
+    }
+
+    public int getEventType() throws XmlPullParserException {
+        return type;
+    }
+
+    // utility methods to make XML parsing easier ...
+
+    public int nextTag() throws XmlPullParserException, IOException {
+        next();
+        if (type == TEXT && isWhitespace) {
+            next();
+        }
+
+        if (type != END_TAG && type != START_TAG) {
+            throw new XmlPullParserException("unexpected type", this, null);
+        }
+
+        return type;
+    }
+
+    public void require(int type, String namespace, String name)
+            throws XmlPullParserException, IOException {
+        if (type != this.type
+                || (namespace != null && !namespace.equals(getNamespace()))
+                || (name != null && !name.equals(getName()))) {
+            throw new XmlPullParserException(
+                    "expected: " + TYPES[type] + " {" + namespace + "}" + name, this, null);
+        }
+    }
+
+    public String nextText() throws XmlPullParserException, IOException {
+        if (type != START_TAG) {
+            throw new XmlPullParserException("precondition: START_TAG", this, null);
+        }
+
+        next();
+
+        String result;
+        if (type == TEXT) {
+            result = getText();
+            next();
+        } else {
+            result = "";
+        }
+
+        if (type != END_TAG) {
+            throw new XmlPullParserException("END_TAG expected", this, null);
+        }
+
+        return result;
+    }
+
+    public void setFeature(String feature, boolean value) throws XmlPullParserException {
+        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature)) {
+            processNsp = value;
+        } else if (XmlPullParser.FEATURE_PROCESS_DOCDECL.equals(feature)) {
+            processDocDecl = value;
+        } else if (FEATURE_RELAXED.equals(feature)) {
+            relaxed = value;
+        } else {
+            throw new XmlPullParserException("unsupported feature: " + feature, this, null);
+        }
+    }
+
+    public void setProperty(String property, Object value) throws XmlPullParserException {
+        if (property.equals(PROPERTY_LOCATION)) {
+            location = String.valueOf(value);
+        } else {
+            throw new XmlPullParserException("unsupported property: " + property);
+        }
+    }
+
+    /**
+     * A chain of buffers containing XML content. Each content source contains
+     * the parser's primary read buffer or the characters of entities actively
+     * being parsed.
+     *
+     * <p>For example, note the buffers needed to parse this document:
+     * <pre>   {@code
+     *   <!DOCTYPE foo [
+     *       <!ENTITY baz "ghi">
+     *       <!ENTITY bar "def &baz; jkl">
+     *   ]>
+     *   <foo>abc &bar; mno</foo>
+     * }</pre>
+     *
+     * <p>Things get interesting when the bar entity is encountered. At that
+     * point two buffers are active:
+     * <ol>
+     * <li>The value for the bar entity, containing {@code "def &baz; jkl"}
+     * <li>The parser's primary read buffer, containing {@code " mno</foo>"}
+     * </ol>
+     * <p>The parser will return the characters {@code "def "} from the bar
+     * entity's buffer, and then it will encounter the baz entity. To handle
+     * that, three buffers will be active:
+     * <ol>
+     * <li>The value for the baz entity, containing {@code "ghi"}
+     * <li>The remaining value for the bar entity, containing {@code " jkl"}
+     * <li>The parser's primary read buffer, containing {@code " mno</foo>"}
+     * </ol>
+     * <p>The parser will then return the characters {@code ghi jkl mno} in that
+     * sequence by reading each buffer in sequence.
+     */
+    static class ContentSource {
+        private final ContentSource next;
+        private final char[] buffer;
+        private final int position;
+        private final int limit;
+        ContentSource(ContentSource next, char[] buffer, int position, int limit) {
+            this.next = next;
+            this.buffer = buffer;
+            this.position = position;
+            this.limit = limit;
+        }
+    }
+
+    /**
+     * Prepends the characters of {@code newBuffer} to be read before the
+     * current buffer.
+     */
+    private void pushContentSource(char[] newBuffer) {
+        nextContentSource = new ContentSource(nextContentSource, buffer, position, limit);
+        buffer = newBuffer;
+        position = 0;
+        limit = newBuffer.length;
+    }
+
+    /**
+     * Replaces the current exhausted buffer with the next buffer in the chain.
+     */
+    private void popContentSource() {
+        buffer = nextContentSource.buffer;
+        position = nextContentSource.position;
+        limit = nextContentSource.limit;
+        nextContentSource = nextContentSource.next;
+    }
+}
diff --git a/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
new file mode 100644
index 0000000..795448d
--- /dev/null
+++ b/xml/src/main/java/com/android/org/kxml2/io/KXmlSerializer.java
@@ -0,0 +1,630 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+
+package com.android.org.kxml2.io;
+
+import java.io.*;
+import java.util.Locale;
+import org.xmlpull.v1.*;
+
+public class KXmlSerializer implements XmlSerializer {
+
+    private static final int BUFFER_LEN = 8192;
+    private final char[] mText = new char[BUFFER_LEN];
+    private int mPos;
+
+    //    static final String UNDEFINED = ":";
+
+    private Writer writer;
+
+    private boolean pending;
+    private int auto;
+    private int depth;
+
+    private String[] elementStack = new String[12];
+    //nsp/prefix/name
+    private int[] nspCounts = new int[4];
+    private String[] nspStack = new String[8];
+    //prefix/nsp; both empty are ""
+    private boolean[] indent = new boolean[4];
+    private boolean unicode;
+    private String encoding;
+
+    private void append(char c) throws IOException {
+        if (mPos >= BUFFER_LEN) {
+            flushBuffer();
+        }
+        mText[mPos++] = c;
+    }
+
+    private void append(String str, int i, int length) throws IOException {
+        while (length > 0) {
+            if (mPos == BUFFER_LEN) {
+                flushBuffer();
+            }
+            int batch = BUFFER_LEN - mPos;
+            if (batch > length) {
+                batch = length;
+            }
+            str.getChars(i, i + batch, mText, mPos);
+            i += batch;
+            length -= batch;
+            mPos += batch;
+        }
+    }
+
+    private void append(String str) throws IOException {
+        append(str, 0, str.length());
+    }
+
+    private final void flushBuffer() throws IOException {
+        if(mPos > 0) {
+            writer.write(mText, 0, mPos);
+            writer.flush();
+            mPos = 0;
+        }
+    }
+
+    private final void check(boolean close) throws IOException {
+        if (!pending)
+            return;
+
+        depth++;
+        pending = false;
+
+        if (indent.length <= depth) {
+            boolean[] hlp = new boolean[depth + 4];
+            System.arraycopy(indent, 0, hlp, 0, depth);
+            indent = hlp;
+        }
+        indent[depth] = indent[depth - 1];
+
+        for (int i = nspCounts[depth - 1]; i < nspCounts[depth]; i++) {
+            append(" xmlns");
+            if (!nspStack[i * 2].isEmpty()) {
+                append(':');
+                append(nspStack[i * 2]);
+            }
+            else if (getNamespace().isEmpty() && !nspStack[i * 2 + 1].isEmpty())
+                throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+            append("=\"");
+            writeEscaped(nspStack[i * 2 + 1], '"');
+            append('"');
+        }
+
+        if (nspCounts.length <= depth + 1) {
+            int[] hlp = new int[depth + 8];
+            System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
+            nspCounts = hlp;
+        }
+
+        nspCounts[depth + 1] = nspCounts[depth];
+        //   nspCounts[depth + 2] = nspCounts[depth];
+
+        if (close) {
+            append(" />");
+        } else {
+            append('>');
+        }
+    }
+
+    private final void writeEscaped(String s, int quot) throws IOException {
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '\n':
+                case '\r':
+                case '\t':
+                    if(quot == -1)
+                        append(c);
+                    else
+                        append("&#"+((int) c)+';');
+                    break;
+                case '&' :
+                    append("&amp;");
+                    break;
+                case '>' :
+                    append("&gt;");
+                    break;
+                case '<' :
+                    append("&lt;");
+                    break;
+                default:
+                    if (c == quot) {
+                        append(c == '"' ? "&quot;" : "&apos;");
+                        break;
+                    }
+                    // BEGIN Android-changed: refuse to output invalid characters
+                    // See http://www.w3.org/TR/REC-xml/#charsets for definition.
+                    // No other Java XML writer we know of does this, but no Java
+                    // XML reader we know of is able to parse the bad output we'd
+                    // otherwise generate.
+                    // Note: tab, newline, and carriage return have already been
+                    // handled above.
+                    boolean allowedInXml = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
+                    if (allowedInXml) {
+                        if (unicode || c < 127) {
+                            append(c);
+                        } else {
+                            append("&#" + ((int) c) + ";");
+                        }
+                    } else if (Character.isHighSurrogate(c) && i < s.length() - 1) {
+                        writeSurrogate(c, s.charAt(i + 1));
+                        ++i;
+                    } else {
+                        reportInvalidCharacter(c);
+                    }
+                    // END Android-changed
+            }
+        }
+    }
+
+    // BEGIN Android-added
+    private static void reportInvalidCharacter(char ch) {
+        throw new IllegalArgumentException("Illegal character (U+" + Integer.toHexString((int) ch) + ")");
+    }
+    // END Android-added
+
+    /*
+        private final void writeIndent() throws IOException {
+            writer.write("\r\n");
+            for (int i = 0; i < depth; i++)
+                writer.write(' ');
+        }*/
+
+    public void docdecl(String dd) throws IOException {
+        append("<!DOCTYPE");
+        append(dd);
+        append('>');
+    }
+
+    public void endDocument() throws IOException {
+        while (depth > 0) {
+            endTag(elementStack[depth * 3 - 3], elementStack[depth * 3 - 1]);
+        }
+        flush();
+    }
+
+    public void entityRef(String name) throws IOException {
+        check(false);
+        append('&');
+        append(name);
+        append(';');
+    }
+
+    public boolean getFeature(String name) {
+        //return false;
+        return (
+            "http://xmlpull.org/v1/doc/features.html#indent-output"
+                .equals(
+                name))
+            ? indent[depth]
+            : false;
+    }
+
+    public String getPrefix(String namespace, boolean create) {
+        try {
+            return getPrefix(namespace, false, create);
+        }
+        catch (IOException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+
+    private final String getPrefix(
+        String namespace,
+        boolean includeDefault,
+        boolean create)
+        throws IOException {
+
+        for (int i = nspCounts[depth + 1] * 2 - 2;
+            i >= 0;
+            i -= 2) {
+            if (nspStack[i + 1].equals(namespace)
+                && (includeDefault || !nspStack[i].isEmpty())) {
+                String cand = nspStack[i];
+                for (int j = i + 2;
+                    j < nspCounts[depth + 1] * 2;
+                    j++) {
+                    if (nspStack[j].equals(cand)) {
+                        cand = null;
+                        break;
+                    }
+                }
+                if (cand != null)
+                    return cand;
+            }
+        }
+
+        if (!create)
+            return null;
+
+        String prefix;
+
+        if (namespace.isEmpty())
+            prefix = "";
+        else {
+            do {
+                prefix = "n" + (auto++);
+                for (int i = nspCounts[depth + 1] * 2 - 2;
+                    i >= 0;
+                    i -= 2) {
+                    if (prefix.equals(nspStack[i])) {
+                        prefix = null;
+                        break;
+                    }
+                }
+            }
+            while (prefix == null);
+        }
+
+        boolean p = pending;
+        pending = false;
+        setPrefix(prefix, namespace);
+        pending = p;
+        return prefix;
+    }
+
+    public Object getProperty(String name) {
+        throw new RuntimeException("Unsupported property");
+    }
+
+    public void ignorableWhitespace(String s)
+        throws IOException {
+        text(s);
+    }
+
+    public void setFeature(String name, boolean value) {
+        if ("http://xmlpull.org/v1/doc/features.html#indent-output"
+            .equals(name)) {
+            indent[depth] = value;
+        }
+        else
+            throw new RuntimeException("Unsupported Feature");
+    }
+
+    public void setProperty(String name, Object value) {
+        throw new RuntimeException(
+            "Unsupported Property:" + value);
+    }
+
+    public void setPrefix(String prefix, String namespace)
+        throws IOException {
+
+        check(false);
+        if (prefix == null)
+            prefix = "";
+        if (namespace == null)
+            namespace = "";
+
+        String defined = getPrefix(namespace, true, false);
+
+        // boil out if already defined
+
+        if (prefix.equals(defined))
+            return;
+
+        int pos = (nspCounts[depth + 1]++) << 1;
+
+        if (nspStack.length < pos + 1) {
+            String[] hlp = new String[nspStack.length + 16];
+            System.arraycopy(nspStack, 0, hlp, 0, pos);
+            nspStack = hlp;
+        }
+
+        nspStack[pos++] = prefix;
+        nspStack[pos] = namespace;
+    }
+
+    public void setOutput(Writer writer) {
+        this.writer = writer;
+
+        // elementStack = new String[12]; //nsp/prefix/name
+        //nspCounts = new int[4];
+        //nspStack = new String[8]; //prefix/nsp
+        //indent = new boolean[4];
+
+        nspCounts[0] = 2;
+        nspCounts[1] = 2;
+        nspStack[0] = "";
+        nspStack[1] = "";
+        nspStack[2] = "xml";
+        nspStack[3] = "http://www.w3.org/XML/1998/namespace";
+        pending = false;
+        auto = 0;
+        depth = 0;
+
+        unicode = false;
+    }
+
+    public void setOutput(OutputStream os, String encoding)
+        throws IOException {
+        if (os == null)
+            throw new IllegalArgumentException("os == null");
+        setOutput(
+            encoding == null
+                ? new OutputStreamWriter(os)
+                : new OutputStreamWriter(os, encoding));
+        this.encoding = encoding;
+        if (encoding != null && encoding.toLowerCase(Locale.US).startsWith("utf")) {
+            unicode = true;
+        }
+    }
+
+    public void startDocument(String encoding, Boolean standalone) throws IOException {
+        append("<?xml version='1.0' ");
+
+        if (encoding != null) {
+            this.encoding = encoding;
+            if (encoding.toLowerCase(Locale.US).startsWith("utf")) {
+                unicode = true;
+            }
+        }
+
+        if (this.encoding != null) {
+            append("encoding='");
+            append(this.encoding);
+            append("' ");
+        }
+
+        if (standalone != null) {
+            append("standalone='");
+            append(standalone.booleanValue() ? "yes" : "no");
+            append("' ");
+        }
+        append("?>");
+    }
+
+    public XmlSerializer startTag(String namespace, String name)
+        throws IOException {
+        check(false);
+
+        //        if (namespace == null)
+        //            namespace = "";
+
+        if (indent[depth]) {
+            append("\r\n");
+            for (int i = 0; i < depth; i++)
+                append("  ");
+        }
+
+        int esp = depth * 3;
+
+        if (elementStack.length < esp + 3) {
+            String[] hlp = new String[elementStack.length + 12];
+            System.arraycopy(elementStack, 0, hlp, 0, esp);
+            elementStack = hlp;
+        }
+
+        String prefix =
+            namespace == null
+                ? ""
+                : getPrefix(namespace, true, true);
+
+        if (namespace != null && namespace.isEmpty()) {
+            for (int i = nspCounts[depth];
+                i < nspCounts[depth + 1];
+                i++) {
+                if (nspStack[i * 2].isEmpty() && !nspStack[i * 2 + 1].isEmpty()) {
+                    throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+                }
+            }
+        }
+
+        elementStack[esp++] = namespace;
+        elementStack[esp++] = prefix;
+        elementStack[esp] = name;
+
+        append('<');
+        if (!prefix.isEmpty()) {
+            append(prefix);
+            append(':');
+        }
+
+        append(name);
+
+        pending = true;
+
+        return this;
+    }
+
+    public XmlSerializer attribute(
+        String namespace,
+        String name,
+        String value)
+        throws IOException {
+        if (!pending)
+            throw new IllegalStateException("illegal position for attribute");
+
+        //        int cnt = nspCounts[depth];
+
+        if (namespace == null)
+            namespace = "";
+
+        //        depth--;
+        //        pending = false;
+
+        String prefix =
+            namespace.isEmpty()
+                ? ""
+                : getPrefix(namespace, false, true);
+
+        //        pending = true;
+        //        depth++;
+
+        /*        if (cnt != nspCounts[depth]) {
+                    writer.write(' ');
+                    writer.write("xmlns");
+                    if (nspStack[cnt * 2] != null) {
+                        writer.write(':');
+                        writer.write(nspStack[cnt * 2]);
+                    }
+                    writer.write("=\"");
+                    writeEscaped(nspStack[cnt * 2 + 1], '"');
+                    writer.write('"');
+                }
+                */
+
+        append(' ');
+        if (!prefix.isEmpty()) {
+            append(prefix);
+            append(':');
+        }
+        append(name);
+        append('=');
+        char q = value.indexOf('"') == -1 ? '"' : '\'';
+        append(q);
+        writeEscaped(value, q);
+        append(q);
+
+        return this;
+    }
+
+    public void flush() throws IOException {
+        check(false);
+        flushBuffer();
+    }
+    /*
+        public void close() throws IOException {
+            check();
+            writer.close();
+        }
+    */
+    public XmlSerializer endTag(String namespace, String name)
+        throws IOException {
+
+        if (!pending)
+            depth--;
+        //        if (namespace == null)
+        //          namespace = "";
+
+        if ((namespace == null
+            && elementStack[depth * 3] != null)
+            || (namespace != null
+                && !namespace.equals(elementStack[depth * 3]))
+            || !elementStack[depth * 3 + 2].equals(name))
+            throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
+
+        if (pending) {
+            check(true);
+            depth--;
+        }
+        else {
+            if (indent[depth + 1]) {
+                append("\r\n");
+                for (int i = 0; i < depth; i++)
+                    append("  ");
+            }
+
+            append("</");
+            String prefix = elementStack[depth * 3 + 1];
+            if (!prefix.isEmpty()) {
+                append(prefix);
+                append(':');
+            }
+            append(name);
+            append('>');
+        }
+
+        nspCounts[depth + 1] = nspCounts[depth];
+        return this;
+    }
+
+    public String getNamespace() {
+        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
+    }
+
+    public String getName() {
+        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
+    }
+
+    public int getDepth() {
+        return pending ? depth + 1 : depth;
+    }
+
+    public XmlSerializer text(String text) throws IOException {
+        check(false);
+        indent[depth] = false;
+        writeEscaped(text, -1);
+        return this;
+    }
+
+    public XmlSerializer text(char[] text, int start, int len)
+        throws IOException {
+        text(new String(text, start, len));
+        return this;
+    }
+
+    public void cdsect(String data) throws IOException {
+        check(false);
+        // BEGIN Android-changed: ]]> is not allowed within a CDATA,
+        // so break and start a new one when necessary.
+        data = data.replace("]]>", "]]]]><![CDATA[>");
+        append("<![CDATA[");
+        for (int i = 0; i < data.length(); ++i) {
+            char ch = data.charAt(i);
+            boolean allowedInCdata = (ch >= 0x20 && ch <= 0xd7ff) ||
+                    (ch == '\t' || ch == '\n' || ch == '\r') ||
+                    (ch >= 0xe000 && ch <= 0xfffd);
+            if (allowedInCdata) {
+                append(ch);
+            } else if (Character.isHighSurrogate(ch) && i < data.length() - 1) {
+                // Character entities aren't valid in CDATA, so break out for this.
+                append("]]>");
+                writeSurrogate(ch, data.charAt(++i));
+                append("<![CDATA[");
+            } else {
+                reportInvalidCharacter(ch);
+            }
+        }
+        append("]]>");
+        // END Android-changed
+    }
+
+    // BEGIN Android-added
+    private void writeSurrogate(char high, char low) throws IOException {
+        if (!Character.isLowSurrogate(low)) {
+            throw new IllegalArgumentException("Bad surrogate pair (U+" + Integer.toHexString((int) high) +
+                                               " U+" + Integer.toHexString((int) low) + ")");
+        }
+        // Java-style surrogate pairs aren't allowed in XML. We could use the > 3-byte encodings, but that
+        // seems likely to upset anything expecting modified UTF-8 rather than "real" UTF-8. It seems more
+        // conservative in a Java environment to use an entity reference instead.
+        int codePoint = Character.toCodePoint(high, low);
+        append("&#" + codePoint + ";");
+    }
+    // END Android-added
+
+    public void comment(String comment) throws IOException {
+        check(false);
+        append("<!--");
+        append(comment);
+        append("-->");
+    }
+
+    public void processingInstruction(String pi)
+        throws IOException {
+        check(false);
+        append("<?");
+        append(pi);
+        append("?>");
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
deleted file mode 100644
index e010f1d..0000000
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ /dev/null
@@ -1,2178 +0,0 @@
-/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The  above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE. */
-
-// Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
-
-package org.kxml2.io;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Map;
-import libcore.internal.StringPool;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * An XML pull parser with limited support for parsing internal DTDs.
- */
-public class KXmlParser implements XmlPullParser, Closeable {
-
-    private static final String PROPERTY_XMLDECL_VERSION
-            = "http://xmlpull.org/v1/doc/properties.html#xmldecl-version";
-    private static final String PROPERTY_XMLDECL_STANDALONE
-            = "http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone";
-    private static final String PROPERTY_LOCATION = "http://xmlpull.org/v1/doc/properties.html#location";
-    private static final String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed";
-
-    private static final Map<String, String> DEFAULT_ENTITIES = new HashMap<String, String>();
-    static {
-        DEFAULT_ENTITIES.put("lt", "<");
-        DEFAULT_ENTITIES.put("gt", ">");
-        DEFAULT_ENTITIES.put("amp", "&");
-        DEFAULT_ENTITIES.put("apos", "'");
-        DEFAULT_ENTITIES.put("quot", "\"");
-    }
-
-    private static final int ELEMENTDECL = 11;
-    private static final int ENTITYDECL = 12;
-    private static final int ATTLISTDECL = 13;
-    private static final int NOTATIONDECL = 14;
-    private static final int PARAMETER_ENTITY_REF = 15;
-    private static final char[] START_COMMENT = { '<', '!', '-', '-' };
-    private static final char[] END_COMMENT = { '-', '-', '>' };
-    private static final char[] COMMENT_DOUBLE_DASH = { '-', '-' };
-    private static final char[] START_CDATA = { '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[' };
-    private static final char[] END_CDATA = { ']', ']', '>' };
-    private static final char[] START_PROCESSING_INSTRUCTION = { '<', '?' };
-    private static final char[] END_PROCESSING_INSTRUCTION = { '?', '>' };
-    private static final char[] START_DOCTYPE = { '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E' };
-    private static final char[] SYSTEM = { 'S', 'Y', 'S', 'T', 'E', 'M' };
-    private static final char[] PUBLIC = { 'P', 'U', 'B', 'L', 'I', 'C' };
-    private static final char[] START_ELEMENT = { '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T' };
-    private static final char[] START_ATTLIST = { '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T' };
-    private static final char[] START_ENTITY = { '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y' };
-    private static final char[] START_NOTATION = { '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N' };
-    private static final char[] EMPTY = new char[] { 'E', 'M', 'P', 'T', 'Y' };
-    private static final char[] ANY = new char[]{ 'A', 'N', 'Y' };
-    private static final char[] NDATA = new char[]{ 'N', 'D', 'A', 'T', 'A' };
-    private static final char[] NOTATION = new char[]{ 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N' };
-    private static final char[] REQUIRED = new char[] { 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D' };
-    private static final char[] IMPLIED = new char[] { 'I', 'M', 'P', 'L', 'I', 'E', 'D' };
-    private static final char[] FIXED = new char[] { 'F', 'I', 'X', 'E', 'D' };
-
-    static final private String UNEXPECTED_EOF = "Unexpected EOF";
-    static final private String ILLEGAL_TYPE = "Wrong event type";
-    static final private int XML_DECLARATION = 998;
-
-    // general
-    private String location;
-
-    private String version;
-    private Boolean standalone;
-    private String rootElementName;
-    private String systemId;
-    private String publicId;
-
-    /**
-     * True if the {@code <!DOCTYPE>} contents are handled. The DTD defines
-     * entity values and default attribute values. These values are parsed at
-     * inclusion time and may contain both tags and entity references.
-     *
-     * <p>If this is false, the user must {@link #defineEntityReplacementText
-     * define entity values manually}. Such entity values are literal strings
-     * and will not be parsed. There is no API to define default attributes
-     * manually.
-     */
-    private boolean processDocDecl;
-    private boolean processNsp;
-    private boolean relaxed;
-    private boolean keepNamespaceAttributes;
-
-    /**
-     * If non-null, the contents of the read buffer must be copied into this
-     * string builder before the read buffer is overwritten. This is used to
-     * capture the raw DTD text while parsing the DTD.
-     */
-    private StringBuilder bufferCapture;
-
-    /**
-     * Entities defined in or for this document. This map is created lazily.
-     */
-    private Map<String, char[]> documentEntities;
-
-    /**
-     * Default attributes in this document. The outer map's key is the element
-     * name; the inner map's key is the attribute name. Both keys should be
-     * without namespace adjustments. This map is created lazily.
-     */
-    private Map<String, Map<String, String>> defaultAttributes;
-
-
-    private int depth;
-    private String[] elementStack = new String[16];
-    private String[] nspStack = new String[8];
-    private int[] nspCounts = new int[4];
-
-    // source
-
-    private Reader reader;
-    private String encoding;
-    private ContentSource nextContentSource;
-    private char[] buffer = new char[8192];
-    private int position = 0;
-    private int limit = 0;
-
-    /*
-     * Track the number of newlines and columns preceding the current buffer. To
-     * compute the line and column of a position in the buffer, compute the line
-     * and column in the buffer and add the preceding values.
-     */
-    private int bufferStartLine;
-    private int bufferStartColumn;
-
-    // the current token
-
-    private int type;
-    private boolean isWhitespace;
-    private String namespace;
-    private String prefix;
-    private String name;
-    private String text;
-
-    private boolean degenerated;
-    private int attributeCount;
-
-    // true iff. we've encountered the START_TAG of an XML element at depth == 0;
-    private boolean parsedTopLevelStartTag;
-
-    /*
-     * The current element's attributes arranged in groups of 4:
-     * i + 0 = attribute namespace URI
-     * i + 1 = attribute namespace prefix
-     * i + 2 = attribute qualified name (may contain ":", as in "html:h1")
-     * i + 3 = attribute value
-     */
-    private String[] attributes = new String[16];
-
-    private String error;
-
-    private boolean unresolved;
-
-    public final StringPool stringPool = new StringPool();
-
-    /**
-     * Retains namespace attributes like {@code xmlns="http://foo"} or {@code xmlns:foo="http:foo"}
-     * in pulled elements. Most applications will only be interested in the effective namespaces of
-     * their elements, so these attributes aren't useful. But for structure preserving wrappers like
-     * DOM, it is necessary to keep the namespace data around.
-     */
-    public void keepNamespaceAttributes() {
-        this.keepNamespaceAttributes = true;
-    }
-
-    private boolean adjustNsp() throws XmlPullParserException {
-        boolean any = false;
-
-        for (int i = 0; i < attributeCount << 2; i += 4) {
-            String attrName = attributes[i + 2];
-            int cut = attrName.indexOf(':');
-            String prefix;
-
-            if (cut != -1) {
-                prefix = attrName.substring(0, cut);
-                attrName = attrName.substring(cut + 1);
-            } else if (attrName.equals("xmlns")) {
-                prefix = attrName;
-                attrName = null;
-            } else {
-                continue;
-            }
-
-            if (!prefix.equals("xmlns")) {
-                any = true;
-            } else {
-                int j = (nspCounts[depth]++) << 1;
-
-                nspStack = ensureCapacity(nspStack, j + 2);
-                nspStack[j] = attrName;
-                nspStack[j + 1] = attributes[i + 3];
-
-                if (attrName != null && attributes[i + 3].isEmpty()) {
-                    checkRelaxed("illegal empty namespace");
-                }
-
-                if (keepNamespaceAttributes) {
-                    // explicitly set the namespace for unprefixed attributes
-                    // such as xmlns="http://foo"
-                    attributes[i] = "http://www.w3.org/2000/xmlns/";
-                    any = true;
-                } else {
-                    System.arraycopy(
-                            attributes,
-                            i + 4,
-                            attributes,
-                            i,
-                            ((--attributeCount) << 2) - i);
-
-                    i -= 4;
-                }
-            }
-        }
-
-        if (any) {
-            for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
-
-                String attrName = attributes[i + 2];
-                int cut = attrName.indexOf(':');
-
-                if (cut == 0 && !relaxed) {
-                    throw new RuntimeException(
-                            "illegal attribute name: " + attrName + " at " + this);
-                } else if (cut != -1) {
-                    String attrPrefix = attrName.substring(0, cut);
-
-                    attrName = attrName.substring(cut + 1);
-
-                    String attrNs = getNamespace(attrPrefix);
-
-                    if (attrNs == null && !relaxed) {
-                        throw new RuntimeException(
-                                "Undefined Prefix: " + attrPrefix + " in " + this);
-                    }
-
-                    attributes[i] = attrNs;
-                    attributes[i + 1] = attrPrefix;
-                    attributes[i + 2] = attrName;
-                }
-            }
-        }
-
-        int cut = name.indexOf(':');
-
-        if (cut == 0) {
-            checkRelaxed("illegal tag name: " + name);
-        }
-
-        if (cut != -1) {
-            prefix = name.substring(0, cut);
-            name = name.substring(cut + 1);
-        }
-
-        this.namespace = getNamespace(prefix);
-
-        if (this.namespace == null) {
-            if (prefix != null) {
-                checkRelaxed("undefined prefix: " + prefix);
-            }
-            this.namespace = NO_NAMESPACE;
-        }
-
-        return any;
-    }
-
-    private String[] ensureCapacity(String[] arr, int required) {
-        if (arr.length >= required) {
-            return arr;
-        }
-        String[] bigger = new String[required + 16];
-        System.arraycopy(arr, 0, bigger, 0, arr.length);
-        return bigger;
-    }
-
-    private void checkRelaxed(String errorMessage) throws XmlPullParserException {
-        if (!relaxed) {
-            throw new XmlPullParserException(errorMessage, this, null);
-        }
-        if (error == null) {
-            error = "Error: " + errorMessage;
-        }
-    }
-
-    public int next() throws XmlPullParserException, IOException {
-        return next(false);
-    }
-
-    public int nextToken() throws XmlPullParserException, IOException {
-        return next(true);
-    }
-
-    private int next(boolean justOneToken) throws IOException, XmlPullParserException {
-        if (reader == null) {
-            throw new XmlPullParserException("setInput() must be called first.", this, null);
-        }
-
-        if (type == END_TAG) {
-            depth--;
-        }
-
-        // degenerated needs to be handled before error because of possible
-        // processor expectations(!)
-
-        if (degenerated) {
-            degenerated = false;
-            type = END_TAG;
-            return type;
-        }
-
-        if (error != null) {
-            if (justOneToken) {
-                text = error;
-                type = COMMENT;
-                error = null;
-                return type;
-            } else {
-                error = null;
-            }
-        }
-
-        type = peekType(false);
-
-        if (type == XML_DECLARATION) {
-            readXmlDeclaration();
-            type = peekType(false);
-        }
-
-        text = null;
-        isWhitespace = true;
-        prefix = null;
-        name = null;
-        namespace = null;
-        attributeCount = -1;
-        boolean throwOnResolveFailure = !justOneToken;
-
-        while (true) {
-            switch (type) {
-
-            /*
-             * Return immediately after encountering a start tag, end tag, or
-             * the end of the document.
-             */
-            case START_TAG:
-                parseStartTag(false, throwOnResolveFailure);
-                return type;
-            case END_TAG:
-                readEndTag();
-                return type;
-            case END_DOCUMENT:
-                return type;
-
-            /*
-             * Return after any text token when we're looking for a single
-             * token. Otherwise concatenate all text between tags.
-             */
-            case ENTITY_REF:
-                if (justOneToken) {
-                    StringBuilder entityTextBuilder = new StringBuilder();
-                    readEntity(entityTextBuilder, true, throwOnResolveFailure, ValueContext.TEXT);
-                    text = entityTextBuilder.toString();
-                    break;
-                }
-                // fall-through
-            case TEXT:
-                text = readValue('<', !justOneToken, throwOnResolveFailure, ValueContext.TEXT);
-                if (depth == 0 && isWhitespace) {
-                    type = IGNORABLE_WHITESPACE;
-                }
-                break;
-            case CDSECT:
-                read(START_CDATA);
-                text = readUntil(END_CDATA, true);
-                break;
-
-            /*
-             * Comments, processing instructions and declarations are returned
-             * when we're looking for a single token. Otherwise they're skipped.
-             */
-            case COMMENT:
-                String commentText = readComment(justOneToken);
-                if (justOneToken) {
-                    text = commentText;
-                }
-                break;
-            case PROCESSING_INSTRUCTION:
-                read(START_PROCESSING_INSTRUCTION);
-                String processingInstruction = readUntil(END_PROCESSING_INSTRUCTION, justOneToken);
-                if (justOneToken) {
-                    text = processingInstruction;
-                }
-                break;
-            case DOCDECL:
-                readDoctype(justOneToken);
-                if (parsedTopLevelStartTag) {
-                    throw new XmlPullParserException("Unexpected token", this, null);
-                }
-                break;
-
-            default:
-                throw new XmlPullParserException("Unexpected token", this, null);
-            }
-
-            if (depth == 0 && (type == ENTITY_REF || type == TEXT || type == CDSECT)) {
-                throw new XmlPullParserException("Unexpected token", this, null);
-            }
-
-            if (justOneToken) {
-                return type;
-            }
-
-            if (type == IGNORABLE_WHITESPACE) {
-                text = null;
-            }
-
-            /*
-             * We've read all that we can of a non-empty text block. Always
-             * report this as text, even if it was a CDATA block or entity
-             * reference.
-             */
-            int peek = peekType(false);
-            if (text != null && !text.isEmpty() && peek < TEXT) {
-                type = TEXT;
-                return type;
-            }
-
-            type = peek;
-        }
-    }
-
-    /**
-     * Reads text until the specified delimiter is encountered. Consumes the
-     * text and the delimiter.
-     *
-     * @param returnText true to return the read text excluding the delimiter;
-     *     false to return null.
-     */
-    private String readUntil(char[] delimiter, boolean returnText)
-            throws IOException, XmlPullParserException {
-        int start = position;
-        StringBuilder result = null;
-
-        if (returnText && text != null) {
-            result = new StringBuilder();
-            result.append(text);
-        }
-
-        search:
-        while (true) {
-            if (position + delimiter.length > limit) {
-                if (start < position && returnText) {
-                    if (result == null) {
-                        result = new StringBuilder();
-                    }
-                    result.append(buffer, start, position - start);
-                }
-                if (!fillBuffer(delimiter.length)) {
-                    checkRelaxed(UNEXPECTED_EOF);
-                    type = COMMENT;
-                    return null;
-                }
-                start = position;
-            }
-
-            // TODO: replace with Arrays.equals(buffer, position, delimiter, 0, delimiter.length)
-            // when the VM has better method inlining
-            for (int i = 0; i < delimiter.length; i++) {
-                if (buffer[position + i] != delimiter[i]) {
-                    position++;
-                    continue search;
-                }
-            }
-
-            break;
-        }
-
-        int end = position;
-        position += delimiter.length;
-
-        if (!returnText) {
-            return null;
-        } else if (result == null) {
-            return stringPool.get(buffer, start, end - start);
-        } else {
-            result.append(buffer, start, end - start);
-            return result.toString();
-        }
-    }
-
-    /**
-     * Returns true if an XML declaration was read.
-     */
-    private void readXmlDeclaration() throws IOException, XmlPullParserException {
-        if (bufferStartLine != 0 || bufferStartColumn != 0 || position != 0) {
-            checkRelaxed("processing instructions must not start with xml");
-        }
-
-        read(START_PROCESSING_INSTRUCTION);
-        parseStartTag(true, true);
-
-        if (attributeCount < 1 || !"version".equals(attributes[2])) {
-            checkRelaxed("version expected");
-        }
-
-        version = attributes[3];
-
-        int pos = 1;
-
-        if (pos < attributeCount && "encoding".equals(attributes[2 + 4])) {
-            encoding = attributes[3 + 4];
-            pos++;
-        }
-
-        if (pos < attributeCount && "standalone".equals(attributes[4 * pos + 2])) {
-            String st = attributes[3 + 4 * pos];
-            if ("yes".equals(st)) {
-                standalone = Boolean.TRUE;
-            } else if ("no".equals(st)) {
-                standalone = Boolean.FALSE;
-            } else {
-                checkRelaxed("illegal standalone value: " + st);
-            }
-            pos++;
-        }
-
-        if (pos != attributeCount) {
-            checkRelaxed("unexpected attributes in XML declaration");
-        }
-
-        isWhitespace = true;
-        text = null;
-    }
-
-    private String readComment(boolean returnText) throws IOException, XmlPullParserException {
-        read(START_COMMENT);
-
-        if (relaxed) {
-            return readUntil(END_COMMENT, returnText);
-        }
-
-        String commentText = readUntil(COMMENT_DOUBLE_DASH, returnText);
-        if (peekCharacter() != '>') {
-            throw new XmlPullParserException("Comments may not contain --", this, null);
-        }
-        position++;
-        return commentText;
-    }
-
-    /**
-     * Read the document's DTD. Although this parser is non-validating, the DTD
-     * must be parsed to capture entity values and default attribute values.
-     */
-    private void readDoctype(boolean saveDtdText) throws IOException, XmlPullParserException {
-        read(START_DOCTYPE);
-
-        int startPosition = -1;
-        if (saveDtdText) {
-            bufferCapture = new StringBuilder();
-            startPosition = position;
-        }
-        try {
-            skip();
-            rootElementName = readName();
-            readExternalId(true, true);
-            skip();
-            if (peekCharacter() == '[') {
-                readInternalSubset();
-            }
-            skip();
-        } finally {
-            if (saveDtdText) {
-                bufferCapture.append(buffer, 0, position);
-                bufferCapture.delete(0, startPosition);
-                text = bufferCapture.toString();
-                bufferCapture = null;
-            }
-        }
-
-        read('>');
-        skip();
-    }
-
-    /**
-     * Reads an external ID of one of these two forms:
-     *   SYSTEM "quoted system name"
-     *   PUBLIC "quoted public id" "quoted system name"
-     *
-     * If the system name is not required, this also supports lone public IDs of
-     * this form:
-     *   PUBLIC "quoted public id"
-     *
-     * Returns true if any ID was read.
-     */
-    private boolean readExternalId(boolean requireSystemName, boolean assignFields)
-            throws IOException, XmlPullParserException {
-        skip();
-        int c = peekCharacter();
-
-        if (c == 'S') {
-            read(SYSTEM);
-        } else if (c == 'P') {
-            read(PUBLIC);
-            skip();
-            if (assignFields) {
-                publicId = readQuotedId(true);
-            } else {
-                readQuotedId(false);
-            }
-        } else {
-            return false;
-        }
-
-        skip();
-
-        if (!requireSystemName) {
-            int delimiter = peekCharacter();
-            if (delimiter != '"' && delimiter != '\'') {
-                return true; // no system name!
-            }
-        }
-
-        if (assignFields) {
-            systemId = readQuotedId(true);
-        } else {
-            readQuotedId(false);
-        }
-        return true;
-    }
-
-    private static final char[] SINGLE_QUOTE = new char[] { '\'' };
-    private static final char[] DOUBLE_QUOTE = new char[] { '"' };
-
-    /**
-     * Reads a quoted string, performing no entity escaping of the contents.
-     */
-    private String readQuotedId(boolean returnText) throws IOException, XmlPullParserException {
-        int quote = peekCharacter();
-        char[] delimiter;
-        if (quote == '"') {
-            delimiter = DOUBLE_QUOTE;
-        } else if (quote == '\'') {
-            delimiter = SINGLE_QUOTE;
-        } else {
-            throw new XmlPullParserException("Expected a quoted string", this, null);
-        }
-        position++;
-        return readUntil(delimiter, returnText);
-    }
-
-    private void readInternalSubset() throws IOException, XmlPullParserException {
-        read('[');
-
-        while (true) {
-            skip();
-            if (peekCharacter() == ']') {
-                position++;
-                return;
-            }
-
-            int declarationType = peekType(true);
-            switch (declarationType) {
-            case ELEMENTDECL:
-                readElementDeclaration();
-                break;
-
-            case ATTLISTDECL:
-                readAttributeListDeclaration();
-                break;
-
-            case ENTITYDECL:
-                readEntityDeclaration();
-                break;
-
-            case NOTATIONDECL:
-                readNotationDeclaration();
-                break;
-
-            case PROCESSING_INSTRUCTION:
-                read(START_PROCESSING_INSTRUCTION);
-                readUntil(END_PROCESSING_INSTRUCTION, false);
-                break;
-
-            case COMMENT:
-                readComment(false);
-                break;
-
-            case PARAMETER_ENTITY_REF:
-                throw new XmlPullParserException(
-                        "Parameter entity references are not supported", this, null);
-
-            default:
-                throw new XmlPullParserException("Unexpected token", this, null);
-            }
-        }
-    }
-
-    /**
-     * Read an element declaration. This contains a name and a content spec.
-     *   <!ELEMENT foo EMPTY >
-     *   <!ELEMENT foo (bar?,(baz|quux)) >
-     *   <!ELEMENT foo (#PCDATA|bar)* >
-     */
-    private void readElementDeclaration() throws IOException, XmlPullParserException {
-        read(START_ELEMENT);
-        skip();
-        readName();
-        readContentSpec();
-        skip();
-        read('>');
-    }
-
-    /**
-     * Read an element content spec. This is a regular expression-like pattern
-     * of names or other content specs. The following operators are supported:
-     *   sequence:    (a,b,c)
-     *   choice:      (a|b|c)
-     *   optional:    a?
-     *   one or more: a+
-     *   any number:  a*
-     *
-     * The special name '#PCDATA' is permitted but only if it is the first
-     * element of the first group:
-     *   (#PCDATA|a|b)
-     *
-     * The top-level element must be either a choice, a sequence, or one of the
-     * special names EMPTY and ANY.
-     */
-    private void readContentSpec() throws IOException, XmlPullParserException {
-        // this implementation is very lenient; it scans for balanced parens only
-        skip();
-        int c = peekCharacter();
-        if (c == '(') {
-            int depth = 0;
-            do {
-                if (c == '(') {
-                    depth++;
-                } else if (c == ')') {
-                    depth--;
-                } else if (c == -1) {
-                    throw new XmlPullParserException(
-                            "Unterminated element content spec", this, null);
-                }
-                position++;
-                c = peekCharacter();
-            } while (depth > 0);
-
-            if (c == '*' || c == '?' || c == '+') {
-                position++;
-            }
-        } else if (c == EMPTY[0]) {
-            read(EMPTY);
-        } else if (c == ANY[0]) {
-            read(ANY);
-        } else {
-            throw new XmlPullParserException("Expected element content spec", this, null);
-        }
-    }
-
-    /**
-     * Reads an attribute list declaration such as the following:
-     *   <!ATTLIST foo
-     *       bar CDATA #IMPLIED
-     *       quux (a|b|c) "c"
-     *       baz NOTATION (a|b|c) #FIXED "c">
-     *
-     * Each attribute has a name, type and default.
-     *
-     * Types are one of the built-in types (CDATA, ID, IDREF, IDREFS, ENTITY,
-     * ENTITIES, NMTOKEN, or NMTOKENS), an enumerated type "(list|of|options)"
-     * or NOTATION followed by an enumerated type.
-     *
-     * The default is either #REQUIRED, #IMPLIED, #FIXED, a quoted value, or
-     * #FIXED with a quoted value.
-     */
-    private void readAttributeListDeclaration() throws IOException, XmlPullParserException {
-        read(START_ATTLIST);
-        skip();
-        String elementName = readName();
-
-        while (true) {
-            skip();
-            int c = peekCharacter();
-            if (c == '>') {
-                position++;
-                return;
-            }
-
-            // attribute name
-            String attributeName = readName();
-
-            // attribute type
-            skip();
-            if (position + 1 >= limit && !fillBuffer(2)) {
-                throw new XmlPullParserException("Malformed attribute list", this, null);
-            }
-            if (buffer[position] == NOTATION[0] && buffer[position + 1] == NOTATION[1]) {
-                read(NOTATION);
-                skip();
-            }
-            c = peekCharacter();
-            if (c == '(') {
-                position++;
-                while (true) {
-                    skip();
-                    readName();
-                    skip();
-                    c = peekCharacter();
-                    if (c == ')') {
-                        position++;
-                        break;
-                    } else if (c == '|') {
-                        position++;
-                    } else {
-                        throw new XmlPullParserException("Malformed attribute type", this, null);
-                    }
-                }
-            } else {
-                readName();
-            }
-
-            // default value
-            skip();
-            c = peekCharacter();
-            if (c == '#') {
-                position++;
-                c = peekCharacter();
-                if (c == 'R') {
-                    read(REQUIRED);
-                } else if (c == 'I') {
-                    read(IMPLIED);
-                } else if (c == 'F') {
-                    read(FIXED);
-                } else {
-                    throw new XmlPullParserException("Malformed attribute type", this, null);
-                }
-                skip();
-                c = peekCharacter();
-            }
-            if (c == '"' || c == '\'') {
-                position++;
-                // TODO: does this do escaping correctly?
-                String value = readValue((char) c, true, true, ValueContext.ATTRIBUTE);
-                if (peekCharacter() == c) {
-                    position++;
-                }
-                defineAttributeDefault(elementName, attributeName, value);
-            }
-        }
-    }
-
-    private void defineAttributeDefault(String elementName, String attributeName, String value) {
-        if (defaultAttributes == null) {
-            defaultAttributes = new HashMap<String, Map<String, String>>();
-        }
-        Map<String, String> elementAttributes = defaultAttributes.get(elementName);
-        if (elementAttributes == null) {
-            elementAttributes = new HashMap<String, String>();
-            defaultAttributes.put(elementName, elementAttributes);
-        }
-        elementAttributes.put(attributeName, value);
-    }
-
-    /**
-     * Read an entity declaration. The value of internal entities are inline:
-     *   <!ENTITY foo "bar">
-     *
-     * The values of external entities must be retrieved by URL or path:
-     *   <!ENTITY foo SYSTEM "http://host/file">
-     *   <!ENTITY foo PUBLIC "-//Android//Foo//EN" "http://host/file">
-     *   <!ENTITY foo SYSTEM "../file.png" NDATA png>
-     *
-     * Entities may be general or parameterized. Parameterized entities are
-     * marked by a percent sign. Such entities may only be used in the DTD:
-     *   <!ENTITY % foo "bar">
-     */
-    private void readEntityDeclaration() throws IOException, XmlPullParserException {
-        read(START_ENTITY);
-        boolean generalEntity = true;
-
-        skip();
-        if (peekCharacter() == '%') {
-            generalEntity = false;
-            position++;
-            skip();
-        }
-
-        String name = readName();
-
-        skip();
-        int quote = peekCharacter();
-        String entityValue;
-        if (quote == '"' || quote == '\'') {
-            position++;
-            entityValue = readValue((char) quote, true, false, ValueContext.ENTITY_DECLARATION);
-            if (peekCharacter() == quote) {
-                position++;
-            }
-        } else if (readExternalId(true, false)) {
-            /*
-             * Map external entities to the empty string. This is dishonest,
-             * but it's consistent with Android's Expat pull parser.
-             */
-            entityValue = "";
-            skip();
-            if (peekCharacter() == NDATA[0]) {
-                read(NDATA);
-                skip();
-                readName();
-            }
-        } else {
-            throw new XmlPullParserException("Expected entity value or external ID", this, null);
-        }
-
-        if (generalEntity && processDocDecl) {
-            if (documentEntities == null) {
-                documentEntities = new HashMap<String, char[]>();
-            }
-            documentEntities.put(name, entityValue.toCharArray());
-        }
-
-        skip();
-        read('>');
-    }
-
-    private void readNotationDeclaration() throws IOException, XmlPullParserException {
-        read(START_NOTATION);
-        skip();
-        readName();
-        if (!readExternalId(false, false)) {
-            throw new XmlPullParserException(
-                    "Expected external ID or public ID for notation", this, null);
-        }
-        skip();
-        read('>');
-    }
-
-    private void readEndTag() throws IOException, XmlPullParserException {
-        read('<');
-        read('/');
-        name = readName(); // TODO: pass the expected name in as a hint?
-        skip();
-        read('>');
-
-        int sp = (depth - 1) * 4;
-
-        if (depth == 0) {
-            checkRelaxed("read end tag " + name + " with no tags open");
-            type = COMMENT;
-            return;
-        }
-
-        if (name.equals(elementStack[sp + 3])) {
-            namespace = elementStack[sp];
-            prefix = elementStack[sp + 1];
-            name = elementStack[sp + 2];
-        } else if (!relaxed) {
-            throw new XmlPullParserException(
-                    "expected: /" + elementStack[sp + 3] + " read: " + name, this, null);
-        }
-    }
-
-    /**
-     * Returns the type of the next token.
-     */
-    private int peekType(boolean inDeclaration) throws IOException, XmlPullParserException {
-        if (position >= limit && !fillBuffer(1)) {
-            return END_DOCUMENT;
-        }
-
-        switch (buffer[position]) {
-        case '&':
-            return ENTITY_REF; // &
-        case '<':
-            if (position + 3 >= limit && !fillBuffer(4)) {
-                throw new XmlPullParserException("Dangling <", this, null);
-            }
-
-            switch (buffer[position + 1]) {
-            case '/':
-                return END_TAG; // </
-            case '?':
-                // we're looking for "<?xml " with case insensitivity
-                if ((position + 5 < limit || fillBuffer(6))
-                        && (buffer[position + 2] == 'x' || buffer[position + 2] == 'X')
-                        && (buffer[position + 3] == 'm' || buffer[position + 3] == 'M')
-                        && (buffer[position + 4] == 'l' || buffer[position + 4] == 'L')
-                        && (buffer[position + 5] == ' ')) {
-                    return XML_DECLARATION; // <?xml
-                } else {
-                    return PROCESSING_INSTRUCTION; // <?
-                }
-            case '!':
-                switch (buffer[position + 2]) {
-                case 'D':
-                    return DOCDECL; // <!D
-                case '[':
-                    return CDSECT; // <![
-                case '-':
-                    return COMMENT; // <!-
-                case 'E':
-                    switch (buffer[position + 3]) {
-                    case 'L':
-                        return ELEMENTDECL; // <!EL
-                    case 'N':
-                        return ENTITYDECL; // <!EN
-                    }
-                    break;
-                case 'A':
-                    return ATTLISTDECL;  // <!A
-                case 'N':
-                    return NOTATIONDECL; // <!N
-                }
-                throw new XmlPullParserException("Unexpected <!", this, null);
-            default:
-                return START_TAG; // <
-            }
-        case '%':
-            return inDeclaration ? PARAMETER_ENTITY_REF : TEXT;
-        default:
-            return TEXT;
-        }
-    }
-
-    /**
-     * Sets name and attributes
-     */
-    private void parseStartTag(boolean xmldecl, boolean throwOnResolveFailure)
-            throws IOException, XmlPullParserException {
-        if (!xmldecl) {
-            read('<');
-        }
-        name = readName();
-        attributeCount = 0;
-
-        while (true) {
-            skip();
-
-            if (position >= limit && !fillBuffer(1)) {
-                checkRelaxed(UNEXPECTED_EOF);
-                return;
-            }
-
-            int c = buffer[position];
-
-            if (xmldecl) {
-                if (c == '?') {
-                    position++;
-                    read('>');
-                    return;
-                }
-            } else {
-                if (c == '/') {
-                    degenerated = true;
-                    position++;
-                    skip();
-                    read('>');
-                    break;
-                } else if (c == '>') {
-                    position++;
-                    break;
-                }
-            }
-
-            String attrName = readName();
-
-            int i = (attributeCount++) * 4;
-            attributes = ensureCapacity(attributes, i + 4);
-            attributes[i] = "";
-            attributes[i + 1] = null;
-            attributes[i + 2] = attrName;
-
-            skip();
-            if (position >= limit && !fillBuffer(1)) {
-                checkRelaxed(UNEXPECTED_EOF);
-                return;
-            }
-
-            if (buffer[position] == '=') {
-                position++;
-
-                skip();
-                if (position >= limit && !fillBuffer(1)) {
-                    checkRelaxed(UNEXPECTED_EOF);
-                    return;
-                }
-                char delimiter = buffer[position];
-
-                if (delimiter == '\'' || delimiter == '"') {
-                    position++;
-                } else if (relaxed) {
-                    delimiter = ' ';
-                } else {
-                    throw new XmlPullParserException("attr value delimiter missing!", this, null);
-                }
-
-                attributes[i + 3] = readValue(delimiter, true, throwOnResolveFailure,
-                        ValueContext.ATTRIBUTE);
-
-                if (delimiter != ' ' && peekCharacter() == delimiter) {
-                    position++; // end quote
-                }
-            } else if (relaxed) {
-                attributes[i + 3] = attrName;
-            } else {
-                checkRelaxed("Attr.value missing f. " + attrName);
-                attributes[i + 3] = attrName;
-            }
-        }
-
-        int sp = depth++ * 4;
-        if (depth == 1) {
-            parsedTopLevelStartTag = true;
-        }
-        elementStack = ensureCapacity(elementStack, sp + 4);
-        elementStack[sp + 3] = name;
-
-        if (depth >= nspCounts.length) {
-            int[] bigger = new int[depth + 4];
-            System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
-            nspCounts = bigger;
-        }
-
-        nspCounts[depth] = nspCounts[depth - 1];
-
-        if (processNsp) {
-            adjustNsp();
-        } else {
-            namespace = "";
-        }
-
-        // For consistency with Expat, add default attributes after fixing namespaces.
-        if (defaultAttributes != null) {
-            Map<String, String> elementDefaultAttributes = defaultAttributes.get(name);
-            if (elementDefaultAttributes != null) {
-                for (Map.Entry<String, String> entry : elementDefaultAttributes.entrySet()) {
-                    if (getAttributeValue(null, entry.getKey()) != null) {
-                        continue; // an explicit value overrides the default
-                    }
-
-                    int i = (attributeCount++) * 4;
-                    attributes = ensureCapacity(attributes, i + 4);
-                    attributes[i] = "";
-                    attributes[i + 1] = null;
-                    attributes[i + 2] = entry.getKey();
-                    attributes[i + 3] = entry.getValue();
-                }
-            }
-        }
-
-        elementStack[sp] = namespace;
-        elementStack[sp + 1] = prefix;
-        elementStack[sp + 2] = name;
-    }
-
-    /**
-     * Reads an entity reference from the buffer, resolves it, and writes the
-     * resolved entity to {@code out}. If the entity cannot be read or resolved,
-     * {@code out} will contain the partial entity reference.
-     */
-    private void readEntity(StringBuilder out, boolean isEntityToken, boolean throwOnResolveFailure,
-            ValueContext valueContext) throws IOException, XmlPullParserException {
-        int start = out.length();
-
-        if (buffer[position++] != '&') {
-            throw new AssertionError();
-        }
-
-        out.append('&');
-
-        while (true) {
-            int c = peekCharacter();
-
-            if (c == ';') {
-                out.append(';');
-                position++;
-                break;
-
-            } else if (c >= 128
-                    || (c >= '0' && c <= '9')
-                    || (c >= 'a' && c <= 'z')
-                    || (c >= 'A' && c <= 'Z')
-                    || c == '_'
-                    || c == '-'
-                    || c == '#') {
-                position++;
-                out.append((char) c);
-
-            } else if (relaxed) {
-                // intentionally leave the partial reference in 'out'
-                return;
-
-            } else {
-                throw new XmlPullParserException("unterminated entity ref", this, null);
-            }
-        }
-
-        String code = out.substring(start + 1, out.length() - 1);
-
-        if (isEntityToken) {
-            name = code;
-        }
-
-        if (code.startsWith("#")) {
-            try {
-                int c = code.startsWith("#x")
-                        ? Integer.parseInt(code.substring(2), 16)
-                        : Integer.parseInt(code.substring(1));
-                out.delete(start, out.length());
-                out.appendCodePoint(c);
-                unresolved = false;
-                return;
-            } catch (NumberFormatException notANumber) {
-                throw new XmlPullParserException("Invalid character reference: &" + code);
-            } catch (IllegalArgumentException invalidCodePoint) {
-                throw new XmlPullParserException("Invalid character reference: &" + code);
-            }
-        }
-
-        if (valueContext == ValueContext.ENTITY_DECLARATION) {
-            // keep the unresolved &code; in the text to resolve later
-            return;
-        }
-
-        String defaultEntity = DEFAULT_ENTITIES.get(code);
-        if (defaultEntity != null) {
-            out.delete(start, out.length());
-            unresolved = false;
-            out.append(defaultEntity);
-            return;
-        }
-
-        char[] resolved;
-        if (documentEntities != null && (resolved = documentEntities.get(code)) != null) {
-            out.delete(start, out.length());
-            unresolved = false;
-            if (processDocDecl) {
-                pushContentSource(resolved); // parse the entity as XML
-            } else {
-                out.append(resolved); // include the entity value as text
-            }
-            return;
-        }
-
-        /*
-         * The parser skipped an external DTD, and now we've encountered an
-         * unknown entity that could have been declared there. Map it to the
-         * empty string. This is dishonest, but it's consistent with Android's
-         * old ExpatPullParser.
-         */
-        if (systemId != null) {
-            out.delete(start, out.length());
-            return;
-        }
-
-        // keep the unresolved entity "&code;" in the text for relaxed clients
-        unresolved = true;
-        if (throwOnResolveFailure) {
-            checkRelaxed("unresolved: &" + code + ";");
-        }
-    }
-
-    /**
-     * Where a value is found impacts how that value is interpreted. For
-     * example, in attributes, "\n" must be replaced with a space character. In
-     * text, "]]>" is forbidden. In entity declarations, named references are
-     * not resolved.
-     */
-    enum ValueContext {
-        ATTRIBUTE,
-        TEXT,
-        ENTITY_DECLARATION
-    }
-
-    /**
-     * Returns the current text or attribute value. This also has the side
-     * effect of setting isWhitespace to false if a non-whitespace character is
-     * encountered.
-     *
-     * @param delimiter {@code <} for text, {@code "} and {@code '} for quoted
-     *     attributes, or a space for unquoted attributes.
-     */
-    private String readValue(char delimiter, boolean resolveEntities, boolean throwOnResolveFailure,
-            ValueContext valueContext) throws IOException, XmlPullParserException {
-
-        /*
-         * This method returns all of the characters from the current position
-         * through to an appropriate delimiter.
-         *
-         * If we're lucky (which we usually are), we'll return a single slice of
-         * the buffer. This fast path avoids allocating a string builder.
-         *
-         * There are 6 unlucky characters we could encounter:
-         *  - "&":  entities must be resolved.
-         *  - "%":  parameter entities are unsupported in entity values.
-         *  - "<":  this isn't permitted in attributes unless relaxed.
-         *  - "]":  this requires a lookahead to defend against the forbidden
-         *          CDATA section delimiter "]]>".
-         *  - "\r": If a "\r" is followed by a "\n", we discard the "\r". If it
-         *          isn't followed by "\n", we replace "\r" with either a "\n"
-         *          in text nodes or a space in attribute values.
-         *  - "\n": In attribute values, "\n" must be replaced with a space.
-         *
-         * We could also get unlucky by needing to refill the buffer midway
-         * through the text.
-         */
-
-        int start = position;
-        StringBuilder result = null;
-
-        // if a text section was already started, prefix the start
-        if (valueContext == ValueContext.TEXT && text != null) {
-            result = new StringBuilder();
-            result.append(text);
-        }
-
-        while (true) {
-
-            /*
-             * Make sure we have at least a single character to read from the
-             * buffer. This mutates the buffer, so save the partial result
-             * to the slow path string builder first.
-             */
-            if (position >= limit) {
-                if (start < position) {
-                    if (result == null) {
-                        result = new StringBuilder();
-                    }
-                    result.append(buffer, start, position - start);
-                }
-                if (!fillBuffer(1)) {
-                    return result != null ? result.toString() : "";
-                }
-                start = position;
-            }
-
-            char c = buffer[position];
-
-            if (c == delimiter
-                    || (delimiter == ' ' && (c <= ' ' || c == '>'))
-                    || c == '&' && !resolveEntities) {
-                break;
-            }
-
-            if (c != '\r'
-                    && (c != '\n' || valueContext != ValueContext.ATTRIBUTE)
-                    && c != '&'
-                    && c != '<'
-                    && (c != ']' || valueContext != ValueContext.TEXT)
-                    && (c != '%' || valueContext != ValueContext.ENTITY_DECLARATION)) {
-                isWhitespace &= (c <= ' ');
-                position++;
-                continue;
-            }
-
-            /*
-             * We've encountered an unlucky character! Convert from fast
-             * path to slow path if we haven't done so already.
-             */
-            if (result == null) {
-                result = new StringBuilder();
-            }
-            result.append(buffer, start, position - start);
-
-            if (c == '\r') {
-                if ((position + 1 < limit || fillBuffer(2)) && buffer[position + 1] == '\n') {
-                    position++;
-                }
-                c = (valueContext == ValueContext.ATTRIBUTE) ? ' ' : '\n';
-
-            } else if (c == '\n') {
-                c = ' ';
-
-            } else if (c == '&') {
-                isWhitespace = false; // TODO: what if the entity resolves to whitespace?
-                readEntity(result, false, throwOnResolveFailure, valueContext);
-                start = position;
-                continue;
-
-            } else if (c == '<') {
-                if (valueContext == ValueContext.ATTRIBUTE) {
-                    checkRelaxed("Illegal: \"<\" inside attribute value");
-                }
-                isWhitespace = false;
-
-            } else if (c == ']') {
-                if ((position + 2 < limit || fillBuffer(3))
-                        && buffer[position + 1] == ']' && buffer[position + 2] == '>') {
-                    checkRelaxed("Illegal: \"]]>\" outside CDATA section");
-                }
-                isWhitespace = false;
-
-            } else if (c == '%') {
-                throw new XmlPullParserException("This parser doesn't support parameter entities",
-                        this, null);
-
-            } else {
-                throw new AssertionError();
-            }
-
-            position++;
-            result.append(c);
-            start = position;
-        }
-
-        if (result == null) {
-            return stringPool.get(buffer, start, position - start);
-        } else {
-            result.append(buffer, start, position - start);
-            return result.toString();
-        }
-    }
-
-    private void read(char expected) throws IOException, XmlPullParserException {
-        int c = peekCharacter();
-        if (c != expected) {
-            checkRelaxed("expected: '" + expected + "' actual: '" + ((char) c) + "'");
-            if (c == -1) {
-                return; // On EOF, don't move position beyond limit
-            }
-        }
-        position++;
-    }
-
-    private void read(char[] chars) throws IOException, XmlPullParserException {
-        if (position + chars.length > limit && !fillBuffer(chars.length)) {
-            checkRelaxed("expected: '" + new String(chars) + "' but was EOF");
-            return;
-        }
-
-        // TODO: replace with Arrays.equals(buffer, position, delimiter, 0, delimiter.length)
-        // when the VM has better method inlining
-        for (int i = 0; i < chars.length; i++) {
-            if (buffer[position + i] != chars[i]) {
-                checkRelaxed("expected: \"" + new String(chars) + "\" but was \""
-                        + new String(buffer, position, chars.length) + "...\"");
-            }
-        }
-
-        position += chars.length;
-    }
-
-    private int peekCharacter() throws IOException, XmlPullParserException {
-        if (position < limit || fillBuffer(1)) {
-            return buffer[position];
-        }
-        return -1;
-    }
-
-    /**
-     * Returns true once {@code limit - position >= minimum}. If the data is
-     * exhausted before that many characters are available, this returns
-     * false.
-     */
-    private boolean fillBuffer(int minimum) throws IOException, XmlPullParserException {
-        // If we've exhausted the current content source, remove it
-        while (nextContentSource != null) {
-            if (position < limit) {
-                throw new XmlPullParserException("Unbalanced entity!", this, null);
-            }
-            popContentSource();
-            if (limit - position >= minimum) {
-                return true;
-            }
-        }
-
-        // Before clobbering the old characters, update where buffer starts
-        for (int i = 0; i < position; i++) {
-            if (buffer[i] == '\n') {
-                bufferStartLine++;
-                bufferStartColumn = 0;
-            } else {
-                bufferStartColumn++;
-            }
-        }
-
-        if (bufferCapture != null) {
-            bufferCapture.append(buffer, 0, position);
-        }
-
-        if (limit != position) {
-            limit -= position;
-            System.arraycopy(buffer, position, buffer, 0, limit);
-        } else {
-            limit = 0;
-        }
-
-        position = 0;
-        int total;
-        while ((total = reader.read(buffer, limit, buffer.length - limit)) != -1) {
-            limit += total;
-            if (limit >= minimum) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns an element or attribute name. This is always non-empty for
-     * non-relaxed parsers.
-     */
-    private String readName() throws IOException, XmlPullParserException {
-        if (position >= limit && !fillBuffer(1)) {
-            checkRelaxed("name expected");
-            return "";
-        }
-
-        int start = position;
-        StringBuilder result = null;
-
-        // read the first character
-        char c = buffer[position];
-        if ((c >= 'a' && c <= 'z')
-                || (c >= 'A' && c <= 'Z')
-                || c == '_'
-                || c == ':'
-                || c >= '\u00c0' // TODO: check the XML spec
-                || relaxed) {
-            position++;
-        } else {
-            checkRelaxed("name expected");
-            return "";
-        }
-
-        while (true) {
-            /*
-             * Make sure we have at least a single character to read from the
-             * buffer. This mutates the buffer, so save the partial result
-             * to the slow path string builder first.
-             */
-            if (position >= limit) {
-                if (result == null) {
-                    result = new StringBuilder();
-                }
-                result.append(buffer, start, position - start);
-                if (!fillBuffer(1)) {
-                    return result.toString();
-                }
-                start = position;
-            }
-
-            // read another character
-            c = buffer[position];
-            if ((c >= 'a' && c <= 'z')
-                    || (c >= 'A' && c <= 'Z')
-                    || (c >= '0' && c <= '9')
-                    || c == '_'
-                    || c == '-'
-                    || c == ':'
-                    || c == '.'
-                    || c >= '\u00b7') {  // TODO: check the XML spec
-                position++;
-                continue;
-            }
-
-            // we encountered a non-name character. done!
-            if (result == null) {
-                return stringPool.get(buffer, start, position - start);
-            } else {
-                result.append(buffer, start, position - start);
-                return result.toString();
-            }
-        }
-    }
-
-    private void skip() throws IOException, XmlPullParserException {
-        while (position < limit || fillBuffer(1)) {
-            int c = buffer[position];
-            if (c > ' ') {
-                break;
-            }
-            position++;
-        }
-    }
-
-    //  public part starts here...
-
-    public void setInput(Reader reader) throws XmlPullParserException {
-        this.reader = reader;
-
-        type = START_DOCUMENT;
-        parsedTopLevelStartTag = false;
-        name = null;
-        namespace = null;
-        degenerated = false;
-        attributeCount = -1;
-        encoding = null;
-        version = null;
-        standalone = null;
-
-        if (reader == null) {
-            return;
-        }
-
-        position = 0;
-        limit = 0;
-        bufferStartLine = 0;
-        bufferStartColumn = 0;
-        depth = 0;
-        documentEntities = null;
-    }
-
-    public void setInput(InputStream is, String charset) throws XmlPullParserException {
-        position = 0;
-        limit = 0;
-        boolean detectCharset = (charset == null);
-
-        if (is == null) {
-            throw new IllegalArgumentException("is == null");
-        }
-
-        try {
-            if (detectCharset) {
-                // read the four bytes looking for an indication of the encoding in use
-                int firstFourBytes = 0;
-                while (limit < 4) {
-                    int i = is.read();
-                    if (i == -1) {
-                        break;
-                    }
-                    firstFourBytes = (firstFourBytes << 8) | i;
-                    buffer[limit++] = (char) i;
-                }
-
-                if (limit == 4) {
-                    switch (firstFourBytes) {
-                    case 0x00000FEFF: // UTF-32BE BOM
-                        charset = "UTF-32BE";
-                        limit = 0;
-                        break;
-
-                    case 0x0FFFE0000: // UTF-32LE BOM
-                        charset = "UTF-32LE";
-                        limit = 0;
-                        break;
-
-                    case 0x0000003c: // '<' in UTF-32BE
-                        charset = "UTF-32BE";
-                        buffer[0] = '<';
-                        limit = 1;
-                        break;
-
-                    case 0x03c000000: // '<' in UTF-32LE
-                        charset = "UTF-32LE";
-                        buffer[0] = '<';
-                        limit = 1;
-                        break;
-
-                    case 0x0003c003f: // "<?" in UTF-16BE
-                        charset = "UTF-16BE";
-                        buffer[0] = '<';
-                        buffer[1] = '?';
-                        limit = 2;
-                        break;
-
-                    case 0x03c003f00: // "<?" in UTF-16LE
-                        charset = "UTF-16LE";
-                        buffer[0] = '<';
-                        buffer[1] = '?';
-                        limit = 2;
-                        break;
-
-                    case 0x03c3f786d: // "<?xm" in ASCII etc.
-                        while (true) {
-                            int i = is.read();
-                            if (i == -1) {
-                                break;
-                            }
-                            buffer[limit++] = (char) i;
-                            if (i == '>') {
-                                String s = new String(buffer, 0, limit);
-                                int i0 = s.indexOf("encoding");
-                                if (i0 != -1) {
-                                    while (s.charAt(i0) != '"' && s.charAt(i0) != '\'') {
-                                        i0++;
-                                    }
-                                    char deli = s.charAt(i0++);
-                                    int i1 = s.indexOf(deli, i0);
-                                    charset = s.substring(i0, i1);
-                                }
-                                break;
-                            }
-                        }
-                        break;
-
-                    default:
-                        // handle a byte order mark followed by something other than <?
-                        if ((firstFourBytes & 0x0ffff0000) == 0x0feff0000) {
-                            charset = "UTF-16BE";
-                            buffer[0] = (char) ((buffer[2] << 8) | buffer[3]);
-                            limit = 1;
-                        } else if ((firstFourBytes & 0x0ffff0000) == 0x0fffe0000) {
-                            charset = "UTF-16LE";
-                            buffer[0] = (char) ((buffer[3] << 8) | buffer[2]);
-                            limit = 1;
-                        } else if ((firstFourBytes & 0x0ffffff00) == 0x0efbbbf00) {
-                            charset = "UTF-8";
-                            buffer[0] = buffer[3];
-                            limit = 1;
-                        }
-                    }
-                }
-            }
-
-            if (charset == null) {
-                charset = "UTF-8";
-            }
-
-            int savedLimit = limit;
-            setInput(new InputStreamReader(is, charset));
-            encoding = charset;
-            limit = savedLimit;
-
-            /*
-             * Skip the optional BOM if we didn't above. This decrements limit
-             * rather than incrementing position so that <?xml version='1.0'?>
-             * is still at character 0.
-             */
-            if (!detectCharset && peekCharacter() == 0xfeff) {
-                limit--;
-                System.arraycopy(buffer, 1, buffer, 0, limit);
-            }
-        } catch (Exception e) {
-            throw new XmlPullParserException("Invalid stream or encoding: " + e, this, e);
-        }
-    }
-
-    public void close() throws IOException {
-        if (reader != null) {
-            reader.close();
-        }
-    }
-
-    public boolean getFeature(String feature) {
-        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature)) {
-            return processNsp;
-        } else if (FEATURE_RELAXED.equals(feature)) {
-            return relaxed;
-        } else if (FEATURE_PROCESS_DOCDECL.equals(feature)) {
-            return processDocDecl;
-        } else {
-            return false;
-        }
-    }
-
-    public String getInputEncoding() {
-        return encoding;
-    }
-
-    public void defineEntityReplacementText(String entity, String value)
-            throws XmlPullParserException {
-        if (processDocDecl) {
-            throw new IllegalStateException(
-                    "Entity replacement text may not be defined with DOCTYPE processing enabled.");
-        }
-        if (reader == null) {
-            throw new IllegalStateException(
-                    "Entity replacement text must be defined after setInput()");
-        }
-        if (documentEntities == null) {
-            documentEntities = new HashMap<String, char[]>();
-        }
-        documentEntities.put(entity, value.toCharArray());
-    }
-
-    public Object getProperty(String property) {
-        if (property.equals(PROPERTY_XMLDECL_VERSION)) {
-            return version;
-        } else if (property.equals(PROPERTY_XMLDECL_STANDALONE)) {
-            return standalone;
-        } else if (property.equals(PROPERTY_LOCATION)) {
-            return location != null ? location : reader.toString();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the root element's name if it was declared in the DTD. This
-     * equals the first tag's name for valid documents.
-     */
-    public String getRootElementName() {
-        return rootElementName;
-    }
-
-    /**
-     * Returns the document's system ID if it was declared. This is typically a
-     * string like {@code http://www.w3.org/TR/html4/strict.dtd}.
-     */
-    public String getSystemId() {
-        return systemId;
-    }
-
-    /**
-     * Returns the document's public ID if it was declared. This is typically a
-     * string like {@code -//W3C//DTD HTML 4.01//EN}.
-     */
-    public String getPublicId() {
-        return publicId;
-    }
-
-    public int getNamespaceCount(int depth) {
-        if (depth > this.depth) {
-            throw new IndexOutOfBoundsException();
-        }
-        return nspCounts[depth];
-    }
-
-    public String getNamespacePrefix(int pos) {
-        return nspStack[pos * 2];
-    }
-
-    public String getNamespaceUri(int pos) {
-        return nspStack[(pos * 2) + 1];
-    }
-
-    public String getNamespace(String prefix) {
-        if ("xml".equals(prefix)) {
-            return "http://www.w3.org/XML/1998/namespace";
-        }
-        if ("xmlns".equals(prefix)) {
-            return "http://www.w3.org/2000/xmlns/";
-        }
-
-        for (int i = (getNamespaceCount(depth) << 1) - 2; i >= 0; i -= 2) {
-            if (prefix == null) {
-                if (nspStack[i] == null) {
-                    return nspStack[i + 1];
-                }
-            } else if (prefix.equals(nspStack[i])) {
-                return nspStack[i + 1];
-            }
-        }
-        return null;
-    }
-
-    public int getDepth() {
-        return depth;
-    }
-
-    public String getPositionDescription() {
-        StringBuilder buf = new StringBuilder(type < TYPES.length ? TYPES[type] : "unknown");
-        buf.append(' ');
-
-        if (type == START_TAG || type == END_TAG) {
-            if (degenerated) {
-                buf.append("(empty) ");
-            }
-            buf.append('<');
-            if (type == END_TAG) {
-                buf.append('/');
-            }
-
-            if (prefix != null) {
-                buf.append("{" + namespace + "}" + prefix + ":");
-            }
-            buf.append(name);
-
-            int cnt = attributeCount * 4;
-            for (int i = 0; i < cnt; i += 4) {
-                buf.append(' ');
-                if (attributes[i + 1] != null) {
-                    buf.append("{" + attributes[i] + "}" + attributes[i + 1] + ":");
-                }
-                buf.append(attributes[i + 2] + "='" + attributes[i + 3] + "'");
-            }
-
-            buf.append('>');
-        } else if (type == IGNORABLE_WHITESPACE) {
-            ;
-        } else if (type != TEXT) {
-            buf.append(getText());
-        } else if (isWhitespace) {
-            buf.append("(whitespace)");
-        } else {
-            String text = getText();
-            if (text.length() > 16) {
-                text = text.substring(0, 16) + "...";
-            }
-            buf.append(text);
-        }
-
-        buf.append("@" + getLineNumber() + ":" + getColumnNumber());
-        if (location != null) {
-            buf.append(" in ");
-            buf.append(location);
-        } else if (reader != null) {
-            buf.append(" in ");
-            buf.append(reader.toString());
-        }
-        return buf.toString();
-    }
-
-    public int getLineNumber() {
-        int result = bufferStartLine;
-        for (int i = 0; i < position; i++) {
-            if (buffer[i] == '\n') {
-                result++;
-            }
-        }
-        return result + 1; // the first line is '1'
-    }
-
-    public int getColumnNumber() {
-        int result = bufferStartColumn;
-        for (int i = 0; i < position; i++) {
-            if (buffer[i] == '\n') {
-                result = 0;
-            } else {
-                result++;
-            }
-        }
-        return result + 1; // the first column is '1'
-    }
-
-    public boolean isWhitespace() throws XmlPullParserException {
-        if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT) {
-            throw new XmlPullParserException(ILLEGAL_TYPE, this, null);
-        }
-        return isWhitespace;
-    }
-
-    public String getText() {
-        if (type < TEXT || (type == ENTITY_REF && unresolved)) {
-            return null;
-        } else if (text == null) {
-            return "";
-        } else {
-            return text;
-        }
-    }
-
-    public char[] getTextCharacters(int[] poslen) {
-        String text = getText();
-        if (text == null) {
-            poslen[0] = -1;
-            poslen[1] = -1;
-            return null;
-        }
-        char[] result = text.toCharArray();
-        poslen[0] = 0;
-        poslen[1] = result.length;
-        return result;
-    }
-
-    public String getNamespace() {
-        return namespace;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getPrefix() {
-        return prefix;
-    }
-
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        if (type != START_TAG) {
-            throw new XmlPullParserException(ILLEGAL_TYPE, this, null);
-        }
-        return degenerated;
-    }
-
-    public int getAttributeCount() {
-        return attributeCount;
-    }
-
-    public String getAttributeType(int index) {
-        return "CDATA";
-    }
-
-    public boolean isAttributeDefault(int index) {
-        return false;
-    }
-
-    public String getAttributeNamespace(int index) {
-        if (index >= attributeCount) {
-            throw new IndexOutOfBoundsException();
-        }
-        return attributes[index * 4];
-    }
-
-    public String getAttributeName(int index) {
-        if (index >= attributeCount) {
-            throw new IndexOutOfBoundsException();
-        }
-        return attributes[(index * 4) + 2];
-    }
-
-    public String getAttributePrefix(int index) {
-        if (index >= attributeCount) {
-            throw new IndexOutOfBoundsException();
-        }
-        return attributes[(index * 4) + 1];
-    }
-
-    public String getAttributeValue(int index) {
-        if (index >= attributeCount) {
-            throw new IndexOutOfBoundsException();
-        }
-        return attributes[(index * 4) + 3];
-    }
-
-    public String getAttributeValue(String namespace, String name) {
-        for (int i = (attributeCount * 4) - 4; i >= 0; i -= 4) {
-            if (attributes[i + 2].equals(name)
-                    && (namespace == null || attributes[i].equals(namespace))) {
-                return attributes[i + 3];
-            }
-        }
-
-        return null;
-    }
-
-    public int getEventType() throws XmlPullParserException {
-        return type;
-    }
-
-    // utility methods to make XML parsing easier ...
-
-    public int nextTag() throws XmlPullParserException, IOException {
-        next();
-        if (type == TEXT && isWhitespace) {
-            next();
-        }
-
-        if (type != END_TAG && type != START_TAG) {
-            throw new XmlPullParserException("unexpected type", this, null);
-        }
-
-        return type;
-    }
-
-    public void require(int type, String namespace, String name)
-            throws XmlPullParserException, IOException {
-        if (type != this.type
-                || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName()))) {
-            throw new XmlPullParserException(
-                    "expected: " + TYPES[type] + " {" + namespace + "}" + name, this, null);
-        }
-    }
-
-    public String nextText() throws XmlPullParserException, IOException {
-        if (type != START_TAG) {
-            throw new XmlPullParserException("precondition: START_TAG", this, null);
-        }
-
-        next();
-
-        String result;
-        if (type == TEXT) {
-            result = getText();
-            next();
-        } else {
-            result = "";
-        }
-
-        if (type != END_TAG) {
-            throw new XmlPullParserException("END_TAG expected", this, null);
-        }
-
-        return result;
-    }
-
-    public void setFeature(String feature, boolean value) throws XmlPullParserException {
-        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature)) {
-            processNsp = value;
-        } else if (XmlPullParser.FEATURE_PROCESS_DOCDECL.equals(feature)) {
-            processDocDecl = value;
-        } else if (FEATURE_RELAXED.equals(feature)) {
-            relaxed = value;
-        } else {
-            throw new XmlPullParserException("unsupported feature: " + feature, this, null);
-        }
-    }
-
-    public void setProperty(String property, Object value) throws XmlPullParserException {
-        if (property.equals(PROPERTY_LOCATION)) {
-            location = String.valueOf(value);
-        } else {
-            throw new XmlPullParserException("unsupported property: " + property);
-        }
-    }
-
-    /**
-     * A chain of buffers containing XML content. Each content source contains
-     * the parser's primary read buffer or the characters of entities actively
-     * being parsed.
-     *
-     * <p>For example, note the buffers needed to parse this document:
-     * <pre>   {@code
-     *   <!DOCTYPE foo [
-     *       <!ENTITY baz "ghi">
-     *       <!ENTITY bar "def &baz; jkl">
-     *   ]>
-     *   <foo>abc &bar; mno</foo>
-     * }</pre>
-     *
-     * <p>Things get interesting when the bar entity is encountered. At that
-     * point two buffers are active:
-     * <ol>
-     * <li>The value for the bar entity, containing {@code "def &baz; jkl"}
-     * <li>The parser's primary read buffer, containing {@code " mno</foo>"}
-     * </ol>
-     * <p>The parser will return the characters {@code "def "} from the bar
-     * entity's buffer, and then it will encounter the baz entity. To handle
-     * that, three buffers will be active:
-     * <ol>
-     * <li>The value for the baz entity, containing {@code "ghi"}
-     * <li>The remaining value for the bar entity, containing {@code " jkl"}
-     * <li>The parser's primary read buffer, containing {@code " mno</foo>"}
-     * </ol>
-     * <p>The parser will then return the characters {@code ghi jkl mno} in that
-     * sequence by reading each buffer in sequence.
-     */
-    static class ContentSource {
-        private final ContentSource next;
-        private final char[] buffer;
-        private final int position;
-        private final int limit;
-        ContentSource(ContentSource next, char[] buffer, int position, int limit) {
-            this.next = next;
-            this.buffer = buffer;
-            this.position = position;
-            this.limit = limit;
-        }
-    }
-
-    /**
-     * Prepends the characters of {@code newBuffer} to be read before the
-     * current buffer.
-     */
-    private void pushContentSource(char[] newBuffer) {
-        nextContentSource = new ContentSource(nextContentSource, buffer, position, limit);
-        buffer = newBuffer;
-        position = 0;
-        limit = newBuffer.length;
-    }
-
-    /**
-     * Replaces the current exhausted buffer with the next buffer in the chain.
-     */
-    private void popContentSource() {
-        buffer = nextContentSource.buffer;
-        position = nextContentSource.position;
-        limit = nextContentSource.limit;
-        nextContentSource = nextContentSource.next;
-    }
-}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
deleted file mode 100644
index 25f0924..0000000
--- a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The  above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE. */
-
-
-package org.kxml2.io;
-
-import java.io.*;
-import java.util.Locale;
-import org.xmlpull.v1.*;
-
-public class KXmlSerializer implements XmlSerializer {
-
-    private static final int BUFFER_LEN = 8192;
-    private final char[] mText = new char[BUFFER_LEN];
-    private int mPos;
-
-    //    static final String UNDEFINED = ":";
-
-    private Writer writer;
-
-    private boolean pending;
-    private int auto;
-    private int depth;
-
-    private String[] elementStack = new String[12];
-    //nsp/prefix/name
-    private int[] nspCounts = new int[4];
-    private String[] nspStack = new String[8];
-    //prefix/nsp; both empty are ""
-    private boolean[] indent = new boolean[4];
-    private boolean unicode;
-    private String encoding;
-
-    private void append(char c) throws IOException {
-        if (mPos >= BUFFER_LEN) {
-            flushBuffer();
-        }
-        mText[mPos++] = c;
-    }
-
-    private void append(String str, int i, int length) throws IOException {
-        while (length > 0) {
-            if (mPos == BUFFER_LEN) {
-                flushBuffer();
-            }
-            int batch = BUFFER_LEN - mPos;
-            if (batch > length) {
-                batch = length;
-            }
-            str.getChars(i, i + batch, mText, mPos);
-            i += batch;
-            length -= batch;
-            mPos += batch;
-        }
-    }
-
-    private void append(String str) throws IOException {
-        append(str, 0, str.length());
-    }
-
-    private final void flushBuffer() throws IOException {
-        if(mPos > 0) {
-            writer.write(mText, 0, mPos);
-            writer.flush();
-            mPos = 0;
-        }
-    }
-
-    private final void check(boolean close) throws IOException {
-        if (!pending)
-            return;
-
-        depth++;
-        pending = false;
-
-        if (indent.length <= depth) {
-            boolean[] hlp = new boolean[depth + 4];
-            System.arraycopy(indent, 0, hlp, 0, depth);
-            indent = hlp;
-        }
-        indent[depth] = indent[depth - 1];
-
-        for (int i = nspCounts[depth - 1]; i < nspCounts[depth]; i++) {
-            append(" xmlns");
-            if (!nspStack[i * 2].isEmpty()) {
-                append(':');
-                append(nspStack[i * 2]);
-            }
-            else if (getNamespace().isEmpty() && !nspStack[i * 2 + 1].isEmpty())
-                throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
-            append("=\"");
-            writeEscaped(nspStack[i * 2 + 1], '"');
-            append('"');
-        }
-
-        if (nspCounts.length <= depth + 1) {
-            int[] hlp = new int[depth + 8];
-            System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
-            nspCounts = hlp;
-        }
-
-        nspCounts[depth + 1] = nspCounts[depth];
-        //   nspCounts[depth + 2] = nspCounts[depth];
-
-        if (close) {
-            append(" />");
-        } else {
-            append('>');
-        }
-    }
-
-    private final void writeEscaped(String s, int quot) throws IOException {
-        for (int i = 0; i < s.length(); i++) {
-            char c = s.charAt(i);
-            switch (c) {
-                case '\n':
-                case '\r':
-                case '\t':
-                    if(quot == -1)
-                        append(c);
-                    else
-                        append("&#"+((int) c)+';');
-                    break;
-                case '&' :
-                    append("&amp;");
-                    break;
-                case '>' :
-                    append("&gt;");
-                    break;
-                case '<' :
-                    append("&lt;");
-                    break;
-                default:
-                    if (c == quot) {
-                        append(c == '"' ? "&quot;" : "&apos;");
-                        break;
-                    }
-                    // BEGIN Android-changed: refuse to output invalid characters
-                    // See http://www.w3.org/TR/REC-xml/#charsets for definition.
-                    // No other Java XML writer we know of does this, but no Java
-                    // XML reader we know of is able to parse the bad output we'd
-                    // otherwise generate.
-                    // Note: tab, newline, and carriage return have already been
-                    // handled above.
-                    boolean allowedInXml = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
-                    if (allowedInXml) {
-                        if (unicode || c < 127) {
-                            append(c);
-                        } else {
-                            append("&#" + ((int) c) + ";");
-                        }
-                    } else if (Character.isHighSurrogate(c) && i < s.length() - 1) {
-                        writeSurrogate(c, s.charAt(i + 1));
-                        ++i;
-                    } else {
-                        reportInvalidCharacter(c);
-                    }
-                    // END Android-changed
-            }
-        }
-    }
-
-    // BEGIN Android-added
-    private static void reportInvalidCharacter(char ch) {
-        throw new IllegalArgumentException("Illegal character (U+" + Integer.toHexString((int) ch) + ")");
-    }
-    // END Android-added
-
-    /*
-        private final void writeIndent() throws IOException {
-            writer.write("\r\n");
-            for (int i = 0; i < depth; i++)
-                writer.write(' ');
-        }*/
-
-    public void docdecl(String dd) throws IOException {
-        append("<!DOCTYPE");
-        append(dd);
-        append('>');
-    }
-
-    public void endDocument() throws IOException {
-        while (depth > 0) {
-            endTag(elementStack[depth * 3 - 3], elementStack[depth * 3 - 1]);
-        }
-        flush();
-    }
-
-    public void entityRef(String name) throws IOException {
-        check(false);
-        append('&');
-        append(name);
-        append(';');
-    }
-
-    public boolean getFeature(String name) {
-        //return false;
-        return (
-            "http://xmlpull.org/v1/doc/features.html#indent-output"
-                .equals(
-                name))
-            ? indent[depth]
-            : false;
-    }
-
-    public String getPrefix(String namespace, boolean create) {
-        try {
-            return getPrefix(namespace, false, create);
-        }
-        catch (IOException e) {
-            throw new RuntimeException(e.toString());
-        }
-    }
-
-    private final String getPrefix(
-        String namespace,
-        boolean includeDefault,
-        boolean create)
-        throws IOException {
-
-        for (int i = nspCounts[depth + 1] * 2 - 2;
-            i >= 0;
-            i -= 2) {
-            if (nspStack[i + 1].equals(namespace)
-                && (includeDefault || !nspStack[i].isEmpty())) {
-                String cand = nspStack[i];
-                for (int j = i + 2;
-                    j < nspCounts[depth + 1] * 2;
-                    j++) {
-                    if (nspStack[j].equals(cand)) {
-                        cand = null;
-                        break;
-                    }
-                }
-                if (cand != null)
-                    return cand;
-            }
-        }
-
-        if (!create)
-            return null;
-
-        String prefix;
-
-        if (namespace.isEmpty())
-            prefix = "";
-        else {
-            do {
-                prefix = "n" + (auto++);
-                for (int i = nspCounts[depth + 1] * 2 - 2;
-                    i >= 0;
-                    i -= 2) {
-                    if (prefix.equals(nspStack[i])) {
-                        prefix = null;
-                        break;
-                    }
-                }
-            }
-            while (prefix == null);
-        }
-
-        boolean p = pending;
-        pending = false;
-        setPrefix(prefix, namespace);
-        pending = p;
-        return prefix;
-    }
-
-    public Object getProperty(String name) {
-        throw new RuntimeException("Unsupported property");
-    }
-
-    public void ignorableWhitespace(String s)
-        throws IOException {
-        text(s);
-    }
-
-    public void setFeature(String name, boolean value) {
-        if ("http://xmlpull.org/v1/doc/features.html#indent-output"
-            .equals(name)) {
-            indent[depth] = value;
-        }
-        else
-            throw new RuntimeException("Unsupported Feature");
-    }
-
-    public void setProperty(String name, Object value) {
-        throw new RuntimeException(
-            "Unsupported Property:" + value);
-    }
-
-    public void setPrefix(String prefix, String namespace)
-        throws IOException {
-
-        check(false);
-        if (prefix == null)
-            prefix = "";
-        if (namespace == null)
-            namespace = "";
-
-        String defined = getPrefix(namespace, true, false);
-
-        // boil out if already defined
-
-        if (prefix.equals(defined))
-            return;
-
-        int pos = (nspCounts[depth + 1]++) << 1;
-
-        if (nspStack.length < pos + 1) {
-            String[] hlp = new String[nspStack.length + 16];
-            System.arraycopy(nspStack, 0, hlp, 0, pos);
-            nspStack = hlp;
-        }
-
-        nspStack[pos++] = prefix;
-        nspStack[pos] = namespace;
-    }
-
-    public void setOutput(Writer writer) {
-        this.writer = writer;
-
-        // elementStack = new String[12]; //nsp/prefix/name
-        //nspCounts = new int[4];
-        //nspStack = new String[8]; //prefix/nsp
-        //indent = new boolean[4];
-
-        nspCounts[0] = 2;
-        nspCounts[1] = 2;
-        nspStack[0] = "";
-        nspStack[1] = "";
-        nspStack[2] = "xml";
-        nspStack[3] = "http://www.w3.org/XML/1998/namespace";
-        pending = false;
-        auto = 0;
-        depth = 0;
-
-        unicode = false;
-    }
-
-    public void setOutput(OutputStream os, String encoding)
-        throws IOException {
-        if (os == null)
-            throw new IllegalArgumentException("os == null");
-        setOutput(
-            encoding == null
-                ? new OutputStreamWriter(os)
-                : new OutputStreamWriter(os, encoding));
-        this.encoding = encoding;
-        if (encoding != null && encoding.toLowerCase(Locale.US).startsWith("utf")) {
-            unicode = true;
-        }
-    }
-
-    public void startDocument(String encoding, Boolean standalone) throws IOException {
-        append("<?xml version='1.0' ");
-
-        if (encoding != null) {
-            this.encoding = encoding;
-            if (encoding.toLowerCase(Locale.US).startsWith("utf")) {
-                unicode = true;
-            }
-        }
-
-        if (this.encoding != null) {
-            append("encoding='");
-            append(this.encoding);
-            append("' ");
-        }
-
-        if (standalone != null) {
-            append("standalone='");
-            append(standalone.booleanValue() ? "yes" : "no");
-            append("' ");
-        }
-        append("?>");
-    }
-
-    public XmlSerializer startTag(String namespace, String name)
-        throws IOException {
-        check(false);
-
-        //        if (namespace == null)
-        //            namespace = "";
-
-        if (indent[depth]) {
-            append("\r\n");
-            for (int i = 0; i < depth; i++)
-                append("  ");
-        }
-
-        int esp = depth * 3;
-
-        if (elementStack.length < esp + 3) {
-            String[] hlp = new String[elementStack.length + 12];
-            System.arraycopy(elementStack, 0, hlp, 0, esp);
-            elementStack = hlp;
-        }
-
-        String prefix =
-            namespace == null
-                ? ""
-                : getPrefix(namespace, true, true);
-
-        if (namespace != null && namespace.isEmpty()) {
-            for (int i = nspCounts[depth];
-                i < nspCounts[depth + 1];
-                i++) {
-                if (nspStack[i * 2].isEmpty() && !nspStack[i * 2 + 1].isEmpty()) {
-                    throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
-                }
-            }
-        }
-
-        elementStack[esp++] = namespace;
-        elementStack[esp++] = prefix;
-        elementStack[esp] = name;
-
-        append('<');
-        if (!prefix.isEmpty()) {
-            append(prefix);
-            append(':');
-        }
-
-        append(name);
-
-        pending = true;
-
-        return this;
-    }
-
-    public XmlSerializer attribute(
-        String namespace,
-        String name,
-        String value)
-        throws IOException {
-        if (!pending)
-            throw new IllegalStateException("illegal position for attribute");
-
-        //        int cnt = nspCounts[depth];
-
-        if (namespace == null)
-            namespace = "";
-
-        //        depth--;
-        //        pending = false;
-
-        String prefix =
-            namespace.isEmpty()
-                ? ""
-                : getPrefix(namespace, false, true);
-
-        //        pending = true;
-        //        depth++;
-
-        /*        if (cnt != nspCounts[depth]) {
-                    writer.write(' ');
-                    writer.write("xmlns");
-                    if (nspStack[cnt * 2] != null) {
-                        writer.write(':');
-                        writer.write(nspStack[cnt * 2]);
-                    }
-                    writer.write("=\"");
-                    writeEscaped(nspStack[cnt * 2 + 1], '"');
-                    writer.write('"');
-                }
-                */
-
-        append(' ');
-        if (!prefix.isEmpty()) {
-            append(prefix);
-            append(':');
-        }
-        append(name);
-        append('=');
-        char q = value.indexOf('"') == -1 ? '"' : '\'';
-        append(q);
-        writeEscaped(value, q);
-        append(q);
-
-        return this;
-    }
-
-    public void flush() throws IOException {
-        check(false);
-        flushBuffer();
-    }
-    /*
-        public void close() throws IOException {
-            check();
-            writer.close();
-        }
-    */
-    public XmlSerializer endTag(String namespace, String name)
-        throws IOException {
-
-        if (!pending)
-            depth--;
-        //        if (namespace == null)
-        //          namespace = "";
-
-        if ((namespace == null
-            && elementStack[depth * 3] != null)
-            || (namespace != null
-                && !namespace.equals(elementStack[depth * 3]))
-            || !elementStack[depth * 3 + 2].equals(name))
-            throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
-
-        if (pending) {
-            check(true);
-            depth--;
-        }
-        else {
-            if (indent[depth + 1]) {
-                append("\r\n");
-                for (int i = 0; i < depth; i++)
-                    append("  ");
-            }
-
-            append("</");
-            String prefix = elementStack[depth * 3 + 1];
-            if (!prefix.isEmpty()) {
-                append(prefix);
-                append(':');
-            }
-            append(name);
-            append('>');
-        }
-
-        nspCounts[depth + 1] = nspCounts[depth];
-        return this;
-    }
-
-    public String getNamespace() {
-        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
-    }
-
-    public String getName() {
-        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
-    }
-
-    public int getDepth() {
-        return pending ? depth + 1 : depth;
-    }
-
-    public XmlSerializer text(String text) throws IOException {
-        check(false);
-        indent[depth] = false;
-        writeEscaped(text, -1);
-        return this;
-    }
-
-    public XmlSerializer text(char[] text, int start, int len)
-        throws IOException {
-        text(new String(text, start, len));
-        return this;
-    }
-
-    public void cdsect(String data) throws IOException {
-        check(false);
-        // BEGIN Android-changed: ]]> is not allowed within a CDATA,
-        // so break and start a new one when necessary.
-        data = data.replace("]]>", "]]]]><![CDATA[>");
-        append("<![CDATA[");
-        for (int i = 0; i < data.length(); ++i) {
-            char ch = data.charAt(i);
-            boolean allowedInCdata = (ch >= 0x20 && ch <= 0xd7ff) ||
-                    (ch == '\t' || ch == '\n' || ch == '\r') ||
-                    (ch >= 0xe000 && ch <= 0xfffd);
-            if (allowedInCdata) {
-                append(ch);
-            } else if (Character.isHighSurrogate(ch) && i < data.length() - 1) {
-                // Character entities aren't valid in CDATA, so break out for this.
-                append("]]>");
-                writeSurrogate(ch, data.charAt(++i));
-                append("<![CDATA[");
-            } else {
-                reportInvalidCharacter(ch);
-            }
-        }
-        append("]]>");
-        // END Android-changed
-    }
-
-    // BEGIN Android-added
-    private void writeSurrogate(char high, char low) throws IOException {
-        if (!Character.isLowSurrogate(low)) {
-            throw new IllegalArgumentException("Bad surrogate pair (U+" + Integer.toHexString((int) high) +
-                                               " U+" + Integer.toHexString((int) low) + ")");
-        }
-        // Java-style surrogate pairs aren't allowed in XML. We could use the > 3-byte encodings, but that
-        // seems likely to upset anything expecting modified UTF-8 rather than "real" UTF-8. It seems more
-        // conservative in a Java environment to use an entity reference instead.
-        int codePoint = Character.toCodePoint(high, low);
-        append("&#" + codePoint + ";");
-    }
-    // END Android-added
-
-    public void comment(String comment) throws IOException {
-        check(false);
-        append("<!--");
-        append(comment);
-        append("-->");
-    }
-
-    public void processingInstruction(String pi)
-        throws IOException {
-        check(false);
-        append("<?");
-        append(pi);
-        append("?>");
-    }
-}
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();
         }